ESS Fast Frequency Reserve

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".

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

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"
    }
]

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.

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

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.

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.

2.1.2 Endpoint

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"
                    }
                ]
            }
        }
    }
}

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

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.

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.

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())

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.

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.

3.1.2 Endpoint

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"
              }
            ]
          }
        }
      }
    }
  }
}

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.

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.

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.

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)