Proposal: EMS Integration Behind a Meter: Towards Seamless Collaboration (clever-PV)

Every Energy Management System (EMS) has its own unique strengths and weaknesses. At OpenEMS, our mission goes beyond developing a powerful open-source EMS—we aim to provide the best possible integration with other EMS ecosystems. In the spirit of open source, we believe in building bridges, not silos.

When it comes to integrating multiple EMS behind a single meter, there are generally three different approaches, each serving different use cases:


1. Read-Only Integration

In this setup, multiple EMS run in parallel, simply reading data from each other without taking over control. This is often the easiest and most robust integration method, allowing systems to co-exist and benefit from shared data.

Examples include:

  • OpenEMS Edge provides local Modbus/TCP and JSON/REST interfaces.
  • HomeAssistant can read from OpenEMS Edge via ha_openems.
  • EVCC can read from OpenEMS Edge (PR #2673).
  • OpenEMS Edge can read data from EVCC (WIP PR #3119).

2. Full Control Override

Here, one EMS becomes the central controller, while the other acts as a command receiver. This setup is ideal when one system needs to enforce central control logic.

Examples include:

  • OpenEMS Edge offers local Modbus/TCP and JSON/REST interfaces that also support set-points (e.g., for battery charge/discharge). Note: These control interfaces may require a separate license in some OpenEMS distributions like FEMS.
  • An OpenEMS “Master” Edge can override a “Slave” Edge via the Edge-to-Edge interface:
    Edge-to-Edge on GitHub
  • This approach is used with many FENECON Industrial energy storage systems, e.g. together energy traders

3. Logical Integration

This hybrid approach combines the strengths of both EMS. It allows systems to work together intelligently while complying with regulatory requirements - like “Is it allowed to charge the battery from grid?”

A prime example:

  • Balancing Schedule Controller: A higher-level EMS sends a schedule to OpenEMS Edge for managing the grid connection point. OpenEMS then handles the real-time control with high responsiveness. Documentation: Balancing Schedule Controller
  • WIP: we (FENECON) are working on extending the Balancing-Controller to accept a “Grid Set-Point” - to be released soon…

This kind of logical integration is particularly useful when combining cloud-based EMS with local EMS, allowing for secure, cyber-resilient operation while leveraging the advantages of both layers.


Proposal: Advanced Integration with Clever-PV

As part of this ongoing effort, we propose an enhancement to the integration with clever-PV. This would allow control override of OpenEMS Edge via the clever-PV Push API.

  • The idea: The HTTP response from the Push API should include control commands (e.g., battery set-points).
  • The goal: A generic and future-proof communication structure that can support other cloud EMS and evolving control command formats.

Key resources:

General

  • Method: POST
  • Content-Type: application/json
  • Authentication: Device-specific API key (via endpoint URL)
  • Rate Limit: 180 requests per minute (OpenEMS default is 15 seconds)
  • Success Response: HTTP 202 Accepted

Request (default clever-PV Push API)

{
  "watt": -1000,
  "producingWatt": 1500,
  "soc": 75,
  "chargingPower": 500,
  "powerStorageState": 1,
}

Alternatively we propose a JSON object that uses OpenEMS Channel-Addresses, similar to CurrentData in OpenEMS UI.

{
  "currentData": {
     "_sum/GridActivePower": -1000,
     "_sum/ProductionActivePower": 1500,
     "_sum/EssSoc": 75,
     "_sum/EssDcDischargePower": -500,
  }
}

Use-Case 1: NO_DISCHARGE

As in the OpenEMS “ESS Time-of-Use Tariff”-Controller there should be a command that stops discharging a energy storage system. Loads are supplied either by PV or from grid. Charging is still allowed.

Example:

Extended Request

  • Add extendable “availableControlModes” | “ess” which holds a list of available control modes for Energy Storage Systems.
  • NO_DISCHARGE is only available if no “ESS Time-of-Use Tariff”-Controller is activated (i.e. not installed or configured with Mode.OFF
  • Mode “NO_DISCHARGE” has no additional parameters, but for other modes this JSON object could hold limits like max charge/discharge power.
{
   "...",
   "availableControlModes": {
     "ess": [{
       "mode": "NO_DISCHARGE",
     }]
   }
}

When activated:

{
   "...",
   "activeControlModes": {
     "ess": {
       "mode": "NO_DISCHARGE",
     }
   }
}

Response

To Activate:

{
   "activateControlModes": {
     "ess": {
       "mode": "NO_DISCHARGE",
     }
   }
}

To Deactivate:

{
   "activateControlModes": {
     "ess": null
   }
}
  • Empty Response does not deactivate the Mode
  • Response has to be updated once every 60 seconds, otherwise it gets deactivated (“Watchdog”)

Use-Case 2: LIMIT_CHARGE

As in the OpenEMS “ESS Grid Optimized Charge”-Controller there should be a command that limits the (DC-side) charging power of an energy storage system. Surplus PV is fed to grid. Discharging is still allowed.

Example:

Extended Request

{
   "...",
   "availableControlModes": {
     "ess": [{
       "mode": "LIMIT_CHARGE",
     }]
   }
}

Response

To Activate:

{
   "activateControlModes": {
     "ess": {
       "mode": "LIMIT_CHARGE",
       "maxChargePower": 1000, // [Watt]
     }
   }
}

To Deactivate:

{
   "activateControlModes": {
     "ess": null
   }
}

We look forward to feedback from the OpenEMS community and to continued collaboration with developers and EMS vendors across the ecosystem.

Please add your comments; I’ll try to incorporate the feedback above.

Let’s make energy systems more open—and smarter—together.


Changelog

  • 02.06.2025 Use "mode" as key within available/activateControlModes. Add proposal for CurrentData that aligns with OpenEMS standards.
3 Likes

Hi @stefan.feilmeier,
great proposal. Since I am a consumer (Fenecon) and a professional software developer, these two API requests are a good start for what I am missing in terms of API and UI.
For me, however, the whole thing goes a little further.
I would like to be able to specify the requests with an “until” condition.

Case1)
For example, when I charge my car, I would like to deactivate the discharge, but only until a certain “time”, “number of hours”, “until sunset”, or better, “until no wallbox has been charged for 15 minutes”. Or even better, “whenever a wallbox charges a car”. I always do the latter manually via the emergency power reserve. I would prefer to have these settings in the UI, of course, otherwise I would have to create an extra header in a third-party system just for this.
Why the until condition? I don’t want to load my car from the energy storage and would like to set the setting via API or UI in the fire and forget style. That way you don’t forget to reset, which has often happened to me with the emergency power reserve.

Case2)
I have a similar view of the load limitation. I would set the default in the UI and then set it to OFF or ON again using the requests you have defined. With OFF I would also like to have a time condition up to a certain “time”, “number of hours”, or “until sunset”. I would also welcome these settings in the UI.
Why the until condition? On days when I know that I won’t be able to charge my car or switch on other large consumers until later, I want to set via API or UI in the morning that the limitation should be switched off today and charging should take place immediately, because otherwise the battery won’t be full in the evening. Again, with fire and forget, so that I don’t have to deactivate manually.

Maybe the suggestion can be incorporated, and preferably in the UI :wink::face_with_peeking_eye:

Hi @stefan.feilmeier,

good breakdown of the possible scenarios.

I would start with a brief introduction of my belief:
When I started with energy management, my first thought was to focus on energy management via the cloud. At that time, I didn’t realise the complexity of the electrical and physical requirements and in particular, the regulatory requirements. Today, a few years later, I am convinced that there must be dezentralized and local energy management, a hardware that is installed on site. There is no other way to achieve a decentralised energy transition.

OpenEMS and its Time-of-Use feature can optimise as a local energy management system. And I think this can become very efficient. But beyond that it also requires grid wide optimisation. Therefore part 3 “logical integration” of your proposal could be a way to do grid wide optimisation. It could also be used to enable convenience features, like e.g. connecting your calendar with your electrical car, without affecting the security of the local EMS installation.

I really like the idea of working with control modes and limitations, rather than working with specific power setpoints. This approach gives local energy management more freedom for better decisions and faster response times, all within the legal permitted control range. Furthermore a remote EMS does not loose much control with control modes. It could control the ESS flexible enough by just sending control modes like

  • NO_DISCHARGE
  • LIMIT_CHARGE

to the local EMS.

With regard to charging stations (or possibly even entire charging parks), control via control modes would also be appropriate. A remote EMS does not need to worry about things like e.g. managing the phase shift load at several charging stations. control modes such as

  • FULL_CHARGE
  • LIMIT_CHARGE

in relation to each charging station (or even to the charging park) are better criteria, than setting fine granular and high frequent power setpoints at all times. In the end energy quantities needs to be shifted. The technical details about how the energy is shifted should not be part of remote ems functionality.

Curious what others think of this aproach :upside_down_face:.

1 Like

This could also be a good topic for the next OpenEMS hackathon.
Provide a docker container with a) a simple UI and push API and b) an OpenEMS Edge bundle as reference implementation. This could be a good starting point for energy programming beginners to e.g. control their chargepoint programmatically or disable battery discharge during car charge.

I wish all of you a happy fathers day/men’s day.

I could see another use case, management of an Energy Community
(Disclamer, I am seen things currently focused on Energy Community, based on the Austrian Model: Erneuerbaren Energie Gemeinschaft, regional, https://energiegemeinschaften.gv.at/erneuerbare-energie-gemeinschaften-eeg/ Level 4-7 of the Energy Network)

Short Intro, in an Energy Community the Energy that is produces from it’s members gets sold to the community, consumers can buy energy from that community. It is an addon to the existing energy providers

The billing happens the day after with 15 minute energy consumption values from the smartmeters. Every Energy that could be used by the members get sold to the community, every access about that get’s sold to the energy providers. It is always equal, the energy bought from the community and the energy sold.

Energy that could not be covered from the energy community is provided by the energy provider to the consumer. Energy needs and surplus energy is handled by individual contracts to the energy provider by every member. These are the normal energy contracts that would be there with or without the energy community. The calculation if the energy was provided by the energy community or the energy provider is done by the network operator on the next day based on the smart meter data. smart meter data is collected on a daily bases by the network operator. e.g. Netz NÖ The energy community or their platform operator gets the data from netz nö.
Examples for energy community platform provider: Cancom, Energy Family, EZN/E.Gon and many more: https://energiegemeinschaften.gv.at/dienstleister-in-oesterreich/

The Problem:
Increase the volume of energy traded inside the energy community.
Make it attractive to install batteries inside the energy community.
Make it attractive to install smart loads.

The Goal:
To make energy usage visible and controllable on an energy community level, it would need one EMS for the energy community that collects the data from every member and calculates in realtime the energy levels in the community. A Energy Community could be treated like a household, if to much energy is available, start something that uses energy. If it is missing energy, disable things that could wait or discharge the batteries.

Situations in the Community:

  1. Surplus Energy
  2. Demand matches Usage
  3. More Energy needed

To achieve that, it would be possible to divide the customers into group, based on the installed equipment and their use case:

  • Standard user, no equipment or an smart meter reader that transfers the data to the community EMS. e.g. shrzdm dongle, smongle,

  • User with smart loads, small (local) ems that known the smart meter realtime data and can control smart loads and does the communication with community ems

  • User with controllable Batteries, full local ems, that known the smart meter realtime data, PV production, Battery values. This EMS can decide, based on the data from the community EMS, if it is worth it to sell energy from the batteries to the community. e.g. a night tarif, where energy is a bit more expensive.

The role of each type of member with an community wide EMS:

  • Standard user: get monitored
  • User with smart loads: takes access energy if avaliable
  • User with controllable Batteries: provides energy at night

The Community EMS would need:

  • a Receiver for the Push Data from the Smart Meter Dongles and local EMS
  • an API to the simulated Smart Meters. (Members without a Smart Meter Dongle cloud be accounted for by simulated usage, based on the smart meter data from the days before)
  • an API where the small EMS can get the data for there smart loads
  • an API for the full EMS with battery.
  • an internal price tracker for time-of-use tariffs inside the energy community.
  • an API for the time-of-use tariffs

What do the situation without an EMS mean for the Members of the Energy Community:

  1. Surplus Energy
    The producers of energy lose some profit and the access energy is sold to the grid for cheap rates. (Based on their energy contracts with their energy providers)

  2. Demand matches Usage
    Best Case for all members

  3. More Energy needed
    The energy consumers are buying energy from their energy provider, which is more expensive than the energy community.

The energy community is not missing out on much if it does not have an EMS.
The benefit would be for the members inside the energy community.

In an Energy community with only PV Generation and no batteries, this would not make sense. But if, for example, hydro power is also within the energy community, it could be a use case.

Then the EMS would have multiply prices to deal with:

  • Energy from the Grid
  • Energy from the Energy Community
  • Energy from PV/Battery

Energy from PV and Battery is always the cheapest option, followed by the Energy Community and the Grid.

@benzman81:

You can maybe use the OpenEMS add-on for Home-Assistant, to automate this: GitHub - Lamarqe/ha_openems: Home Assistant Integration for Fenecon FEMS and OpenEMS

I don’t want to load my car from the energy storage

In general I don’t agree with this statement, because very often it is very feasible to do that. Of course there needs to be a stop condition then. (e.g. “Charge 10 kWh till 7am in the morning”). We are working on such features in the “Energy Scheduler v2” project.


@c.lehne:

Thanks for that use-case. Yes, indeed a lot of current developments are towards “schedule management”, where a schedule is always a list of “control modes” per time-period (e.g. 15 minutes slot). So maybe the API should allow/foresee optional time/duration settings already from the beginning.

See discussion and OpenEMS Networking Friday slides here: 04.04. Networking Friday on Energy Scheduler v2 & Genetic Algorithms - #2 by stefan.feilmeier

Really appreciate your experience here. That’s why I already had ess in activeControlModes, to be prepared also for evcs or evse. The Evse.Controller.Single already uses such control modes per chargepoint as you describe:

{
   "...",
   "activeControlModes": {
     "ess0": {
       "mode": "NO_DISCHARGE",
     }
     "ctrlEvseSingle0": {
       "mode": "FORCE",
     }
   }
}

(I’m using ess0 instead of ctrlEssTimeOfUseTariff0 because this should work also without an installed/bought Time-of-Use-Tariff-Controller)


I am not sure yet if/how this will be used as an extension or replacement for the existing local JSON/REST-Api. Current proposal really just targeted Cloud-EMS, but of course this could also make sense towards Home-Assistant, OpenHAB, ioBroker, etc.


@JonasGhost:

Thanks for bringing up and explaining Energy Communities. Austria is ahead there, but as this is a European Law, we will see it more widely applied soon.

OpenEMS could play multiple roles in such an environment; with parts handled by OpenEMS Backend and parts handled locally by OpenEMS Edge. I have also seen that clever-PV and other Cloud-EMS providers are actively working on implementing specific solutions for this use-case. On the Edge-side this could than be handled by OpenEMS with the proposed API.