I am interested in testing the integration of the component I have written (a battery) with the Generic Symmetric ESS component as I have been seeing some issues around starting the battery in this setup.
I have previously written some unit tests for my battery using the ComponentTest class which allows one to instantiate a component and add references to dummy components where needed such as ModbusBridge. Like this:
new ComponentTest(new MyBatteryImpl()) //
.addReference("cm", new DummyConfigurationAdmin()) //
.addReference("componentManager", new DummyComponentManager(clock)) //
.addReference("setModbus", new DummyModbusBridge(MODBUS_ID)) //
.activate(MyConfig.create() //
.setId(BATTERY_ID) //
.setModbusId(MODBUS_ID) //
.setModbusUnitId(1) //
.setStartStop(StartStopConfig.START) //
.build())
.next(new TestCase("Check State Machine = UNDEFINED to begin")
.input(STATUS_CHANNEL, MyBattery.Status.SLEEP) // Ensure that it is in a sleep mode to begin with, so it will need to be woken up
.output(STATE_MACHINE, StateMachine.State.UNDEFINED))
This works fine, but I have a couple of issues:
I would like to call a method on the MyBatteryImpl class as part of a test case. Specifically I would like to call the setStartStop method to simulate the Generic ESS calling this method to start the battery. I know that I can use the input method of the TestCase to set specific channel value, but how can I call an actual method on the unit under test?
I would like to write a test involving an ’ EssGenericManagedSymmetric’ and ‘MyBattery’ (with a dummy battery inverter). Is this possible, and are there any examples available where this is done? I can’t find any examples of tests where there are two ‘real’ components under test - as opposed to a single real component under test and references to only dummy components.
Hope my questions make sense - any help greatly appreciated.
I have an answer to question 1, which is quite simple. It is just to declare the battery (or SUT) as a variable which is passed to the test case. Code looks like the below:
// Define the battery as a variable
MyBattery sut = new MyBattery();
// Set up the test
ComponentTest test = new ComponentTest(sut) //
.addReference("cm", new DummyConfigurationAdmin()) //
.addReference("componentManager", new DummyComponentManager(clock)) //
.addReference("setModbus", new DummyModbusBridge(MODBUS_ID)) //
.activate(MyConfig.create() //
.setId(BATTERY_ID) //
.setModbusId(MODBUS_ID) //
.setModbusUnitId(1) //
.setStartStop(StartStopConfig.AUTO) //
.build())
.next(new TestCase("Start in UNDEFINED state. The StartStop is UNDEFINED to begin with")
.input(STATUS_CHANNEL, Status.IDLE)
.output(STATE_MACHINE, StateMachine.State.UNDEFINED)
.output(START_STOP, StartStop.UNDEFINED))
// Call method on the battery
sut.setStartStop(StartStop.START);
// Continue the test
test.next(new TestCase("Check that nothing has changed (yet)")
.output(STATE_MACHINE, StateMachine.State.UNDEFINED)
.output(START_STOP, StartStop.UNDEFINED))
I still am not sure how it is possible to define a test involving a Generic ESS and MyBattery.
I am begineer of OpenEMS. I am also interested in implementing of new Battery. Could you tell me where you modified the code and how did you implement it?
Sure I can provide some information. Can you let me know a little more about the battery you want to implement in OpenEMS? What connectivity does the battery provide (e.g modbus)? Do you have a Modbus specification for the battery?
In general it is necessary to create a new device in OpenEMS This guide ( Implementing a device :: Open Energy Management System (openems.github.io)) is a good starting point. The main programming task is to implement the communication with the device, which for me involved defining all the Modbus registers used by the battery and mapping these to OpenEMS channels.
I found it very useful to thoroughly read the code for existing battery implementations in OpenEMS - e.g for the Fenecon Home and Commercial batteries - and I used this as the basis for the device that I wrote.
Happy to share more information and my code if you can provide a little more info on your situation
Thank you very much for your response. I followed this guide(Implementing a device :: Open Energy Management System) to implement new Meter. I haven’t tried yet for a new battery. I will try, and follow your above suggestions and update you.
I also am having troubles defining a battery.
My biggest problem is that the battery communicates with an RS485 cable to the inverter (Sinexcel PWS2-30P-EX). how did you resolve this problem? i have a working modbus-tcp connection with the inverter but this doesn’t give me an ESS.ID so i cant implement any controller. Do you have an idea how to specify this in code?
I have some ideas, but I have a couple of questions before I can say which approach might be best…
Is your inverter already supported by OpenEMS? Or is it necessary to define a new device for this?
Does the modbus TCP connection with your inverter report values such as State of Charge, Battery voltage, temperature etc? (I.e the battery parameters which are defined in the Battery Nature within OpenEMS).
The Sinexcel inverter seems supported (i see other people with this inverter also on the forum but they all dont have a actual battery connected). The state of the inverter is also correctly reported in openems UI (so when it has an error you see a red exclamation mark in the top and when there is no error it turns green). I However get no dashboard data shown or any data visible in UI or Edge.
Yes the Battery gives all BMS information to the Sinexcell inverter and sinexcell inverter listens to this (so max charge current is only 9 amps the sinexcell will not go past that). These values i dont get visible in Edge or UI.
By the way, just a small note: if you want to keep the ‘fluent’ coding style in JUnit tests, there are fluent-helpers to call a method in a cycle-event, e.g.