Sweden
Loading...
India
Loading...

OpenEMS

OpenEMS is a modular, open-source Energy Management System (EMS) designed to control, monitor, and integrate energy storage systems with renewable energy sources. The platform comprises three primary components:

  • OpenEMS Edge: The local interface interacting with the physical environment.
  • OpenEMS UI: The real-time user interface for monitoring and control.
  • OpenEMS Backend: The central server for aggregation, monitoring, and control.

OpenEMS Edge

The OpenEMS Edge functions as the local interface, actively interacting with the physical environment and the OpenEMS Backend. It is built using a high-level programming language and adheres to a three-component architecture: Input, Process (Controller), and Output.

Architecture

  • Programming Language: OpenEMS Edge and Backend are implemented in Java, requiring a Java Runtime Environment (JRE) for platform independence. The software typically runs on an Industrial IoT Gateway or a development board like a Raspberry Pi with a GNU/Linux Operating System.

Input-Process-Output Model

OpenEMS follows the Input-Process-Output (IPO) model, defining the internal execution cycle:

Image

  • Input: Collects all relevant information and provides it as a process image.
  • Process: Runs algorithms and tasks based on the process image information to evaluate whether a digital output should be turned on.
  • Output: Applies the results from the process phase.

The Scheduler

The Scheduler manages the execution of all energy management (EM) algorithms, determining the order and timing of their execution. It uses three major ordering mechanisms:

  • Fixed priority order
  • Schedule based on a Daily/JSCalendar
  • Simple alphabetical execution

Image

The Scheduler resolves conflicts when multiple controllers attempt to set the same output by prioritizing commands.

The Controller (Business Logic)

The Controller holds the core business logic and algorithms of OpenEMS that control the hardware. It manages the decision-making process for determining what command should be passed to the hardware.

Image

Controllers operate in two modes:

  • Setpoint Mode: Calculates a specific, immediate command—the "setpoint"—and sends that value directly to the device for execution.
  • Parameterization Mode: Transmits configuration parameters or rules to the device, instructing the hardware on how to behave under certain conditions. The hardware then runs its own internal, high-speed control loop based on those parameters.

Bridge

In OpenEMS Edge, Bridges are components designed to simplify the implementation and integration of hardware devices that use specific standardized physical connection layers and communication protocols. Essentially, a Bridge handles the low-level communication details, allowing other OpenEMS components (like devices and controllers) to interact with the hardware more easily.

Modbus Bridge

The Modbus Bridge supports both Modbus/TCP and Modbus/RTU protocols, commonly used for communication with devices like inverters and meters.

Modbus/TCP: Enables communication over a TCP/IP network.

Modbus/RTU: Facilitates serial communication via an RS485 bus.

The Modbus Bridge manages the execution of Modbus tasks, prioritizing write requests and optimizing read requests to occur just when their values are needed.

HTTP Bridge

The HTTP Bridge is used for devices that communicate via the HTTP protocol, often employing RESTful APIs. This includes various hardware devices like electric meters and relays.

M-Bus Bridge

The M-Bus Bridge supports the M-Bus (Meter-Bus) protocol, a standard for connecting to metering devices such as electricity, gas, or water meters.

OneWire Bridge

The OneWire Bridge connects to devices using the OneWire protocol, commonly found in home automation for sensors like thermometers. OpenEMS's implementation communicates directly with the OneWire bus master (e.g., a USB dongle) and does not require the OneWire File System (OWFS).

Process Image

OpenEMS uses a Process Image to maintain data consistency:

  • nextValue: Holds the latest received data.
  • value: Holds the stable value used by controllers.

During each cycle, OpenEMS performs a "Switch Process Image" operation that copies nextValue into value, ensuring that Channel data remains consistent and unchanged throughout the entire calculation cycle.

Asynchronous Threads and Cycle Synchronization

OpenEMS communicates with multiple external devices and services, each operating at its own timing and speed. These interactions happen using asynchronous threads, meaning data updates can occur unpredictably and independently of the system’s computing cycle. To maintain data consistency, OpenEMS uses Cycle Synchronization, ensuring that controllers always work with a synchronized snapshot of data for the entire duration of the cycle.

Image

Architecture Schema

The OpenEMS Edge architecture is structured to efficiently separate hardware communication from control logic. This design ensures flexibility, predictability, and stability while simplifying the integration of new devices and components. Hardware devices are abstracted using:

Image

Configuration Management Methods

OpenEMS Edge utilizes the OSGi Configuration Admin Service for configuration management, offering several methods: - Via OpenEMS UI: Manage configurations through the graphical interface when connected to OpenEMS Edge or Backend. - Via Apache Felix Web Console: Use the native OSGi method to manage configurations via a web interface. - Via JSON-RPC: Adjust configurations programmatically using JSON-RPC requests: createComponentConfig: Create a new component instance from a specific factory. updateComponentConfig: Modify properties of an existing component instance. By Editing/Preseeding Configuration Files: Manually edit plain text files on the filesystem for quick changes or initial setups, requiring an application restart to apply.

Configuration Architecture Concepts

The configuration structure in OpenEMS Edge is based on four key concepts:

Nature - An interface defining a standard set of characteristics and required channels. Channel - A single piece of information about a component, enriched with metadata. Factory - A blueprint implementing one or more natures, defining required configuration parameters. Instance - A runtime instantiation of a factory with a defined set of configuration parameters, uniquely identified by its Component-ID.

The complete configuration is available via API in a JSON format called the EdgeConfig, allowing external services like the OpenEMS UI to adapt to the current setup of OpenEMS Edge.

Nature

Natures are implemented as OSGi API Bundles and categorize devices and core functionalities. Here are some of the key Natures:

ESS (Energy Storage System)

Represents an integrated system comprising a battery and a battery inverter. Implementations include:

  • Ess (generic)
  • SymmetricEssReadonly
  • ManagedSymmetricEss (controllable)
  • EssDcCharger (solar charger connected to the DC side of an energy storage system)

These implementations require a State of Charge (SoC) Channel.

Battery / Battery-Inverter

Defines characteristics for the battery cell component and the power conversion unit separately. Used when the battery and inverter are treated as distinct components.

Meter

Defines a device that measures electricity flows. Implementations include:

  • ElectricityMeter (tracks consumption, production, and grid exchange)

EVCS (Electric Vehicle Charging Station)

Represents a device for charging electric vehicles. Implementations include:

  • Evcs (charging station for electric vehicles like e-cars and e-buses)

I/O (Digital Input/Output)

Represents hardware components like relays or digital I/O modules. Implementations include:

  • DigitalOutput (for controlling one or more digital outputs or relays)

Predictor

Provides abstract access to time-series predictions. Used by components that forecast energy production or consumption (e.g., LSTM models).

Thermometer

Represents a device that measures temperature. Provides temperature data channels.

Time-Of-Use Tariff API

Provides a unified interface for accessing energy prices from various providers (e.g., aWATTar). Used for optimizing charging/discharging based on variable pricing.

Weather API

Provides a clean interface for accessing historical and forecast weather data. Used for improving PV production predictions.

Controller / Scheduler

Represents core system logic components. Used to define and execute control strategies and scheduling tasks.

Timedata Service

The Timedata Service is essential for data persistence, handling the writing and reading of Channel values to and from a database, thus allowing the system to track performance over time. Its two main functions are:

  • Recording (Write): Persistently stores all Channels (e.g., Active Power, State of Charge) with a precise timestamp, often utilizing time-series databases like InfluxDB or optimized methods like RRD4J.
  • History (Read): Makes historical data available for the User Interface (UI), which displays charts and graphs; the Backend, which uses aggregated data for centralized monitoring; and Simulation, which feeds historical data to test control algorithms.

Configuration and Implementation

OpenEMS configuration can be performed through:

  • The UI
  • The Apache Felix Web Console
  • JSON-RPC
  • Directly editing configuration files

Implementing a Device

Step-by-Step Guide: Implementing a New OpenEMS Device

Implementing a new hardware Device in OpenEMS Edge involves defining, coding, and deploying a new software component (driver) that connects abstract data requirements (Natures) to physical communication protocols (Bridges). This process is generally focused on Modbus communication and encourages the use of abstract base classes for rapid and reliable development.

Phase 1: Development and Definition

  1. Create the OSGi Bundle: The entire device implementation begins by creating an OSGi bundle in Java. This bundle is the self-contained module that will host the driver code and manage its lifecycle within the OpenEMS Edge environment.

  2. Define Dependencies and Configuration: Specify any required libraries or internal OpenEMS components the device needs to function. Define the required configuration parameters that a user must set (e.g., the Modbus unit ID, IP address, or serial port settings).

  3. Code the Device Class (The Translation Layer): Implement the device driver code, focusing on protocol translation logic by:

  4. Defining Natures: The device must implement the appropriate Natures (Java interfaces) that define the abstract capabilities of the hardware (e.g., MeterNature or EssNature).

  5. Mapping Channels: For every data point required by Nature, map the corresponding Channel to the correct physical address or register required by the hardware's communication protocol.

  6. Unit Testing and Simulation: Before deployment, validate the device implementation by:

  7. Running isolated tests to ensure the mapping and scaling logic is correct and handles edge cases properly.

  8. Creating a simulation environment to test the device's behavior within the full Input → Process → Output cycle, without requiring the physical hardware to be connected.

Phase 2: Deployment and Runtime

  1. Deployment: Once tested, deploy the new device support to the OpenEMS Edge instance. This deployment can be handled in two ways:

  2. Via the Felix Web Console, which offers a GUI for installing the new OSGi bundle.

  3. Via a programmatic API (Application Programming Interface), allowing for automated, remote deployment.

  4. Configuration and Instantiation: With the Factory for the new device now available in the Edge runtime, a user can create a working instance by:

  5. Configuring the device via the UI or console.

  6. Creating a runtime Instance, which is the operational copy of the device driver ready to perform its API calls and communication.

OpenEMS Edge Build Guide

Building with Eclipse IDE (Manual Development)

  1. Open the io.openems.edge.application project in Eclipse IDE and open the EdgeApp.bndrun file.
  2. Press [Export] to start the Export Wizard Selection assistant.
  3. Select [Executable JAR] and press [Next >].
  4. Select a destination for the export to JAR.
  5. Press [Finish].

This creates a "fat JAR" file, including all bundles. It can be executed by running java -jar openems.jar in a console.

Building with Gradle (Automated & Production)

Gradle is a build tool used in the OpenEMS project to compile the JAR files and execute other tasks like building the documentation webpage using Antora and the Javadocs. To build OpenEMS Edge:

  1. Open a console and change to your repository directory.
  2. Execute gradlew buildEdge.

OpenEMS UI

Setup Visual Studio Code

  1. Download and install Node.js LTS.
  2. Download and install Visual Studio Code.
  3. Open OpenEMS UI source code in Visual Studio Code:

  4. Menu: [File] → [Open Folder…] → Select the ui directory inside the downloaded source code.

  5. Open the integrated terminal:

  6. Menu: [Terminal] → [New Terminal]

  7. Install Angular CLI:

  8. npm install -g @angular/cli

  9. Resolve and download dependencies:

  10. npm install

Run OpenEMS UI

In Visual Studio's integrated terminal, type:

ng serve -c openems-edge-dev

Open a browser at http://localhost:4200/.

Architecture

The OpenEMS UI is a real-time user interface for web browsers and smartphones. It features an Adaptive User Interface, meaning its visualization dynamically adjusts based on the actual configuration of the connected OpenEMS Edge device. It connects to the OpenEMS Edge or OpenEMS Backend via WebSockets for real-time data communication.

Build OpenEMS UI

The build process is executed using the Angular CLI (ng build command). Configuration is specified during the build process to target different environments, such as:

  • OpenEMS Edge: ng build -c "openems,openems-edge-prod,prod"
  • OpenEMS Backend: ng build -c "openems,openems-backend-prod,prod"

This process compiles the source code into deployable artifacts that can be run outside of an IDE.

Implementation Widgets

  • FlatWidget: the FlatWidget serves as a compact display element that presents essential or general data. It functions as a button that, when interacted with, opens a more detailed ModalWidget. This design pattern ensures a clean and efficient user interface, displaying only critical information at first glance while providing access to detailed views upon user interaction.
  • Modal Widget: At the time of this documentation, multiple implementations of ModalWidgets exist. However, the unit-testable version is considered the best practice. This approach allows for better testing and validation of the widget's functionality, ensuring reliability and maintainability.
  • Chart: Charts are primarily utilized in the History View to display historical data. In this context, they should behave similarly to ModalWidgets in the Live View. This means that charts should not be immediately visible in the History View but should open upon clicking on a FlatWidget, providing users with detailed historical data in a modal format.

Device Implementations

A Device in OpenEMS Edge represents a specific piece of hardware (e.g., battery, inverter, meter) and its corresponding software driver. These devices are categorized by function and include:

Energy Storage Systems (ESS) / Batteries

BYD Battery-Box Commercial

FENECON Commercial

FENECON Home

  • Pylontech Powercube M2
  • Soltaro Battery Rack
  • KACO blueplanet gridsave
  • REFUstore 88K
  • Sinexcel Battery Inverter
  • Bosch BPT-S 5 Hybrid

Meters

  • ABB Meters
  • Carlo Gavazzi Meters
  • Eastron Meters
  • Janitza Meters
  • Virtual Meters (for calculated values)

PV Inverters

  • Fronius Inverters
  • GoodWe Inverters
  • KACO Inverters
  • SMA Inverters

Electric Vehicle Charging Stations (EVCS)

  • Go-e Charging Stations
  • Heidelberg Charging Stations
  • Webasto Charging Stations
  • Open Charge Point Protocol (OCPP) Server Support

Relays and I/O Modules

  • Shelly WiFi Relays
  • Siemens LOGO!
  • WAGO Fieldbus Couplers

Predictors

  • LSTM (Long Short-Term Memory) Models
  • Persistence-Model

Tariffs

  • Tibber Integration
  • Awattar Integration
  • Manual Tariffs

Core Services

These are essential background components that manage the OpenEMS Edge environment itself, rather than external hardware.

Function ComponentManager - Provides easy access to OpenEMS Components and Channels. It handles the application of default configurations (like APIs) and configuration validation. Cycle - Provides the core runtime cycle of OpenEMS Edge, dictating when operations (like reading data and executing control logic) occur. Host - Provides operating system-specific commands, such as configuration of the TCP/IP network. Meta - Exposes system constants (e.g., software version) as channels, making them available via APIs. Sum - Calculates and holds aggregated information on energy flows, such as summed production, consumption, and total energy storage charge/discharge. AppManager / App - Services for managing and running predefined or custom applications within OpenEMS Edge.

Edge-2-Edge

This feature allows one OpenEMS Edge instance (Master) to connect to and manage devices attached to another OpenEMS Edge instance (Slave) via Modbus, enabling distributed or clustered energy management.

Absolutely. Here’s the fully rewritten, professionally structured, and concise version of your OpenEMS Backend documentation — aligned with the official OpenEMS documentation style and hierarchy.

OpenEMS Backend

The OpenEMS Backend is a cloud-native, modular platform built to aggregate, monitor, and control multiple OpenEMS Edge systems. It provides centralized data storage, user management, and system-wide coordination through an extensible, service-based architecture.

Architecture

The OpenEMS Backend is implemented in Java, following a modular OSGi (Open Service Gateway Initiative) framework using Apache Felix. This design enables flexibility, modular deployment, and high scalability across single-site or multi-site energy management environments.

Core Architectural Principles

  • Modularity: Each functional capability—such as storage, API, or authentication—is an independent, hot-swappable OSGi bundle.

  • Event-Driven Communication: Components communicate through a shared event bus, ensuring loose coupling and real-time responsiveness.

  • Database Abstraction: The backend supports multiple database types, allowing developers to plug in or replace persistence layers without code changes.

  • Microservices-Ready: While it can run as a monolithic service, the modular design allows decomposition into microservices for containerized or Kubernetes environments.

Data and Control Flow

Flow Direction Protocol Purpose
Upward Data Edge → Backend → UI WebSocket (JSON-RPC), HTTPS/WSS Aggregated Edge data flows upward for visualization and analytics.
Storage Backend → Database Internal DB connections Metadata stored in PostgreSQL; time-series data stored in InfluxDB or TimescaleDB.
Downward Control UI → Backend → Edge HTTPS/WSS, WebSocket (JSON-RPC) Commands and configuration changes sent from UI to Edge.

Deployment Topologies

  • Single-Site: One Edge connected to a single Backend instance.
  • Multi-Site: Multiple Edges managed by one Backend for fleet-level supervision.
  • Hierarchical: Multiple Backends communicate in parent-child relationships, enabling distributed or regional aggregation.

Backend-to-Backend

The OpenEMS Backend exposes both REST and JSON-RPC interfaces to support communication between backend instances, as well as integration with external systems and UIs.

API Interfaces

API Type Endpoint Use Case Authentication
REST GET /rest/channel/{edgeId}/{componentId}/{channelId} Retrieve current or historical channel values. API Token, Role-Based Access Control (RBAC)
JSON-RPC POST /jsonrpc Execute control commands or batch operations. API Token, RBAC

Key Use Cases

  • Federated backend communication in hierarchical deployments.
  • Integration with third-party monitoring or analytics tools.
  • Data export and synchronization between different backend instances.

Metadata

The Metadata Service manages non-time-series information about connected systems, components, and users.

Core Functions

Function Description Storage
Device Configuration Stores device and Edge setup details. PostgreSQL or equivalent RDBMS
Device Hierarchy Maintains parent-child relationships and dependencies.
Status & Availability Tracks system and component operational states.
Access Control Implements RBAC and user permissions.

Features

  • Persistent configuration management for all connected Edges.
  • Role-based access and hierarchical user privileges.
  • API-based retrieval for external management systems.

Timedata

The Timedata Service is responsible for ingesting, storing, and querying time-series data received from the Edge systems.

Core Functions

Function Description Recommended Storage Performance Optimization
Real-Time Ingestion Receives and validates live data streams. InfluxDB Batch writes and async commit
Historical Storage Stores large-scale time-series datasets. TimescaleDB (PostgreSQL extension) Retention & compression policies
Aggregation & Querying Supports aggregated and filtered data retrieval. Custom OSGi implementations Indexed queries for performance

Highlights

  • Supports pluggable database implementations.
  • Designed for high-frequency telemetry from multiple Edge devices.
  • Configurable retention policies to manage data growth.

Service

The Service Layer orchestrates internal communication, synchronization, and lifecycle management of OSGi bundles. Each service implements a clearly defined interface and can be independently deployed or replaced.

Core Service Types

  • Websocket & API Services: Handle inbound and outbound communication with Edge devices and the UI.
  • Storage Services: Abstract data persistence for metadata and timedata.
  • Authentication Services: Manage token verification, session validation, and user identity.
  • Event Bus Service: Propagates internal events and messages between bundles.

Key Characteristics

  • Dynamic Discovery: Services register and discover each other at runtime through the OSGi registry.
  • Hot-Swapping: Bundles can be updated or replaced without system downtime.
  • Extensibility: Developers can add new custom services for analytics, monitoring, or device-specific integrations.

Deploy

The OpenEMS Backend can be deployed on Debian/Ubuntu or in Docker containers. Both deployment methods require Java 17+ and a suitable configuration directory (/etc/openems/backend).

Deploy on Debian/Ubuntu

This method provides a native service setup for production environments.

Steps

Install Dependencies

sudo apt update
sudo apt install openjdk-17-jre git

Build Backend

git clone https://github.com/OpenEMS/openems.git
cd openems
./gradlew buildBackend

Install and Configure

  • Copy the built JAR to /opt/openems/backend/
  • Create configuration directory /etc/openems/backend/
  • Add configuration files (database, services, Edge endpoints)

Create Systemd Service

sudo nano /etc/systemd/system/openems-backend.service

Example:

[Unit]
Description=OpenEMS Backend
After=network.target

[Service]
ExecStart=/usr/bin/java -jar /opt/openems/backend/openems-backend.jar
WorkingDirectory=/opt/openems/backend
User=openems
Restart=always

[Install]
WantedBy=multi-user.target

Enable and Start

sudo systemctl daemon-reload
sudo systemctl enable openems-backend
sudo systemctl start openems-backend

Deploy to Docker

Docker provides a lightweight and consistent runtime for deploying OpenEMS Backend.

Steps

Pull Latest Image

docker pull openems/openems-backend:latest

Run Container

docker run -d \
  --name openems-backend \
  -p 8080:8080 -p 8084:8084 \
  -v /path/to/config:/etc/openems \
  openems/openems-backend:latest
  • Port 8080 – Edge WebSocket communication
  • Port 8084 – REST/JSON-RPC API for UI and external systems

Advantages

  • Fast setup and consistent environments.
  • Easy orchestration via Docker Compose or Kubernetes.
  • Seamless version upgrades and rollback.