Hey there,
I am currently working on implementing a controller for my ESS.
Ultimately, I want the following functionalities:
- Peak Shaving
- Restarting the ESS x times when in error mode.
- Starting and stopping the ESS via remote call
Peak Shaving I just implemented in the run()
method of my controller. But now I was wondering whether I should implement a new controller for the other tasks. The second is something for the run()
method as well I would assume. And from my understanding I should be able to use the REST API to call a startESS()
/stopESS()
method inside my controller for the third requirement. Is that correct?
Should I use separate controllers for each functionality?
I am grateful for any input on this matter.
Hi Finn,
it sounds like you are doing it wrong.
-
A Peak-Shaving-Controller is already available, including visualization in UI, etc.: openems/io.openems.edge.controller.symmetric.peakshaving at develop · OpenEMS/openems · GitHub
- Or is there any specific reason why you are not able to use this one?
-
Restarting the ESS x times when in error mode.
- This should be handled inside the ESS, Battery or BatteryInverter component. We typically implement something like this in an internal State-Machine.
- Can you please provide more insight in what hardware you are using so I could guide you where this belongs?
-
Starting and stopping the ESS via remote call
- What exactly do you want to do? Shutdown the entire hardware? Or just stop charging/discharging?
Hi Stefan, thank you for the quick reply.
- At some point I want to use a custom controller, which implements more then just peak shaving. So it is not about peak shaving but just a ess controller in general.
- I am trying to control a multi level inverter which I can control via modbus registers.
- Basically, I just want to write values to some predefined modbus registers and thereby charge/discharge or do a software reset (remotely).
Wothout an exact Use-Case Scenario it is pretty hard to help/answer..
We’re working with a multilevel inverter connected to the grid and several strings of batteries (for a total of 200 kWh). Right now, OpenEMS is running on a laptop for development, but we plan to move it to a device like a Raspberry Pi later on.
The inverter communicates with OpenEMS over Modbus TCP and handles most of the core logic internally — such as managing maximum charge/discharge power and balancing across the battery strings. Our main goals for the system are peak shaving and self-consumption optimization.
In addition, we need some basic maintenance functionality:
The ability to remotely trigger a reset by writing a flag to a specific Modbus register.
Automatic retries: when the inverter goes into an error state, it should attempt to reset itself a few times.
I was thinking that I need to implement my own ess controller for the inverter has no register for setting the reactive power (as done in the already implemented peak shaving controller) and no register for reading the total active power. Instead I can retrieve the active power of the individual phases and sum them up.
Thanks a lot for your time!
Thanks Finn for providing some details.
The inverter communicates with OpenEMS over Modbus TCP and handles most of the core logic internally
Then you just have to implement ManagedSymmetricEss
in your OpenEMS Edge component.
Our main goals for the system are peak shaving and self-consumption optimization.
This should work out of the box for you.
The ability to remotely trigger a reset by writing a flag to a specific Modbus register.
Easiest is to map a Channel on that Register and write the Channel via OpenEMS UI | Settings | Channels whenever you need to. A more advanced implementation would use a custom JSONRPC-Request.
Automatic retries: when the inverter goes into an error state, it should attempt to reset itself a few times.
This has to be done in a State-Machine inside the OpenEMS Component.
[…] has no register for setting the reactive power
The ManagedSymmetricEss
has a applyPower(activePower, reactivePower)
method. Just ignore the reactivePower
in your use case: openems/io.openems.edge.ess.api/src/io/openems/edge/ess/api/ManagedSymmetricEss.java at develop · OpenEMS/openems · GitHub
A more advanced implementation would add custom constraints via getStaticConstraints()
that define that there is no reactive power available: openems/io.openems.edge.ess.api/src/io/openems/edge/ess/api/ManagedSymmetricEss.java at develop · OpenEMS/openems · GitHub
Open Source is about sharing and collaborating. Can you please share the code you are working with? It would be much easier to help you if we knew what kind of “multilevel inverter” you are working with. 200 kWh is a serious size and does not sound like a private garage project… 
1 Like
Thanks a lot @stefan.feilmeier, the state machine is exactly what I was looking for and I totally forgot about the possibility of writing to channels via the UI.
I still need to Quote Stefan:
It is not only about helping everyone better but also to push OpenSource Projects like these forward and support them.
Please consider sharing what you are working on - especially - as Stefan stated - if this is not a “home-private” project.
@Sn0w3y texted you privately