ESS with Multiple Inverters

Hello,

I am writing an OpenEMS device for an ESS, the ESS has different configuration available and can have either 1 or 2 BatteryInverters. The specific inverter already has good support in OpenEMS.

Does anyone have knowledge to share about the best way to implement this?

I have taken the approach of writing an OpenEMS device for our ESS because I don’t believe this configuration is possible with the GenericESS.

I am thinking of having a List<> of the inverters, and when activating the ESS the inverters are added to the list.

I notice that if I try to use a class like SpecificInverterModel in my ESS class I get a warning Discouraged Access: The type SpecificInverterModel is not API. Presumably this is because it is recommended to use the BatteryInverter nature in my ESS instead to maintain generic-ness. If I use the ‘BatteryInverter’ nature instead, will all channels of the SpecificInverter be available, including those that are not included in the BatteryInverter API?

Any help appreciated or general advice appreciated.

Thomas

Hi Thomas,

we call this an “ESS-Cluster”. The idea is to configure two Generic-ESS (“ess1” and “ess2”) and then configure an ESS-Cluster “ess0”. This way you can use “ess0” e.g. in a Fix-Active-Power Controller and power is distributed among “ess1” and “ess2”. Does this work for your use-case?

Regards,
Stefan

Hi Stefan,

Thanks for letting me know about the ESS Cluster. I think that this will definitely be useful for future use cases when we have multiple ESSes.

In this specific case we have a single ESS comprising 2 inverters and a single battery (common DC bus for both inverters). Is there a way to accommodate this in OpenEMS? I am not sure if the ESS-Cluster will work here because it is a single ESS.

I have been taking a look at the code for ESS-Cluster and I am wondering if it is possible to create a similar component for BatteryInverter-Cluster - where it splits the power across multiple inverters. Do you see any issue with doing this?

Regards,
Thomas

Hi Stefan,

I have been busy over the past few hours and have mostly written an BatteryInverter.Cluster device for parallel BatteryInverters based on the ESS.Cluster code.

I am interested in the updateReferenceFilter code in the EssClusterImpl. This appears to be the code that fetches the ESS components based on the config.ess_ids() and adds a reference to them to the List<SymmetricEss> esss.

I am wondering how the updateReferenceFilter method knows that it needs to add the references to the esss List because member passed to updateReferenceFilter is Ess whereas the List is called esss.

@Activate
	private void activate(ComponentContext context, Config config) throws OpenemsException {
		this.config = config;
		super.activate(context, config.id(), config.alias(), config.enabled());
		if (OpenemsComponent.updateReferenceFilter(this.cm, this.servicePid(), "Ess", config.ess_ids())) {
			return;
		}
		this.channelManager.activate(this.esss);
	}

In my BatteryInverter.Cluster implementation I have List<SymmetricBatteryInverter> inverters, would the code OpenemsComponent.updateReferenceFilter(this.cm, this.servicePid(), "Inverter", config.batteryInverterIds()) correctly add the inverters to the cluster?

UPDATE: I asked GPT-4 about how this works and amazingly it explained perfectly about how it is because of the OSGi @Reference annotation and how it injects dependencies! So I understand now :smiley:

Hi @stefan.feilmeier ,

I have created a device for BatteryInverterCluster in my own fork. I have tested it using unit tests, however I have not yet tested it with physical battery inverters (I do not currently have 2 inverters that I can connect in parallel).

The design is very much based on the EssCluster. The logic for applying power to each inverter is that the power is applied in proportion to the MaxApparentPower, and the last inverter takes the remainder of the power.

I have created a PR for the changes:

BatteryInverterCluster - Adds support for clustering of DC-parallel battery inverters by thomasjbhayes · Pull Request #2486 · OpenEMS/openems (github.com)

If you think this would be useful for the community it would be great if it could be reviewed.

Thomas

Thank you Thomas. I’ll try to find time to review the Code. If I had to implement this feature, I would have tried to incorporate the power distribution inside the existing “ESS Power” component, that tries to optimize the distribution among different ESS:

But it might be difficult to add this distribution there… What do you think? Do you see downsides in just proportionally distributing the power among the inverters?

Regards,
Stefan

Hi Stefan,

Thanks for sharing the ESS Power component - I will take a look and see if it can be incorporated.

From my initial research it looks like the Data class in the Ess.Power implementation collects the data on which inverters should be used in the calculation from List<ManagedSymmetricEss> esss and splits the power between the ManagedSymmetricEsss in the List according to the chosen strategy.

In this use case we are dealing with a number of ManagedSymmetricBatteryInverters instead of ESSs. Indeed we might be using the BatteryInverter.Cluster inside a ManagedSymmetricEss and therefore I am not sure if this will work in this case.
Are you aware of an alternative way to work with the Ess.Power component or have I maybe misunderstood how this works?

I have had contact with our inverter manufacturer (KACO) and they have said that the power setpoint should be always equal for parallel inverters.
It looks like the ESS Power component supports a “KeepAllEqual” strategy though so this could suit if we can find a way to use the ESS.Power.

Thomas

Hi Thomas,

your quick analysis is quite on spot. And because everything is based on ESSs there and not Battery-Inverters it will be difficult to add this. Also the code is rather outdated and we are anyway planning a complete overhaul (that should use a linear equation system also for grid/submeter restrictions, EVCS, etc.)

I am not an electrical engineer. If KACO says that power should be distributed equally, maybe we should just follow that path. At least for now.

Thanks.
Stefan

1 Like