APIs - External Interfaces

The FENECON Energy Management System (FEMS) provides various external interfaces - so-called APIs, Application Programming Interfaces - through which data can be read out or actions can be performed. In addition, it is possible to integrate e.g. into a network control centre or a smart home system.

1. Local interfaces

Local interfaces provide access to the FEMS on the local network. It is necessary for the accessing device to have direct access to the IP address of the FEMS - for example, it is connected to the same physical network.

1.1. FEMS App REST/JSON-Api, read-only

The "FEMS App REST/JSON-Api, read-only" provides an API interface similar to REST .

This app is included in the standard FEMS scope of delivery.

The base address for the REST accesses is http://<USER>:<PASSWORD>@<IP>:8084/rest

  • http is the protocol

  • <USER> is the username. Since authentication is only done by the password, any value (e.g. "x") can be specified here

  • <PASSWORD> is the user’s password. The default "Guest" user in FEMS has the password "user"

  • <IP> is the IP address of the FEMS

  • 8084 is the port for the REST/JSON api

So if your FEMS has the local IP address '192.168.0.23', the base address for REST accessisis is 'http://x:user@192.168.0.23:8084/rest'

The following API endpoints are available to you:

1.1.1. /channel

The /channel endpoint allows access to individual data points, so-called "Channels", in the system.

For example, to read the State-of-Charge of an energy storage system, send a GET request to the address http://x:user@192.168.0.23:8084/rest/channel/_sum/EssSoc. You will receive a response in JSON format:

{
  "value": 50
}

1.2. FEMS App Modbus/TCP-Api, read-only

The "FEMS App Modbus/TCP-Api, read-only" provides a Modbus/TCP Slave API interface.

This app is included in the standard FEMS scope of delivery.

The Modbus interface is configured as follows:

Table 1. Parameters of the FEMS App Modbus/TCP-Api, read-only

Port

502

Unit-ID

1

Function-Codes

03 (Read Holding Registers)

04 (Read Input Registers)

The interface provides standard access to the channels of the Component '_sum'.

1.2.1. Modbus table

The individual Modbus protocol for your system can be conveniently downloaded via online monitoring as an Excel file. The most important data points can also be found here in the Quick Overview. For details on the contents of the data points, see the Glossary.

Table 2. Modbus table of the FEMS app Modbus/TCP-Api, read-only
Address Channeladdress/Description Data type

2

FEMS Major-Version

uint16

3

FEMS Minor-Version

uint16

4

FEMS Patch-Version; the FEMS-Version is built from Major, Minor and Patch-Version, e.g,: 2020.2.1

uint16

222

_sum/State

uint16

302

_sum/EssSoc

uint16

303

_sum/EssActivePower

float32

315

_sum/GridActivePower

float32

327

_sum/ProductionActivePower

float32

331

_sum/ProductionAcActivePower

float32

339

_sum/ProductionDcActualPower

float32

343

_sum/ConsumptionActivePower

float32

391

_sum/EssActivePowerL1

float32

393

_sum/EssActivePowerL2

float32

395

_sum/EssActivePowerL3

float32

397

_sum/GridActivePowerL1

float32

399

_sum/GridActivePowerL2

float32

401

_sum/GridActivePowerL3

float32

403

_sum/ProductionAcActivePowerL1

float32

405

_sum/ProductionAcActivePowerL2

float32

407

_sum/ProductionAcActivePowerL3

float32

409

_sum/ConsumptionActivePowerL1

float32

411

_sum/ConsumptionActivePowerL2

float32

412

_sum/ConsumptionActivePowerL3

float32

1.2.2. Data types

The following data types are used in the Modbus protocol:

uint16

Unsigned integer in a Modbus 16-bit word

uint32

Unsigned integer in a Modbus 32-bit double word

float32

Floating-point number in format IEEE 754 in a Modbus 32-bit double word

float64

Floating-point number in format IEEE 754 in four Modbus words (64-bit)

string16

String in ASCII format with two characters per Modbus 16-bit word

Note that for data points that are longer than a 16-bit word, the correct length must be read, otherwise you will receive a read error. Example: To read the address 303 '_sum/EssActivePower', it is mandatory to read both Modbus words 303 and 304 (32 bit).

1.2.3. Undefined data

Due to the system state, individual data points may not be available permanently - for example, because there are no power generators or no energy storage systems - or at temporarily - e.g. in the event of a communication error to the network meter. In this case, use the API to read the following values:

Table 3. Modbus: Darstellung von "undefinierten Daten"
Data Type Undefined value

uint16

0xffff

uint32

0xffffffffff

float32

0x7fc000

float64

0x7ff8000000

string16

0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

1.3. FEMS App Websocket/JSON-Api

Todo…​ we are working on it.

1.4. FEMS App REST/JSON-Api read-write

Todo…​ we are working on it.

1.5. FEMS App Modbus/TCP-Api read-write

The "FEMS App Modbus/TCP-Api read-write" provides an Modbus/TCP Slave API interface.

The "FEMS App Modbus/TCP-Api read-write" is an extension of the "FEMS App Modbus/TCP-Api, read-only". The information provided is also valid here.
Table 4. Parameters of the FEMS App Modbus/TCP-Api read-write
Port 502

Unit-ID

1

Function-Codes

03 (Read Holding Registers)

04 (Read Input Registers)

06 (Write Single Holding Register)

16 (Write Multiple Holding Registers)

As in the read-only interface, the standard allows access to the channels of the component '_sum'. Access to additional Components is configured project-specifically - e.g. to access manageable energy storage systems or charging stations via the interface.

1.5.1. Modbus table

The individual Modbus protocol for your system can be conveniently downloaded via online monitoring as an Excel file. The most important data points can also be found here in the Quick Overview. For details on the contents of the data points, see the Glossary.

The Modbus table is structured in blocks. Each block corresponds to a component and is divided according to which properties ("Natures)" the component supports. The block-by-block structure of the Modbus table is based on the SunSpec specification and is designed in such a way that the blocks can also be read completely dynamically.

An OpenEMS system can be identified with "OpenEMS" in the first Modbus register:

Table 5. OpenEMS Identification Header
Address Description Value Data Type

0

Hash of the word "OpenEMS"

0x6201

uint16

Each block has a header area, which is structured as follows:

Table 6. Header data area of a block
Address Offset Description Data type

0

Component ID

string16

16

Length of entire block

uint16

17-19

reserved

20

Hash of the Nature name, see table below

uint16

21

Length of Nature Block

uint16

Table 7. Example Sum-Block
Adresse Beschreibung Wert Datentyp

0

Hash des Wortes "OpenEMS"

0x6201

uint16

1

Länge des Komponenten-Blocks "_meta"

199

uint16

200 (= 1 + 199)

Komponenten-ID

"_sum" als ASCII

string16

216

Länge des gesamten Komponenten-Blocks

300

uint16

220

Hash der Nature "OpenemsComponent"

0xb3dc

uint16

221

Länge des Blocks für "OpenemsComponent"

80

uint16

300 (= 220 + 80)

Hash der Nature "Sum"

0x462b

uint16

301

Länge des Blocks für "Sum"

199

uint16

500 (= 200 + 300)

…​

Table 8. Identification hash values from Natures
Nature Name Hash

OpenemsComponent

0xb3dc

Sum

0x462b

SymmetricEss

0x42ee

AsymmetricEss

0x958f

ManagedSymmetricEss

0xa3ed

ManagedAsymmetricEs

0x5470

All component blocks and nature blocks together form the individual Modbus table for a FEMS. Following, you will find the Nature blocks in detail.

The offset in the Nature table is the value that must be added to the base address of the Nature block. Example:

  • Component base address: 200

  • Basic address of Nature "OpenemsComponent": 220 (= 200 + 20)

  • Offset of the register for the channel "State": 2

  • Modbus tab address for the channel "State": 222 (= 220 + 2)

Access differs in

RO

only reading

RW

reading and writing

RO

only writing

1.5.2. Nature "OpenemsComponent"

Table 9. Nature "OpenemsComponent"
Offset Channel Data type Access

2

State

uint16

RO

1.5.3. Nature "SymmetricEss"

Table 10. Nature "OpenemsComponent"
Offset Channel Data type Access

2

Soc

uint16

RO

3

GridMode

uint16

RO

1.5.4. Nature "SymmetricEss"

Table 11. Nature "SymmetricEss"
Offset Channel Data type Access

2

Soc

uint16

RO

3

GridMode

uint16

RO

1.5.5. Nature "AsymmetricEss"

Table 12. Nature "AsymmetricEss"
Offset Channel Data type Access

2

ActivePowerL1

float32

RO

4

ActivePowerL2

float32

RO

6

ActivePowerL2

float32

RO

1.5.6. Nature "ManagedSymmetricEss"

Table 13. Nature "ManagedSymmetricEss"
Offset Channel Data type Access

2

AllowedChargePower

float32

RO

4

AllowedDischargePower

float32

RO

6

SetActivePowerEquals

float32

WO

8

SetReactivePowerEquals

float32

WO

10

SetActivePowerLessOrEquals

float32

WO

12

SetReactivePowerLessOrEquals

float32

WO

14

SetActivePowerGreaterOrEquals

float32

WO

16

SetReactivePowerGreaterOrEquals

float32

WO

1.5.7. Nature "ManagedAsymmetricEss"

Table 14. Nature "ManagedAsymmetricEss"
Offset Channel Data type Access

2

SetActivePowerL1Equals

float32

WO

4

SetActivePowerL2Equals

float32

WO

6

SetActivePowerL3Equals

float32

WO

8

SetReactivePowerL1Equals

float32

WO

10

SetReactivePowerL2Equals

float32

WO

12

SetReactivePowerL3Equals

float32

WO

14

SetActivePowerL1LessOrEquals

float32

WO

16

SetActivePowerL2LessOrEquals

float32

WO

18

SetActivePowerL3LessOrEquals

float32

WO

20

SetReactivePowerL1LessOrEquals

float32

WO

22

SetReactivePowerL2LessOrEquals

float32

WO

24

SetReactivePowerL3LessOrEquals

float32

WO

26

SetActivePowerL1GreaterOrEquals

float32

WO

28

SetActivePowerL2GreaterOrEquals

float32

WO

30

SetActivePowerL3GreaterOrEquals

float32

WO

32

SetReactivePowerL1GreaterOrEquals

float32

WO

34

SetReactivePowerL2GreaterOrEquals

float32

WO

36

SetReactivePowerL3GreaterOrEquals

float32

WO

2. Cloud interfaces

Cloud interfaces allow access to the FEMS via the FENECON cloud server - i.e. the server through which FEMS Online-Monitoring is implemented. These interfaces are particularly interesting when local access to the FEMS is not possible, e.g. for the implementation of a virtual power plant or for access via mobile apps.

2.1. FEMS App Cloud REST/JSON-Api

The REST/JSON api uses the JSON-RPC protocol.

2.1.1. Connection data

For all connections, use the following data:

Method

POST

URL

https://fenecon.de/fems/rest/jsonrpc

As well as as headers:

Authorization

Basic <Encoded Username + Password>

Content-Type

application/json

When using the REST/JSON api, the jsonrpc: '2.0' und id: UUID parameters required by JSON-RPC are optional.

2.1.2. Status of all FEMS

Returns the status of all FEMS that you have access to.

2.1.2.1. Request
{
  "method": "getEdgesStatus",
  "params": {}
}
2.1.2.2. Response
{
  "jsonrpc": "2.0",
  "id": "UUID",
  "result":{
    "fems1234":{
      "online": true
    },
    "fems4711":{
      "online": false
    }
  }
}

2.1.3. Data points of all FEMS

Reads the current values of specific channels.

2.1.4. Request

{
  "method": "getEdgesChannelsValues",
  "params": {
    "ids": string[],
    "channels": string[]
  }
}

Example:

{
  "method": "getEdgesChannelsValues",
  "params": {
    "ids": [
      "fems1234",
      "fems4711"
    ],
    "channels": [
      "_sum/EssSoc",
      "_sum/ProductionActivePower"
    ]
  }
}

2.1.5. Response

{
  "jsonrpc": "2.0",
  "id": "UUID",
  "result": {
    [Edge-ID: string]: [{
      [Channel-Address: string]: number
    }]
  }
}

Example:

{
  "jsonrpc":"2.0",
  "id":"UUID",
  "result":{
    "fems1234":{
      "_sum/EssSoc":50,
      "_sum/ProductionActivePower":0
    },
    "fems4711":{
      "_sum/EssSoc":99,
      "_sum/ProductionActivePower":null
    }
  }
}

2.1.6. Access to a specific FEMS

To access a specific FEMS, the specific JSON-RPC requests are packaged in a higher-level JSON-RPC request edgeRpc:

{
  "method": "edgeRpc", (1)
  "params": {
    "edgeId": string, (2)
    "payload": {} (3)
  }
}
1 The unique method name
2 The name of the FEMS, e.g. fems1234
3 The payload contains the JSON-RPC request that is forwarded to the FEMS
2.1.6.1. Historical data points

Query historical data.

Request
{
  "method": "queryHistoricTimeseriesData",
  "params": {
    "timezone": Number,
    "fromDate": YYYY-MM-DD,
    "toDate": YYYY-MM-DD,
    "channels": ChannelAddress[],
    "resolution"?: Number
  }
}

Example

{
  "method": "edgeRpc",
  "params": {
    "edgeId": "fems1234",
    "payload": {
      "method": "queryHistoricTimeseriesData",
      "params": {
        "timezone": -2,
        "fromDate": 2020-01-15,
        "toDate": 2020-01-16,
        "channels": [
          "_sum/EssSoc",
          "_sum/ProductionActivePower"
        ]
      }
    }
  }
}
Response
{
  "jsonrpc": "2.0",
  "id": "UUID",
  "result": {
    "timestamps": [
      '2020-01-15T10:15:30Z',...
    ],
    "data": {
      "_sum/EssSoc": [
        50, 51,...
      ],
      "_sum/ProductionActivePower": [
        2000, 2020,...
      ]
    }
  }
}
2.1.6.2. Historical energy values
Request
{
  "method": "queryHistoricTimeseriesEnergy",
  "params": {
    "timezone": Number,
    "fromDate": YYYY-MM-DD,
    "toDate": YYYY-MM-DD,
    "channels": ChannelAddress[]
  }
}
Response
{
  "result": {
    "data": {
      [channelAddress]: number | null
    }
  }
}
2.1.6.3. Excel export of historical data points and energy values
Request
{
  "method": "queryHistoricTimeseriesExportXlxs",
  "params": {
    "timezone": Number,
    "fromDate": YYYY-MM-DD,
    "toDate": YYYY-MM-DD,
    "dataChannels": ChannelAddress[],
    "energyChannels": ChannelAddress[]
  }
}
Response
{
  "jsonrpc": "2.0",
  "id": "UUID",
  "result": {
    "payload": Base64-String
  }
}
2.1.6.4. Read the current configuration
Request
{
  "method": "getEdgeConfig",
  "params": {}
}
Response
{
  "jsonrpc": "2.0",
  "id": "UUID",
  "result": {
    "components": {
      "alias": string,
      "factoryId": string,
      "properties": {
        [key: string]: value
      },
      "channels": {
        [channelId: string]: {}
      }
    },
    "factories": {
      [key: string]: {
        natureIds: string[]
      }
    }
  }
}
2.1.6.5. Create a new component
Request
{
  "method": "createComponentConfig",
  "params": {
    "factoryPid": string,
    "properties": [{
      "name": string,
      "value": any
    }]
  }
}
Response
{
  "jsonrpc": "2.0",
  "id": "UUID",
  "result": {}
}
2.1.6.6. Reconfigure component
Request
{
  "method": "updateComponentConfig",
  "params": {
    "componentId": string,
    "properties": [{
      "name": string,
      "value": any
    }]
  }
}

Example: Changing the configuration of a Fix Active Power Controller for static power setpoints on a Energy storage system:

{
  "method": "edgeRpc",
  "params": {
    "edgeId": "fems1234",
    "payload": {
      "method": "updateComponentConfig",
      "params": {
        "componentId": "ctrlFixActivePower0", (1)
        "properties": [{
          "name": "power",
          "value": -4000 (2)
        }]
      }
    }
  }
}
1 Controller ID
2 Power set-point: positive for discharge; negative for charge
Response
{
  "jsonrpc": "2.0",
  "id": "UUID",
  "result": {}
}
2.1.6.7. Deleting component
Request
{
  "method": "deleteComponentConfig",
  "params": {
    "componentId": string
  }
}
Response
{
  "jsonrpc": "2.0",
  "id": "UUID",
  "result": {}
}
2.1.6.8. Write value

This request can be used, for example, to demand a power set-point on an energy storage system (within the permitted limits).

Request
{
  "method": "setChannelValue",
  "params": {
    "componentId": string,
    "channelId": string,
    "value": any
  }
}
Response
{
  "jsonrpc": "2.0",
  "id": "UUID",
  "result": {}
}
2.1.6.9. Access to a specific component

Various components allow further, specific accesses. Similar to 'edgeRpc', the actual request to the component is wrapped here in a componentJsonApi request.

{
  "method": "componentJsonApi",
  "params": {
    "componentId": string,
    "payload": {}
  }
}

2.2. FEMS App Cloud Websocket/JSON-Api

Todo…​ we are working on it.