Use OpenEMS to manage a simulated microgrid

Hi, I’m working on a research project where I’d like to use OpenEMS to optimize the management of a microgrid. Specifically, I want to implement custom optimization algorithms to make the EMS choose the Distributed Energy Resources (DERs) from which to draw energy, based on economic or environmental criteria. However, before attempting to implement such algorithms, I need to connect an actual microgrid to OpenEMS. Since I currently don’t have access to one, I would like to use a software simulator, preferably one that’s compatible with the Modbus protocol. This would allow me to model a microgrid in the simulator and connect it to OpenEMS Edge.

As I’m completely new to the energy management domain, could you please tell me if this approach is feasible? Additionally, if you’re aware of any, could you suggest some ready-to-use, free simulators? Thank you.

Hi Fabio,
I can’t recommend a ready-to-use simulator, but I probably had a similar task in my MA. I set up a test stand for exactly the same application, but it consisted of real components and virtually simulated ones. I wrote a Python application for simulated consumers and generators, which provided me with a Modbus server and wrote values to it cyclically from a CSV. I used an already implemented meter as a register. The default values of the CSV were standard load profiles and also real recorded measured values. For the battery storage, I programmed a new component in OpenEMS that functions as an interface for an external storage. In principle, this is just a simple Modbus protocol with the data relevant to me. I also simulated this externally using a Python script. This worked well and can be extended as required.

Regards
Josef

1 Like

Thank you for your answer. Could you give me some guidance on how to make such a simulator (i.e. what are the needed components and how they should be linked to each other, if they should)? Another thing I would like to understand is how to implement a two-way communication between the simulator and OpenEMS. As for my understanding, the simulator should produce some values about energy production from its DERs, and send them to OpenEMS via the Modbus server. Then, OpenEMS should use those values, in conjunction with the load information from the consumers (it could be a CSV), to compute setpoints for each DER using some optimization algorithm, and send those setpoints back to the simulator which, eventually, should apply them so that we can see the results. Is this approach correct, and did you do anything similar?

For only ‘measured’ generators or consumers, for which you simply evaluate a meter in the real case, I do it in exactly the same way. To do this, I set up a modbus server with different ports for each meter on my PC using a Python script. I then configured an OpenEMS Modbus bridge

on these and connected this in turn to an implemented Modbus meter e.g. I use the Siemens PAC1600.

To describe the server, I wrote a simple script that has exactly the registers of the real meter. This means that you have integrated the individual meters but not yet a network connection point. You define this by building the point by adding the components virtual substract and virtual add meter.

If you send me your email by personal message, I can also send you a simple example of the virtual meter script in Python.

Another thing I would like to understand is how to implement a two-way communication between the simulator and OpenEMS. As for my understanding, the simulator should produce some values about energy production from its DERs, and send them to OpenEMS via the Modbus server. Then, OpenEMS should use those values, in conjunction with the load information from the consumers (it could be a CSV), to compute setpoints for each DER using some optimization algorithm, and send those setpoints back to the simulator which, eventually, should apply them so that we can see the results. Is this approach correct, and did you do anything similar?

I have done it in a very similar way, as I have integrated a BESS whose behaviour should be controlled by an OpenEMS algorithm. Here I also had a Modbus server, which was described by OpenEMS and an external script. The EMS always wrote my power specification to it and the Python script determined the current power from my model and the specification. In principle, every BESS that is integrated in OpenEMS does this. By simulating the storage system, however, you also have to subtract this power from your grid connection point so that it is correct.

My OpenEMS Component to connect the simulated BESS to OpenEMS is on a public repository, but I haven’t the time to switch it to the official Repo.

Thank you for your help and detailed answers. I have some questions though: supposing you wanted to emulate a microgrid made up by multiple DERs (let’s say a PV panel, a wind turbine, an ESS and a diesel generator), would you need to implement a device in OpenEMS for each of them, or would it be enough to simply implement a meter which collects all the values from all of them, allowing two-way communication with each simulator via Modbus?
Secondly, in your example, if I understood correctly, you created a simulator for a BESS, and you also implemented a corresponding device within OpenEMS, right? What is the role of the meter which you talked earlier about? As for my understanding, you created another simulator for a meter, then connected it to OpenEMS Modbus Bridge which, in turn, was connected to a device implemented within OpenEMS. Is this correct or did I get it wrong?

I have some questions though: supposing you wanted to emulate a microgrid made up by multiple DERs (let’s say a PV panel, a wind turbine, an ESS and a diesel generator), would you need to implement a device in OpenEMS for each of them, or would it be enough to simply implement a meter which collects all the values from all of them, allowing two-way communication with each simulator via Modbus?

If you need only the sum of all Components, you can put it in one component. But if you need all DERs at there own, you have to make it for each component.

Secondly, in your example, if I understood correctly, you created a simulator for a BESS, and you also implemented a corresponding device within OpenEMS, right? What is the role of the meter which you talked earlier about? As for my understanding, you created another simulator for a meter, then connected it to OpenEMS Modbus Bridge which, in turn, was connected to a device implemented within OpenEMS. Is this correct or did I get it wrong?

I think you understand it correct. If you implement a external simulated device, OpenEMS only see what the state of the component is, but this have no impact to the grid meter, because there is no real energy flow. If you use than e.g. a controller to balance the grid point it can’t work correctly. To fix this problem I builded in a production and consumtion meter, that have the same powerflow as the BESS. This one I substract from the grid meter and use the new one as simulated grid meter.

Do both approaches allow for a two-way communication between the simulator and OpenEMS, so that the latter can send parameters to the former, after running some controllers?

This is trickier for me to understand: for “external simulated device” do you mean a device implemented in OpenEMS or within the external simulator? If it is the former, are you saying that, other than the device implemented in OpenEMS, we also need to implement a meter? And for “production and consumption meter” do you mean the same meter or two different ones?

A meter is only a one way component from which OpenEMS read the actuall state. If you have a real meter e.g. your energy meter in your home to measure the energy consumption this can only measure and give you the value but this can’t controll something. If you need a two way communication you have to use a system like the BESS systems they are implemented.

With external simulated device I mean in this context a device that is a simulated device which is simulated external but can communicate with OpenEMS what it actually did and what it has to do. So this has a two-way communication.

This is a nature of the meter.

Have you done the Getting Started Guide before? I think this will help you to understand a little bit more how OpenEMS work and what I mean.

Yes, I followed both the Getting Started and the device implementation guide. My doubts are due to my lack of knowledge on how a microgrid could be emulated and how to connect it to OpenEMS. Anyway, thank you again for your help.

Just for completeness: OpenEMS provides a number of simulated devices out-of-the-box in the Simulator-Bundle: openems/io.openems.edge.simulator at develop · OpenEMS/openems · GitHub

Example:

Regards,
Stefan

Thank you Stefan. I knew there are some simulated devices (I’ve followed the tutorial), but I wanted to emulate the interaction with an external microgrid in the most realistic way.
Anyway, what are the included optimization algorithms to balance the micrigrid? I 've taken a look at the list of controllers, but couldn’t understand the differences between the various algorithms. Could you please explain it in a simple way?

Hi Fabio,

if you have a energy storage system (battery) you will typically want to use the “Balancing Controller” → Controller :: Open Energy Management System

Electric Vehicle Charging Stations are typically controlled in “Surplus-PV-Mode” → Controller :: Open Energy Management System

I’d start with those.

Regards,
Stefan

Thank you Stefan. I’ve had a look at that controller and have tried using it with an ESS device implemented in OpenEMS (thanks to @Josef 's help) and linked to a modbus server. I haven’t understood how the controller is able to actually write the Modbus registers. I know that the code that writes the registers is the applyPower method that must be implemented in the device “impl” class. But who calls it? Is the setActivePowerEqualsWithPid method in the ManagedSymmetricEss interface responsible for it being called? Could you please give me some hints on how to control a modbus ESS through the ESS balancing controller?

One way of finding out how a method is called, is by using Eclipse IDE, right click on applyPower() method and select Open Call Hierarchy. This way you can follow all the methods that lead to this one.

OpenEMS uses a linear equation system with constraints to distribute the power among Energy Storage Systems (ESS). These constraints are very useful for defining limitations and handling environments with multiple ESS. See the docs for an example on Controllers applying limits: Edge Architecture :: Open Energy Management System

In a simple example, the flow is like this:

  • Controller.Symmetric.LimitActivePower in run():
    • ess.addPowerConstraint("SymmetricLimitActivePower", Phase.ALL, Pwr.ACTIVE, Relationship.GREATER_OR_EQUALS, this.maxChargePower);
    • This adds a power constraint to the linear equation system inside the Ess.Power component.
  • Ess.Power listens to the BEFORE_WRITE Cycle event, which:
    • solves the linear equation system (this.solver.solve(this.config.strategy()))
    • and applies the solution this.applySolution(inverterSolutionMap);
  • Solver.java then calls the applyPower() method (ess.applyPower(inv.getActivePower(), inv.getReactivePower());

Regards,
Stefan

Thanks for the explanation. So, applyPower is called by the applySolution method in the Solver class, and the latter is called by the the solve method in the same class, which eventually is called by the handleEvent method in the EssPowerImpl class, which listens to the TOPIC_CYCLE_BEFORE_WRITE event, right? What I don’t understand is how this is related to the this.ess.setActivePowerEqualsWithPid(calculatedPower); method call in the ControllerEssBalancingImpl class. In other words, how do I make it work the ControllerEssBalancing with a modbus ESS? Is this controller suitable to be used with a modbus ESS?

If you follow the this.ess.setActivePowerEqualsWithPid(calculatedPower); you’ll find it calls:

  1. this.getSetActivePowerEqualsWithPidChannel().setNextWriteValue(value); (openems/io.openems.edge.ess.api/src/io/openems/edge/ess/api/ManagedSymmetricEss.java at develop · OpenEMS/openems · GitHub)
  2. SET_ACTIVE_POWER_EQUALS_WITH_PIDonChannelSetNextWrite() (openems/io.openems.edge.ess.api/src/io/openems/edge/ess/api/ManagedSymmetricEss.java at develop · OpenEMS/openems · GitHub)
  3. Which calls ess.setActivePowerEquals(pidOutput); (openems/io.openems.edge.ess.api/src/io/openems/edge/ess/api/ManagedSymmetricEss.java at develop · OpenEMS/openems · GitHub)
  4. Which creates and applies a PowerConstraint object that again calls ess.addPowerConstraintAndValidate(description, phase, pwr, relationship, v); - similarly to the “Controller.Symmetric.LimitActivePower” example above. (openems/io.openems.edge.ess.api/src/io/openems/edge/ess/api/PowerConstraint.java at develop · OpenEMS/openems · GitHub)

I know this sounds complicated, but it’s really made for complex systems with clusters of energy storage systems and has proven well in thousands of systems in production. Most of the times you don’t need to care about it at all. Just implement ManagedSymmetricEss, map the required channels (e.g. AllowedChargePower, AllowedDischargePower, MaxApparentPower) in your modbus ESS and you are done.

Thank you again for your quick answer. I had tried implementing an ESS device (again, thanks to @Josef for his help) and put some logs in the applyPower method. It was always being called with 0 as argument, and I couldn’t figure out why this was happening. Then, thanks to your reply in this thread I’ve understood that I needed to set max apparent power, allowed charge power and allowed discharge power in the Ess impl class, so I’ve set them in the activate method. Now the battery gets discharged, but never charged, and the value passed to applyPower is different from the calculated power in ControllerEssBalancing. Could you please help me making it work? I just want to know how to reproduce the same scenario of the getting started tutorial, but using my Ess instead of SimulatorEssSymmetricReacting. Thank you again for your precious help.

Here are same samples of my Ess class

In the activate method I put this code:

this._setGridMode(GridMode.ON_GRID);
		this._setCapacity(config.capacity());
		this._setMaxApparentPower(config.maxApparentPower());
		this._setAllowedChargePower(config.capacity() * -1);
		this._setAllowedDischargePower(config.capacity());

This is my applyPower method:

@Override
	public void applyPower(int activePower, int reactivePower) throws OpenemsNamedException {
		log.info("applyPower called with active power {}", activePower);
		if (this.config.readOnlyMode()) {
			return;
		}

		EnumWriteChannel setControlMode = this.channel(Ess.ChannelId.SET_CONTROL_MODE);
		IntegerWriteChannel setActivePowerChannel = this.channel(Ess.ChannelId.SET_ACTIVE_POWER);
		IntegerWriteChannel setReactivePowerChannel = this.channel(Ess.ChannelId.SET_REACTIVE_POWER);

		setControlMode.setNextWriteValue(SetControlMode.START);
		setActivePowerChannel.setNextWriteValue(activePower);
		setReactivePowerChannel.setNextWriteValue(reactivePower);
	}

And, finally, this is the defineModbusProtocol method (this is not a real device, hence the very simple register table) :

@Override
	protected ModbusProtocol defineModbusProtocol() {
		return new ModbusProtocol(this, //				

				new FC3ReadRegistersTask(4, Priority.HIGH, 
						m(SymmetricEss.ChannelId.SOC, new UnsignedWordElement(4))),
				new FC3ReadRegistersTask(5, Priority.HIGH, 
						m(SymmetricEss.ChannelId.CAPACITY, new UnsignedWordElement(5))),
				new FC3ReadRegistersTask(7, Priority.HIGH, 
						m(SymmetricEss.ChannelId.ACTIVE_POWER, new SignedWordElement(7))),
			

				new FC16WriteRegistersTask(6,
						m(Ess.ChannelId.SET_ACTIVE_POWER, new SignedWordElement(6))));
	}

P.S.: I’ve noticed that, when using the SimulatorEssSymmetricReacting, the active power passed to the applyPower method is slightly different from the calculated power obtained in ControllerEssBalancing passed to the setActivePowerEqualsWithPid method. I can’t understand why is it so, could you please explain that to me? Do I have to expect the same when using my custom Ess device?

I’m sorry if my questions may sound silly, but I’m new to this domain and, even having read the docs, some things are still not very clear to me.

Your code samples look good. They are similar to the Simulator implementation → openems/io.openems.edge.simulator/src/io/openems/edge/simulator/ess/symmetric/reacting/SimulatorEssSymmetricReactingImpl.java at develop · OpenEMS/openems · GitHub

Now the battery gets discharged, but never charged, and the value passed to applyPower is different from the calculated power in ControllerEssBalancing.

You should try to test this with a Controller.Ess.FixActivePower to be sure that you actually send a negative value for charging.

I’ve noticed that, when using the SimulatorEssSymmetricReacting, the active power passed to the applyPower method is slightly different from the calculated power obtained in ControllerEssBalancing passed to the setActivePowerEqualsWithPid method

This might be because of the PID-Filter. Try disabling it with enablePid property of Ess.Power-Component (-> openems/io.openems.edge.ess.core/src/io/openems/edge/ess/core/power/Config.java at develop · OpenEMS/openems · GitHub).

Instead of relying on the log, you could also run OpenEMS Edge directly from Eclipse IDE. This allows you to set breakpoints and understand more easily whats going on.