BatteryProtection - help in understanding


As per my previous posts, I have been continuing the development work of our battery system in OpenEMS, following the example of the Fenecon Commercial battery system.

I notice that the Fenecon battery system is using the BatteryProtection function of OpenEMS, which appears to allow the definition of parameters which are monitored by the EMS to prevent over/undervoltage scenarios.

Can someone please provide some more information on this functionality and how to use it? Some of the parameters are clear - e.g setting the max charge/discharge currents, but I am unsure how to use others - e.g the Polyline for getDischargeVoltageToPercent.

Any information about the meaning of each of the potential parameters in a BatteryProtectionDefinition and how it is used by Openems would be greatly appreciated!


I also noticed the following code in the activate function:

private void activate(ComponentContext context, Config config) throws OpenemsException {
	this.config = config;
	if (super.activate(context,, config.alias(), config.enabled(), config.modbusUnitId(),, "Modbus", config.modbus_id())) {

	// Initialize Battery-Protection
	this.batteryProtection = BatteryProtection.create(this) //
			.applyBatteryProtectionDefinition(new BatteryProtectionDefinition(), this.componentManager) //

It looks to me as if the BatteryProtection.create function will not be called if super.activate returns true.
The docs for the activate method on AbstractOpenemsModbusComponent indicate say it will return true “if the target filter was updated. You may use it to abort the activate() method.”.

Can someone shed some light on what this means? And why it will not prevent the BatteryProtection from being activated?


Hi Thomas,

the Battery (better the Battery-Management-System - BMS) provides information on the allowed charge and discharge current. The BatteryProtection serves as an additional layer to these limits on an Energy Management System (EMS) level. Its features are are:

  • Soften the ramp-up of charge/discharge power:

    • Often the current limits provided by BMS change in big steps (e.g. from 0 A to 40 A). BatteryProtection applies a MaxIncreaseAmperePerSecond that will steadily increase the value from 0 A to 40 A in this example.
    • Why is this important? The values for DC charge/discharge current are used to calculate the AllowedCharge- and -DischargePower of an Energy Storage System (ESS). Many Controllers will use the maximum available power, so softening these values reduces the stress on the battery.
  • Max charge/discharge current per Cell-Voltage/-Temperature:

    • ChargeVoltageToPercent, DischargeVoltageToPercent, etc. allow the definition of PolyLines to calculate limitations for charge/discharge current based on the minimum/maximum cell voltage or cell temperature.
    • The X-value of the polyline is the cell-voltage or -temperature; Y-value is percentage of actual max current (see InitialBmsMaxEverChargeCurrent)
    • Additionally there are some internal logics implemented to reduce fluctuating
  • Block discharge/Force charge on low battery (and vice versa)

    • ForceDischargeParams and ForceChargeParams allow definition of thresholds. They mark the threshold values for ‘forbid discharge’, ‘force charge’ and ‘stop force-charge’ on empty battery and ‘forbid charge’, ‘force discharge’ and ‘stop force-discharge’ on full battery.
    • Force Charge/Discharge is represented as negative values for allowed charge/discharge current.

All BatteryProtection limits are applied additionally to the BMS limits, i.e. the minimum of all values wins.

Hope that clarifies the features.

To wire OpenEMS Components with each other by Component-ID (e.g. the Battery Components ‘battery0’ requires a Reference to the Modbus Bridge ‘modbus0’), they need a so called ‘target’ filter (see the OSGI Reference 112.3.10 Selecting Target Services).

OpenEMS Components set this target filter automatically using the method you mentioned. A target filter counts as a Component configuration, and a side effect of applying a new configuration is, that the Component will be reinstantiated (as long as there is no ‘@Modified’ method defined).

This means: when the activate method on AbstractOpenemsModbusComponent returns true, the Component configuration was changed, which means the Component will be deativated and activated again. In that case it is feasible to not execute any other tasks in the activate-method. This is true especially for running a task, etc… You will find appropriate code in many places in OpenEMS.


Hi Stefan

Thank you very much for this information - makes it a lot clearer!

In the BatteryProtection, if we are only able to specify certain values (e.g because the manufacturer didn’t provide us with a threshold cell voltage under which the battery should be charged), is it possible to leave these values blank? (i.e will it function correctly if only certain of the BatteryProtection values are defined?