Controller

A OpenEMS Edge Controller holds the actual business logic or the actual algorithm that controls hardware. The logic of each active Controller is executed regularly on every Cycle, i.e. once per second.

On each execution cycle, e.g. once every second, the EMS can send a control command, which allows two different ways of controlling the hardware:

  • Control by setpoint

    In “control by setpoint” mode, the EMS calculates setpoint commands and sends them to the hardware for immediate execution.

    Example: A power smoothing algorithm uses the current and previous output power values of a photovoltaics system. By applying its configured maximum defined ramp rate it deduces that the energy storage systems needs to be discharged with 150 kW to compensate a suddenly reduced output power. It therefore sends a setpoint for "discharge with 150 kW" to the ESS for immediate execution.

  • Control by parameterization

    In “control by parameterization” mode, the EMS sends the configuration parameters for control algorithms embedded into the hardware for internal execution.

    Example: In a Virtual Inertia Ancillary Services application, the EMS sends the configuration parameters for the control characteristics to the ESS. The ESS uses this parameter set for its internal, high-performance algorithm.

The following Controllers are implemented in the OpenEMS standard codebase. The links point directly to the source code.

1. Api Backend

Connects to OpenEMS Backend and sends all Channel data regularly. It is implemented as a Controller, as Channels can be written from OpenEMS Backend.

2. Api Modbus

The OpenEMS Edge Modbus-Slave-API is provided by the "Modbus-API Controller". As the Modbus protocol is widely used in industrial monitoring and automation, this allows for easy access to OpenEMS channels from external systems.

The configuration of the Modbus-API controller defines which OpenEMS Components should be exported and made available via the API. It then generates a dynamic Modbus protocol that is structured in address blocks that map to OpenEMS Components and Modbus register addresses that map to OpenEMS channels.

The modbus table is designed in a way that allows dynamic parsing of all available registers.

The following example describes a Controller that is configured to export the Sum-Component (_sum). By reading the headers of the individual blocks, the entire Modbus protocol can be parsed dynamically:

  1. Register 0 identifies the system as an OpenEMS by the hash value 0x17ed6201.

  2. Register 1 shows the length of the first block. Adding the length (199) the current address (1) gives the starting address of the next block (200).

  3. Register 200 gives a string with fixed length of 16 characters with the Component-ID.

  4. Register 216 shows the length of the complete block. Adding the length (300) to the starting address of the block (200) gives the starting address of the next block (500) and so forth.

  5. Register 220 identifies the first sub-block as Nature OpenemsComponent. The length of the sub-block follows in Register 221 and gives the starting address of the next sub-block (300) and so on.

Instead of parsing the Modbus protocol, it is also possible to download the EMS specific Excel file via OpenEMS UI "System Profile" menu. An example export is available in the 'doc' folder of this bundle.

To communicate with specific channels, it is then sufficient to read or write to the matching registers, e.g. - Read register 302 _sum/EssSoc to get the total average state of charge of the ESS. - Write to register 806 ess0/SetActivePowerEquals to trigger charging or discharging of the ESS with ID ess0.

3. Api MQTT

Publishes OpenEMS Edge data to a MQTT broker.

  • edge/{OpenEMS-Edge-ID}/channel/{Component-ID}/{Channel-ID}

    • Data of Channels is published on change and at least every 5 minutes to these topics.

    • Example: edge/edge0/channel/_sum/GridActivePower

  • edge/{OpenEMS-Edge-ID}/channel/lastUpdate

    • Timestamp of the latest data update on any of the Channel topics above.

    • Example: edge/edge0/channel/lastUpdate

  • edge/{OpenEMS-Edge-ID}/edgeConfig

    • Configuration of the OpenEMS Edge instance is published to this topic as a JsonObject.

    • Example: edge/edge0/edgeConfig

4. REST-Api Controller

A REST-Api for external access to OpenEMS Edge. This Controller provides access to Channels and JSON-RPC Requests from an external device via JSON/REST.

The default port for the server is 8084; so the default base address for REST calls is http://x:<PASSWORD>@<IP>:8084/rest, where

  • http is the protocol

  • x is the user. Authentication in OpenEMS is via password only, so the username can be omitted.

  • <PASSWORD> is the user password. If no specific settings have been made, try 'user' or 'admin' here.

  • 8084 is the configured port

A good way to test REST-Api calls is via the Chrome extension Restlet

For more information find the implementation Source Code .

Those are the available REST-Api endpoints:

4.1. Endpoint /rest/channel/<Component-ID>/<Channel-ID>

  • Component-ID is the ID of the Component, e.g. "_sum", "ess0", "meter0",…​

  • Channel-ID is the ID of the Channel, e.g. "ActivePowerL1", "Soc",…​

4.1.1. GET

Use a HTTP request with method GET to read the current value of a Channel.

Example: To read the current state of charge of the battery, send a GET request to http://x:user@localhost:8084/rest/channel/_sum/EssSoC. It returns a response like:

{
  "type":"INTEGER",
  "accessMode":"RO",
  "text":"",
  "unit":"%",
  "value":50
}

The GET api also understands regular expressions. Send a GET request to http://x:user@localhost:8084/rest/channel/.*/Active.*Power to read all ActivePower and ReactivePower channels of all components. It returns a response like:

[
  {
    "address":"pvInverter0/ActivePower",
    "type":"INTEGER",
    "accessMode":"RO",
    "text":"",
    "unit":"W",
    "value":90
  },
  {
    "address":"meter0/ActiveProductionPower",
    "type":"INTEGER",
    "accessMode":"RO",
    "text":"",
    "unit":"W",
    "value":465
  },
  {
    "address":"meter0/ActivePower",
    "type":"INTEGER",
    "accessMode":"RO",
    "text":"",
    "unit":"W",
    "value":465
  },
  {
    "address":"meter0/ActiveConsumptionPower",
    "type":"INTEGER",
    "accessMode":"RO",
    "text":"",
    "unit":"W",
    "value":0
  }
]

4.1.2. POST

Use a HTTP request with method POST to write a Channel.

Example: To switch a Digital-Output or Relay on, send a POST request to http://x:user@localhost:8084/rest/channel/io0/Relay1 with the following body:

{
  "value": true
}

4.2. Endpoint '/jsonrpc'

This allows remote procedure calls (RPC) using JSON-RPC. The JSON-RPC commands need to be sent as POST requests with the specified body.

JSON-RPC usually requires the properties 'id' and 'jsonrpc'. Those can be omitted here, as they are not required for HTTP POST calls.

Following JSON-RPC commands are available:

4.2.1. getEdgeConfig

Gets the current configuration of the OpenEMS Edge.

{
  "method": "getEdgeConfig",
  "params": {}
}

4.2.2. componentJsonApi

Forwards a JSON-RPC payload to a given Component, identified by its Component-ID.

4.2.2.1. getModbusProtocol

Gets the currently active Modbus-TCP protocol definition from the Modbus-TCP-Api Controller with the ID "ctrlModbusTcp0".

{
  "method":"componentJsonApi",
  "params":{
    "componentId":"ctrlApiModbusTcp0",
    "payload":{
      "method":"getModbusProtocol",
      "params":{

      }
    }
  }
}

4.2.3. updateComponentConfig

Updates a Component configuration.

{
	"method": "updateComponentConfig",
	"params": {
		"componentId": "ctrlDebugLog0",
		"properties": [{
 			"name": "enabled",
			"value": true
		}]
	}
}

5. Api Websocket

Provides a JSON/REST implementation via HTTP Websocket for OpenEMS Edge. It provides access to Channels and JSON-RPC Requests from an external device via Websocket. This Controller is used for local connection of OpenEMS UI.

6. Asymmetric Balancing Cos-Phi

Controls an asymmetric energy storage system in self-consumption optimization mode while keeping the grid meter on a defined cos-phi.

7. Asymmetric Fix Reactive Power

Sets a fixed reactive power for an asymmetric energy storage system.

8. Asymmetric Peak-Shaving

Applies asymmetric peak-shaving at the grid meter using a energy storage system. The controller evaluates the grid meter phase with the highest load and discharges the energy storage system accordingly to cut this power peak in order to avoid the fuse to be triggered. On low consumption periods the energy storage system recharges.

9. Asymmetric Phase Rectification

Balances the three phases at the grid using an asymmetric energy storage system.

10. Channel-Threshold

Generic Controller that sets a digital output according to the value of given Channel - e.g. turn a Relay on, when battery state of charge is above a given threshold.

11. CHP control via State-of-Charge (SoC)

Controls a CHP device. Signals the CHP to turn 'ON' when battery SoC is low; signal it to turn 'OFF' when SoC is high. This controller needs four parameters,

  • State of Charge(Soc) of the ESS.

  • Low Threshold(LT) Soc

  • High Threshold(HT) Soc

  • Output channel to signal.

The Soc of the Ess is compared with the LT and HT, and The following operations or state change is performed.

  • If the Soc is less-than("<") LT, signal is sent to the Output channel which eventually turns the CHP device 'ON'.

  • If the Soc is greater-than(">") HT, signal is sent to the Output channel which turns the CHP device 'OFF'.

  • Any other conditions the there is no change in the State of the CHP device.

11.1. Configuration

  • Component-ID Unique ID of this Component (id), e.g. "ctrlIoAlarm0", "ctrlIoAlarm1"

  • Alias Human-readable name of this Component; defaults to Component-ID (alias)

  • Input Channels Addresses of the input State-Channels (inputChannelAddress), This is a array of input state channels.

  • Output Channel Channel address of the Digital Output that should be switched (outputChannelAddress)

  • Low Threshold Low boundary of the threshold

  • High Threshold High boundary of the threshold

11.2. Example Configuration

  • Component-ID : ctrlChpSoc0

  • Alias : myChpCtrl

  • Input Channels : _sum/EssSoc

  • Output Channel : io0/Relay1

  • Low Threshold 25

  • High Threshold 75

_sum/EssSoc - represents the Soc channel of the ESS0, io0/relay1 - represents the relay 1 of the relay board.

12. Detailed Debug Log

Constantly shows the values of all Channels of a Component on the console. Primarily used for developing and debugging.

13. Debug Log

Constantly shows the most important values of all Components on the console. This is often activated by default to be able to track the running system easily.

The 'most important values' are predefined by the individual OpenEMS Components. The configuration allows to

additionalChannels

add additional Channels to the log

ignoreComponents

ignore the output of certain Components

The priority of additionalChannels is higher than ignoreComponents, so an explicitly added Channel will be logged even if the Component has explicitly been ignored.

14. ESS AC-Island

Switches an AC PV inverter to the emergency power on grid outage.

15. Ess Active Power Voltage Characteristic

  • This controller charges/discharges an energy storage system with active power in order to keep the grid voltage within an acceptable range.

  • The active power set-point depends on the ratio of the grid voltage divided by the configured nominalVoltage parameter.

  • The active power per voltage ratio is defined by a poly-line graph in the lineConfig parameter. It takes a Json-Array of the following form:

[
   {
      "voltageRatio":0.95,
      "power":4000
   },
   {
      "voltageRatio":0.97999,
      "power":1000
   },
   {
      "voltageRatio":0.98,
      "power":0
   },
   {
      "voltageRatio":1.0299,
      "power":0
   },
   {
      "voltageRatio":1.03,
      "power":-1000
   },
   {
      "voltageRatio":1.05,
      "power":-4000
   }
]
  • waitForHysteresis parameter: active power set-point is not updated more often than the hysteresis time in seconds. Default value is 20 seconds. The purpose of this parameter is to avoid oscillation in grid voltage via frequently setting power.

16. ESS Balancing

This controls a energy storage system in self-consumption optimization mode by trying to balance the power at the grid connection point, i.e.: - charge the battery, when production is larger than consumption (i.e. when feeding power to the grid) - discharge the battery, when consumption is larger than production (i.e. when buying power from the grid)

16.1. Requirements

  • ManagedSymmetricEss, a controllable energy storage system

  • ElectricityMeter, a meter at the grid connection point

16.2. Additional application notes

Above description assumes that the grid connection point should be balanced to 0 Watt. This bevahiour is configurable using the targetGridSetpoint configuration parameter.

17. Cycle Controller

This controller was developed to support battery cycling or battery capacity test scenarios.

17.1. Configuration

Parameters which should be taken care of:

mode

Select MANUAL_ON to activate the logic

ess_id

Id of the device. ex, ess0

cycleOrder

Initial step decide whether to start with charge or discharge in type of 'CycleOrder'. ex, START_WITH_DISCHARGE

standbyTime

The time to wait between charge and discharge in minutes. ex, standbyTime=5, means wait 5 minute before switching from charge to discharge

startTime

Start time in format [YYYY-MM-DD HH:MM], activates the controller logic at required date and time

maxSoc

The maximum state-of-charge value that will be reached for charging when the controller is activated. For maxSoc=100 charging will be stopped only when 'AllowedChargePower' is 0; otherwise charging stops at maxSoc

minSoc

The minimum state-of-charge value that will be reached for discharging when the controller is activated. For minSoc=0 discharging will be stopped only when 'AllowedDischargePower' is 0; otherwise discharging stops at minSoc

power

The power in Watt to charge or discharge

hybridEssMode

Whether to apply the power on AC or DC side of a hybrid ESS

totalCycleNumber

Number of charge/discharge cycles

finalSoc

After the last cycle, the battery will be charged/discharge to this state-of-charge

17.2. Monitoring

Channels can be followed from Grafana or online monitoring:

ctrlEssCycle0/AwaitingHysteresis

Active when waiting between two states (see standby-time)

ctrlEssCycle0/CompletedCycleNumber

Number of already completed cycles

ctrlEssCycle0/StateMachine

The current State of the State-Machine: UNDEFINED, FINISHED, CHARGE, DISCHARGE, STORE_SOC, etc. states.

17.3. Algorithm logic

Controller starts with UNDEFINED state. First checks for cycleOrder configuration. If it is defined, according to the selection goes to CHARGE or `DISCHARGE state. If cycleOrder is not defined, selection is made according to the Soc value. If Soc is higher than 50 % starts with CHARGE state, otherwise starts with DISCHARGE state.

If the second state is CHARGE state, controller start to charge the system until maxSoc. Again, if it is configured as 100 %, when allowed charge power is 0 W, charge will be stopped. Then, based on the standbyTime configuration will wait until hysteresis completed. Afterwards, will switch to DISCHARGE state.

If the second state is DISCHARGE state, controller start to discharge the system until minSoc. Again, if it is configured as 0 %, when allowed discharge power is 0 W, discharge will be stopped. Then, based on the standbyTime configuration will wait until hysteresis completed. Afterwards, will switch to CHARGE state.

After first CHARGE and DISCHARGE next state will be FINISHED. If the totalCycleNumber is "1", next state will be FINAL_SOC. And in this state, according to the finalSoc system will be charged or discharged last time. If the totalCycleNumber is higher than "1", next cycle will be called. This process will repeat itself until totalCycleNumber reaches. At the end, last state will be FINAL_SOC and required last Soc value will be kept in the battery.

18. ESS Delay Charge

This Controller delays full charing of an energy storage system (ESS) to a certain hour of the day. If for example configured to delay till 4 pm, the allowed charge power is limited in a way, that 100 % State-of-Charge is reached only at 4 pm. The Controller therefor constantly watches the remaining time and remaining capacity of the ESS.

19. ESS Delayed Sell-To-Grid

Controls an energy storage system so, that it delays the sell-to-grid power e.g. of a photovoltaics system.

It charges the battery, when sell-to-grid power exceeds the configured "Sell-To-Grid power limit" and discharges when sell-to-grid power is falling below "Continuous Sell-To-Grid power".

20. ESS Emergency Capacity Reserve

This Controller allows setting a ReserveSoc as the minimum State-Of-Charge that should be reached during normal on-grid operation, i.e. a energy storage system in self-consumption optimization mode will stop discharging at this SoC.

It is used to keep a certain part of the capacity as reserve for power outage situations.

21. ESS Fast Frequency Reserve

21.1. 1.1 Introduction

In electricity networks, the Fast Frequency Reserve (FFR) controller is providing power available to the system operator within a short interval to meet demand in case of a frequency drop, i.e. in case a generator goes down or there is another disruption to the supply. More details on Wikipedia.

This controller helps the Energy Storage System (ESS) to provide power, essentially battery discharge, when the measured "Grid frequency" is lower than that of a defined "Frequency limit".

21.2. 1.2 Controller Parameters

  • mode: mode of the controller, On or Off?

  • id: the id for the controller

  • alias: Alias for the controller

  • enabled: enabled or not?

  • meterId: the id of the meter

  • essId: the id of the Ess

  • batteryInverterId: the id of the battery inverter

  • preActivationTime: A time before the activation time for charging the system(min).

  • schedule: scheduling of the controller, via JSON see below for the example

21.2.1. 1.2.1 The Example Schedule-JSON

[
    {
        "startTimestamp": 1684792800,
        "duration": 86400,
        "dischargePowerSetPoint": 92000,
        "frequencyLimit": 50000,
        "activationRunTime": "LONG_ACTIVATION_RUN",
        "supportDuration": "LONG_SUPPORT_DURATION"
    },
    {
        "startTimestamp": 1684879200,
        "duration": 86400,
        "dischargePowerSetPoint": 6000,
        "frequencyLimit": 50000,
        "activationRunTime": "LONG_ACTIVATION_RUN",
        "supportDuration": "LONG_SUPPORT_DURATION"
    }
]

21.2.2. 1.2.2 JSON Element details

  • StartTimeStamp: When the controller should be activated.

  • Duration: How long is the controller to be activated?

  • frequency limit: The controller continuously monitors and checks whether a Frequency limit or threshold is less than the measured grid frequency.

  • DischargePower: The Ess discharges from the batteries when generating capacity.

  • activationRunTime: The time in milliseconds required for the reserve to fully activate. Short(700 ms) or Medium(1000 ms) or Long(1300 ms) activation Time.

  • supportDuration: The time in milliseconds for which the reserve should continue providing support after the frequency has stabilized. Short(5 seconds) or Long(30 seconds) support duration.

21.2.3. 1.2.3 Explanation of the Schedule

The Schedule JSON activates FFR for a full day (86400 seconds or 24 hours) with the following parameters:

  1. Schedule for 23rd May 2023 00:00:00 to 24th May:

    • Threshold frequency: 49700 mHz

    • Discharge power: 92000 W

    • Long activation time: 1.3 seconds

    • Support duration: 30 seconds

  2. Following Schedule for 24th May 2023 00:00:00 to 25th May:

    • Threshold frequency: 49700 mHz

    • Discharge power: 52000 W

    • Long activation time: 1.3 seconds

    • Support duration: 30 seconds

21.3. 2.1 REST API for updating Fast Frequency Reserve controllers schedule locally

note : The controller/ App should be activated to update the schedule, which can be done using online monitoring or apache felix.

21.4. 2.1.1 Overview

This REST API allows you to update FFR schedule for the specified edge device. The API endpoint takes a JSON payload that specifies the schedule, including the start time, duration, discharge power set point, frequency limit, activation runtime, and support duration.

21.5. 2.1.2 Endpoint

21.6. 2.1.3 Body

The request body must be a JSON object with the following structure:

{
    "method": "componentJsonApi",
    "params": {
        "componentId": "ctrlFastFreqReserve0",
        "payload": {
            "method": "setActivateFastFreqReserve",
            "params": {
                "id": "edge0",
                "schedule": [
                    {
                        "startTimestamp": 1701871562,
                        "duration": 999,
                        "dischargePowerSetPoint": 6000,
                        "frequencyLimit": 502000,
                        "activationRunTime": "LONG_ACTIVATION_RUN",
                        "supportDuration": "LONG_SUPPORT_DURATION"
                    }
                ]
            }
        }
    }
}

21.7. 2.1.4 Request Parameters

The request body for this REST API call is a JSON object with the following parameters:

  • method: The specific method to call within the component. In this case, it is componentJsonApi.

  • params: The parameters associated with the method call.

  • componentId: The unique identifier of the component that is receiving the request.

  • payload: The specific data being sent to the component. See below

21.7.1. 2.1.5 Payload Parameters

Within the payload parameter, there is another JSON object that specifies the details of the activation request:

  • method: The method to call within the component to handle the activation request. In this case, it is setActivateFastFreqReserve.

  • params: The parameters associated with the setActivateFastFreqReserve method.

  • id: The unique identifier of the edge device for which the activation is being requested, locally is always edge0.

  • schedule: An array of schedule items that define the activation pattern for the reserve.

21.7.2. 2.1.6 Schedule Item Parameters

Each schedule item within the schedule array specifies a specific activation period:

  • startTimestamp: The unix time stamp when the FFR should start activating.

  • duration: The duration in milliseconds for which the reserve should remain active.

  • dischargePowerSetPoint: The maximum power in kilowatts that the reserve should discharge during activation.

  • frequencyLimit: The frequency threshold below which the reserve should be activated.

  • activationRunTime: The time in milliseconds required for the reserve to fully activate.

  • supportDuration: The time in milliseconds for which the reserve should continue providing support after the frequency has stabilized.

21.7.3. 2.1.7 Example Python code

import requests
import json
from requests.auth import HTTPBasicAuth

# API URL
url = 'http://10.0.10.178:8084/jsonrpc'

# Authentication
auth = HTTPBasicAuth('x', 'owner')

# Request headers
headers = {
    'Content-Type': 'application/json',
}

# Request payload
payload = {
    'jsonrpc': '2.0',
    'id': '00000000-0000-0000-0000-000000000000',
    'method': 'componentJsonApi',
    'params': {
        'componentId': 'ctrlFastFreqReserve0',
        'payload': {
            'method': 'setActivateFastFreqReserve',
            'params': {
                'id': 'edge0',
                'schedule': [
                    {
                        'startTimestamp': 1701871562,
                        'duration': 999,
                        'dischargePowerSetPoint': 6000,
                        'frequencyLimit': 502000,
                        'activationRunTime': 'LONG_ACTIVATION_RUN',
                        'supportDuration': 'LONG_SUPPORT_DURATION'
                    }
                ]
            }
        }
    }
}

# Make the request
response = requests.post(url, auth=auth, headers=headers, json=payload)

# Print the response
print(response.json())

21.8. 3.1 REST API for Activating Fast Frequency Reserve controllers schedule using Backend

note : The controller/ App should be activated to update the schedule, which can be done using online monitoring or apache felix.

21.9. 3.1.1 Overview

This REST API allows you to update FFR for a specific edge device. The API endpoint takes a JSON payload that updates activation schedule, including the start time, duration, discharge power set point, frequency limit, activation runtime, and support duration.

21.10. 3.1.2 Endpoint

21.11. 3.1.3 Body

The request body must be a JSON object with the following structure:

{
  "method": "edgeRpc",
  "params": {
    "edgeId": "fems3734",
    "payload": {
      "method": "componentJsonApi",
      "params": {
        "componentId": "ctrlFastFreqReserve0",
        "payload": {
          "method": "setActivateFastFreqReserve",
          "params": {
            "id": "edge3734",
            "schedule": [
              {
                "startTimestamp": "1701767477",
                "duration": "11000",
                "dischargePowerSetPoint": "6000",
                "frequencyLimit": "52000",
                "activationRunTime": "LONG_ACTIVATION_RUN",
                "supportDuration": "LONG_SUPPORT_DURATION"
              }
            ]
          }
        }
      }
    }
  }
}

21.12. 3.1.4 Request Parameters

  • method: The JSONRPC method to call. In this case, it is edgeRpc.

  • params: The JSONRPC parameters.

  • edgeId: The ID of the edge device for which to activate the FFR.

  • payload: The JSONRPC payload.

21.13. 3.1.5 Payload Parameters

Within the payload parameter, there is another JSON object that specifies the details of the activation request:

  • method: The JSONRPC method to call within the component. In this case, it is componentJsonApi.

  • params: The JSONRPC parameters for the componentJsonApi method.

  • componentId: The ID of the component within which to call the method. In this case, it is ctrlFastFreqReserve0.

  • payload: The JSONRPC payload for the method.

21.14. 3.1.6 Schedule Item Parameters

Each schedule item within the schedule array specifies a specific activation period:

  • startTimestamp: The unix time stamp in milliseconds when the FFR should start activating.

  • duration: The duration in milliseconds for which the reserve should remain active.

  • dischargePowerSetPoint: The maximum power in kilowatts that the reserve should discharge during activation.

  • frequencyLimit: The frequency threshold below which the reserve should be activated.

  • activationRunTime: The time in milliseconds required for the reserve to fully activate.

  • supportDuration: The time in milliseconds for which the reserve should continue providing support after the frequency has stabilized.

21.15. 3.1.7 Example Python code:

import requests
import json
from requests.auth import HTTPBasicAuth
import base64
import os

url = "https://fenecon.de/fems/rest/jsonrpc"

username = os.getenv("FENECON_USERNAME")
password = os.getenv("FENECON_PASSWORD")

headers = {
    "Content-Type": "application/json",
    "Authorization": "Basic " + base64.b64encode(f"{username}:{password}".encode("utf-8")).decode("utf-8")
}

body = {
    "method": "edgeRpc",
    "params": {
        "edgeId": "fems3734",
        "payload": {
            "method": "componentJsonApi",
            "params": {
                "componentId": "ctrlFastFreqReserve0",
                "payload": {
                    "method": "setActivateFastFreqReserve",
                    "params": {
                        "id": "edge3734",
                        "schedule": [
                            {
                                "startTimestamp": "1701767477",
                                "duration": "11000",
                                "dischargePowerSetPoint": "6000",
                                "frequencyLimit": "52000",
                                "activationRunTime": "LONG_ACTIVATION_RUN",
                                "supportDuration": "LONG_SUPPORT_DURATION"
                            }
                        ]
                    }
                }
            }
        }
    }
}

response = requests.post(url, headers=headers, data=json.dumps(body))

if response.status_code == 200:
    print("Fast Frequency Reserve activated successfully")
else:
    print("Error activating Fast Frequency Reserve:", response.text)

22. Symmetric Fix Active Power

Sets a fixed active power for charging/discharging of a symmetric energy storage system.

23. ESS Fix State Of Charge

Sets active power constraints for charging/discharging of a symmetric energy storage system, to reach a final SoC under the constraints below.

  • State of Charge should be reached at a certain time or as fast as possible

  • State of Charge is held for a configured time or optionally until a specific end condition is fulfilled

24. ESS Grid Optimized Charge

Combination of the PredictiveDelayCharge and the SellToGridPowerLimit controllers:

Delays the charging of the AC or DC storage system based on predicted production and consumption given by the PredictorManager.

Even during the delayed charging, the battery is able to force charge when the sell-to-grid power exceeds the configured "Sell-To-Grid maximum power limit". This is mainly used when only 70 percent of the maximum production is allowed to feed in to the grid.

25. Hybrid-Ess Surplus-Feed-To-Grid Controller

Controls a Hybrid Battery Inverter (i.e. integrated Energy Storage System) so, that the surplus DC production of its chargers gets fed to grid.

26. ESS §14a EnWG Controller

Established by law (for Germany), this controller lowers active power to -4200 W in response to grid operator limitations, aiming to alleviate load on transformers.

27. ESS Limit Total Discharge

Limits the discharge power of an energy storage system according to its State-of-Charge, e.g. to keep energy for emergency power or to avoid deep discharge.

28. ESS Linear Power Band

Executes a test cycle for an energy storage system by increasing and decreasing the charging/discharging power in given limits.

29. ESS Minimum Discharge Period

Provides a minimum discharge power of the storage system for a configured time period, if a certain power peak has been reached.

This can be used in some systems where the allowed charge power has been set to zero and the storage needs a minimum discharge power for a certain time, to recognize that the storage is not full and the allowed charge power should be higher.

30. Ess Reactive Power Voltage Characteristic

  • This controller sets reactive power of an energy storage system in order to keep the grid voltage within an acceptable range.

  • The reactive power set-point depends on the ratio of the grid voltage divided by the configured nominalVoltage parameter.

  • The reactive power set-point is defined as percent of the maximum apparent power of the inverter.

  • The reactive power per voltage ratio is defined by a poly-line graph in the lineConfig parameter. It takes a Json-Array of the following form:

[
   {
      "voltageRatio":0.9,
      "percent":60
   },
   {
      "voltageRatio":0.93,
      "percent":0
   },
   {
      "voltageRatio":1.07
      "percent":0
   },
   {
      "voltageRatio":1.1,
      "percent":-60
   }
]
  • waitForHysteresis parameter: reactive power set-point is not updated more often than the hysteresis time in seconds. Default value is 20 seconds. The purpose of this parameter is to avoid oscillation in grid voltage via frequently setting power.

31. ESS Sell-To-Grid Limit

Limits the maximum sell-to-grid power by actively charging the Ess. Can be used to apply a 70 % limit to the sell-to-grid power according to German law.

32. ESS Standby

Regularly checks the functionality of an ESS once per week while being in Standby mode.

Use-Case

In projects with Hochlastzeitfenster (HLZF) the storage system might not be used for some weeks or months. In these periods it is required to make a regular check of the system and to calibrate the battery. This controller automates this function.

Scheduling

The controller is supposed to be configured to run with less priority than "LimitTotalDischarge", "BatteryHandling",…​ and higher priority than "HLZF", "Balancing", "Peak-Shaving",…​

33. ESS Time-of-Use Tariff

This Controller optimizes the performance of an energy storage system (ESS) in conjunction with a Time-Of-Use (ToU) Tariff provider.

The primary aim of the controller is to optimize the economic utilization of energy stored within the battery, primarily for self-consumption. To achieve this goal, the controller employs a rolling approach, where it continuously fetches predictions from the prediction service. It takes into account the current state of the battery’s capacity, recalculates its operations, and generates a detailed schedule for the Energy Storage System (ESS) for the upcoming 24-hour period, in 15-minute intervals.

This iterative and dynamic approach ensures that the ESS operates efficiently by staying synchronized with real-time forecasts and the evolving state of the battery, thereby maximizing cost-effectiveness and self-consumption of stored energy.

33.1. Schedule Calculation Modes

The schedule calculation process varies depending on the local market conditions. To accommodate this variability, two distinct modes have been introduced to facilitate flexible operation:

CHARGE_CONSUMPTION

This mode is well-suited for markets that permit charging the battery from the grid. In this mode, the controller utilizes production and consumption forecasts along with day-ahead electricity prices to calculate the optimal time periods for charging the battery from the grid. This approach ensures efficient utilization of resources while taking advantage of cost-effective grid charging opportunities.

DELAY_DISCHARGE

This mode is tailored for markets where grid charging is restricted or discouraged. In such scenarios, optimal time periods are determined based on forecasts and day-ahead pricing information. The controller then schedules the Energy Storage System (ESS) to limit or delay discharging during these specific periods. This strategic approach aims to optimize economic performance by avoiding costly grid interactions when grid charging is not feasible or economical.

These two operation modes provide the necessary flexibility to adapt to varying market conditions, allowing for efficient energy management and cost savings based on the specific requirements of your local energy market.

34. EVCS

Controls an Electric Vehicle Charging Station (EVCS) in different modes, like "Force-Charge" and "Surplus Energy Charging".

35. EVCS Fix Active Power

Sets a fixed maximum charge power to an Electric Vehicle Charging Station (EVCS).

36. Generic JsonLogic

The JsonLogic-Controller is a very generic Controller that allows the definition of a complex logic as a configuration at runtime, e.g. via Apache Felix Web Console.

It is based on the JsonLogic specification (jsonlogic.com). Logics can be defined by a rule:

{
   "if":[
      {
         "<":[
            {
               "var":"_sum/EssSoc"
            },
            50
         ]
      },
      [
         [
            "ess0/SetActivePowerEquals",
            5000
         ]
      ],
      [
         [
            "ess0/SetActivePowerEquals",
            -2000
         ]
      ]
   ]
}

The input data that is referenced via var is automatically provided from OpenEMS Channels - e.g. as

{
   "_sum/EssSoc": 40
}

This example would result in:

[
    "ess0/SetActivePowerEquals",
    5000
]

i.e. the Controller will require a set-point of 5000 W discharge on ess0.

It is also possible to write to multiple channels, by adding more arrays to the result.

37. High-Load Timeslot

Controls an energy storage system for a High-Load timeslot application (German "Hochlastzeitfenster").

38. IO Alarm

Switches a digital output, when one or more State-Channels are set. This controller can be used to signal alarms. This controller is used to check for the State-Channels which are boolean type, which typically represents the error channels. A specific configured digital output channel can be signaled based on the configured input State-Channels(one more channels).

38.1. Configuration

  • Component-ID Unique ID of this Component (id), e.g. "ctrlIoAlarm0", "ctrlIoAlarm1"

  • Alias Human-readable name of this Component; defaults to Component-ID (alias)

  • Input Channels Addresses of the input State-Channels (inputChannelAddress), This is a array of input state channels.

  • Output Channel Channel address of the Digital Output that should be switched (outputChannelAddress)

Multiple instances can be created in "Apache felix" during the configuration for each Output channel signal.

38.2. Example Configuration

  • Component-ID : ctrlIoAlarm0

  • Alias : myIoAlarm

  • Input Channels : [ess0/State15, ess0/State33, ess0/State43]

  • Output Channel : io0/Relay1

ess0/State15 - represents the State15 channels of the ESS0, io0/relay1 = represents the relay 1 of the KM tronic relay board.

The above example configuration describes, if any of the configured three input channels is set to "True" then a signal "True" is sent to output channel, else the "False" signal is sent to output channel.

39. IO Analog Controller

Controller that sets a analog output according to the configured inputs to OFF|AUTOMATIC|ON.

In AUTOMATIC mode the output is set dynamically depending on the current surplus power.

40. IO Channel-Single-Threshold

Generic Controller that sets a digital output according to the value of given Channel - e.g. turn a Relay on or off, when configured input channel/SoC is above or below a given threshold respectively.

41. IO Fix Digital Output

Sets a digital output statically ON or OFF.

42. IO Heating Element

Controls a three-phase heating element via Relays, according to grid active power.

42.1. Phase and Level

The Controller distinguishes the definition of Phase and Level. Phase represents the electrical phase L1, L2 or L3. Level represents how many Phases are active at one point in time:

  • Level 1: only Phase L1 is active

  • Level 2: Phase L1 and L2 are active

  • Level 3: all three Phases are active

42.2. Channels

Example: * the power of the heating element per phase is 1000 W * each "x" below represents one hour

Assume the Controller was activating Phases L1, L2 and L3 during the day like this:

L3|           xxx
L2|        xxxxxxxxx
L1|     xxxxxxxxxxxxxxxx
 t|------------------------
Channel Phase1Time

= 16 h = 57600 sec

        |--------------|
Channel Phase2Time

= 9 hours = 32400 sec

           |-------|
Channel Phase3Time

= 3 hours = 10800 sec

              |-|
Channel Level1Time

= Phase1Time - Phase2Time = 7 hours = 25200 sec

        |-|         |--|
Channel Level2Time

= Phase2Time - Phase3Time = 6 hours = 21600 sec

           |-|   |-|
Channel Level3Time

= Phase3Time = 3 hours = 10800 sec

              |-|
Channel TotalTime

28000 Wh = 28 kWh

Channel TotalPhaseTime

= Phase1Time + Phase2Time + Phase3Time = 16 + 9 + 3 = 28 h = 100800 sec

43. IO SG-Ready Heat Pump

Controls a heat pump that implements the SG-Ready standard via two Relay contacts, depending on surplus power and battery state-of-charge.

43.1. States

The Controller distinguishes the different States, according to the SG-Ready standard.

Name Description

Lock State

The lock state blocks everything till an internal maximum time of (default) two hours

Regular State

The heat pump runs in energy-efficient standard operation

Recommendation State

State: The heat pump runs in a more sufficient mode for space heating and hot water production, to use available surplus power

Force-On State

The heat pump runs in a definitive start/heat-up mode. Depending on the heat pump, heating is forced and additional heaters may be switched on

43.2. Channels

The Controller has an ongoing time counter for every state, that is started and stopped if the corresponding state is active or not.

Minimum switching time: As an additional preventative, the controller has a minimum switching time. If a state changed, it will wait for this time (default 60 seconds) till the next state can be set.

44. PV-Inverter Fix Power Limit

Sets a fixed power limit for PV-Inverter production.

45. PV-Inverter Sell-To-Grid limit

Dynamically limits the Sell-To-Grid power of a PV-Inverter to a defined maximum power.

If the configured mode is asymmetric, the controller evaluates the grid meter phase with the highest Sell-To-Grid power and curbs the PV-power of the configured PV-Inverter. The main purpose of the asymmetric mode is, to prevent the grid fuse from overcurrent.

46. Symmetric Balancing Schedule

Controls a symmetric energy storage system in balancing mode. The control algorithm charges or discharges the battery in order to reach a given power target set-point at the grid connection point. If the target set-point is defined as zero, the behaviour is like with self-consumption optimization.

This controller allows two ways of controlling the power target set-point:

46.1. 1. Definition of a power target set-point Schedule

The static configuration parameter "schedule" takes a Schedule of set-points as a Json-Array. An example schedule looks like this:

[
	{
		"startTimestamp": 1577836800,
		"duration": 900,
		"activePowerSetPoint": 0
	}, {
		"startTimestamp": 1577837700,
		"duration": 900,
		"activePowerSetPoint": -2000
	}
]

This schedule will activate a power target set-point of zero starting at the epoch time 1577836800 (i.e. seconds since 1st January 2020 00:00:00 in timezone UTC), that lasts for 900 seconds (i.e. 15 minutes). Afterwards - from 1577837700 - for another 900 seconds a set-point of -2000 W (i.e. feeding 2000 W to the grid) is targeted. After the second period passes, no more charging or discharging commands are set on the battery.

The schedule configuration parameter may be updated

Be aware that an UpdateComponentConfigRequest will always result in a actual configuration file being updated by Apache Felix Configuration Admin, so this command should not be used too frequently, e.g. only once per day. The SetGridConnScheduleRequest variant runs only in memory and is not persisted. Downside is, that if OpenEMS Edge gets restarted, the schedule is lost.

46.2. 2. Immediate control of the power target set-point

The power target set-point may also be controlled directly via the GridActivePowerSetPoint channel. E.g. if the controller component has the Id ctrlBalancingSchedule0 one can use e.g. the REST-Api Controller and write

{
	"value": 5000
}

to the channel ctrlBalancingSchedule0/GridActivePowerSetPoint (e.g. ` http://x:user@localhost:8084/rest/channel/ctrlBalancingSchedule0/GridActivePowerSetPoint`), to set a temporary power target set-point of 5000.

47. Symmetric Fix Reactive Power

Sets a fixed reactive power for a symmetric energy storage system.

48. Symmetric Limit Active Power

Limits the allowed active power for charging and discharging of a symmetric energy storage system.

49. Symmetric Peak-Shaving

Applies peak-shaving at the grid using a symmetric energy storage system.

50. Symmetric Random-Power

Applies random charging/discharging of a symmetric energy storage system for performance tests.

51. Symmetric Timeslot Peak-Shaving

Applies peak-shaving within a configured timeslot at the grid using a symmetric energy storage system. Outside of the timeslot the battery recharges.

This Controller can be used for "Atypische Netznutzung" applications in Germany, e.g. "Hochlastzeitfenster".