APIs - Externe Schnittstellen

Das FENECON Energiemanagementsystem (FEMS) stellt verschiedene externe Schnittstellen - sog. APIs, Application Programming Interfaces - bereit, über die Daten ausgelesen oder Aktionen ausgeführt werden können. Darüber ist die Einbindung z. B. in eine Netzleitstelle oder ein Smart-Home-System möglich.

1. Lokale Schnittstellen

Lokale Schnittstellen ermöglichen den Zugriff auf das FEMS im lokalen Netzwerk. Es ist dafür notwendig, dass das zugreifende Gerät direkten Zugriff auf die IP-Adresse des FEMS hat - also z. B. im gleichen physischen Netzwerk angeschlossen ist.

1.1. FEMS App REST/JSON-Api, lesend

Die "FEMS App REST/JSON-Api, lesend" stellt eine an REST angelehnte API-Schnittstelle zur Verfügung.

Diese App ist im Standard-Lieferumfang des FEMS enthalten.

Die Basis-Adresse für die REST-Zugriffe lautet http://<BENUTZER>:<PASSWORT>@<IP>:8084/rest

  • http ist das Protokoll

  • <BENUTZER> ist der Benutzername. Da die Authentifizierung lediglich über das Passwort erfolgt, kann hier ein beliebiger Wert (z. B. "x") angegeben werden

  • <PASSWORT> ist das Passwort des Benutzers. Der Standard "Gast"-Benutzer im FEMS hat das Passwort "user"

  • <IP> ist die IP-Adresse des FEMS

  • 8084 ist der Port für die REST/JSON-Api

Wenn Ihr FEMS also die lokale IP-Adresse '192.168.0.23' hat, lautet die Basis-Adresse für REST-Zugriffe http://x:user@192.168.0.23:8084/rest

Folgende API-Endpunkte stehen Ihnen zur Verfügung:

1.1.1. /channel

Der /channel Endpunkt ermöglicht den Zugriff auf einzelne Datenpunkte, sogenannte "Channels", im System.

Die vollständige Adresse des Endpunkts lautet http://x:<PASSWORT>@<IP>:8084/rest/channel/<KOMPONENTE>/<KANAL>;

Um z. B. den Ladezustand des Stromspeichers auszulesen, senden Sie einen GET-Request an die Adresse http://x:user@192.168.0.23:8084/rest/channel/_sum/EssSoc. Sie erhalten eine Antwort im JSON-Format:

{
  "value": 50
}

1.2. FEMS App REST/JSON-Api Schreibzugriff

Die "FEMS App REST/JSON-Api Schreibzugriff" stellt eine an REST angelehnte API-Schnittstelle zur Verfügung, mit der Datenpunkte im System beschrieben werden können.

Die Schnittstelle kann z. B. dafür genutzt werden, um einem Stromspeichersystem Leistungsvorgaben zu geben.

Beachten Sie für die Leistungsvorgaben an ein Stromspeichersystem den Punkt Leistungsvorgabe im Glossar.

Sämtliche Schreibzugriffe müssen als POST-Requests gesendet werden.

1.2.1. Timeout

Die "FEMS App REST/JSON-Api Schreibzugriff" verfügt über einen konfigurierbaren Timeout. Im Standard ist dieser auf 60 Sekunden konfiguriert. Er sorgt dafür, dass ein Vorgabewert 60 Sekunden lang aktiv bleibt. Sobald ein neuer Vorgabewert geschrieben wird, wird der neue Wert verwendet. Erfolgt kein neuer Vorgabewert innerhalb von 60 Sekunden, fällt die Steuerung auf den nachrangig priorisierten Controller zurück - z. B. Vorgabe einer "0"-Leistung oder Eigenverbrauchsoptimierung.

1.2.2. /channel

Genau wie bei der "FEMS App REST/JSON-Api, lesend", wird über den Endpunkt /channel der Zugriff auf einzelne Datenpunkte, sogenannte "Channels", im System ermöglicht.

Die vollständige Adresse des Endpunkts lautet http://x:<PASSWORT>@<IP>:8084/rest/channel/<KOMPONENTE>/<KANAL>;

Um z. B. eine feste Leistungsvorgabe an das erste Stromspeichersystem (bzw. den Stromspeicher-Cluster) zu geben, senden Sie einen POST-Request an die Adresse http://x:user@192.168.0.23:8084/rest/channel/ess0/SetActivePowerEquals. Sie erhalten eine Antwort im JSON-Format:

Mehr Informationen zum Channel SetActivePowerEquals und anderen Channels zur Leistungsvorgabe finden Sie im Glossar
{
  "value": 50
}

1.3. FEMS App Modbus/TCP-Api, lesend

Die "FEMS App Modbus/TCP-Api, lesend" stellt eine Modbus/TCP Slave API-Schnittstelle zur Verfügung.

Diese App ist im Standard-Lieferumfang des FEMS enthalten.

Die Modbus-Schnittstelle ist folgendermaßen konfiguriert:

Table 1. Parameter der FEMS App Modbus/TCP-Api, lesend

Port

502

Unit-ID

1

Function-Codes

03 (Read Holding Registers)

04 (Read Input Registers)

Die Schnittstelle ermöglicht im Standard den Zugriff auf die Kanäle der Komponente _sum.

1.3.1. Modbus-Tabelle

Das individuelle Modbus-Protokoll für Ihr System können Sie bequem über das Online-Monitoring als Excel-Datei herunterladen. Die wichtigsten Datenpunkte finden Sie auch hier in der Schnellübersicht. Details zu den Inhalten der Datenpunkte finden Sie im Glossar.

Table 2. Modbus-Tabelle der FEMS App Modbus/TCP-Api, lesend
Adresse Kanal-Adresse/Beschreibung Datentyp

2

FEMS Major-Version

uint16

3

FEMS Minor-Version

uint16

4

FEMS Patch-Version; die FEMS-Version ergibt sich aus Major, Minor und Patch-Version, z. B: 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

351

_sum/EssActiveChargeEnergy

float64

355

_sum/EssActiveDischargeEnergy

float64

359

_sum/GridBuyActiveEnergy

float64

363

_sum/GridSellActiveEnergy

float64

367

_sum/ProductionActiveEnergy

float64

371

_sum/ProductionAcActiveEnergy

float64

375

_sum/ProductionDcActiveEnergy

float64

379

_sum/ConsumptionActiveEnergy

float64

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.3.2. Datentypen

Folgende Datentypen werden im Modbus-Protokoll verwendet:

uint16

Vorzeichenlose Ganzzahl in einem Modbus 16-Bit Wort

uint32

Vorzeichenlose Ganzzahl in einem Modbus 32-Bit Doppelwort

float32

Gleitkommazahl im Format IEEE 754 in einem Modbus 32-Bit Doppelwort

float64

Gleitkommazahl im Format IEEE 754 in vier Modbus Wörtern (64-Bit)

string16

String im ASCII-Format mit zwei Zeichen je Modbus 16-Bit Wort

Beachten Sie, dass bei Datenpunkten, die länger als ein 16-Bit Wort sind, jeweils die richtige Länge gelesen werden muss, andernfalls erhalten Sie einen Lesefehler. Beispiel: Um die Adresse 303 _sum/EssActivePower zu lesen, müssen zwingend beide Modbus-Wörter 303 und 304 (32 Bit) gelesen werden.

1.3.3. Undefinierte Daten

Systembedingt können einzelne Datenpunkte dauerhaft - z. B. weil keine Erzeuger oder kein Stromspeicher vorhanden sind - oder kurzfristig - z. B. bei einem Kommunikationsfehler zum Netzzähler - nicht zur Verfügung stehen. In diesem Fall lesen Sie über die API die folgenden Werte aus:

Table 3. Modbus: Darstellung von "undefinierten Daten"
Datentyp Undefinierter Wert

uint16

0xffff

uint32

0xffffffff

float32

0x7fc000

float64

0x7ff8000000

string16

0x00000000000000000000000000000000

1.4. FEMS App Websocket/JSON-Api

TODO…​ wir arbeiten daran.

1.5. FEMS App Modbus/TCP-Api Schreibzugriff

Die "FEMS App Modbus/TCP-Api Schreibzugriff" stellt eine Modbus/TCP Slave API-Schnittstelle zur Verfügung.

Die "FEMS App Modbus/TCP-Api Schreibzugriff" ist eine Erweiterung der "FEMS App Modbus/TCP-Api, lesend". Die angegebenen Informationen gelten entsprechend auch hier.
Table 4. Parameter der FEMS App Modbus/TCP-Api Schreibzugriff
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)

Wie auch in der lesenden Schnittstelle ist im Standard der Zugriff auf die Kanäle der Komponente _sum freigegeben. Der Zugriff auf weitere Komponenten wird projektspezifisch freigegeben - um z. B. ansteuerbare Stromspeichersysteme oder Ladesäulen über die Schnittstelle freizugeben.

1.5.1. Modbus-Tabelle

Das individuelle Modbus-Protokoll für Ihr System können Sie bequem über das Online-Monitoring als Excel-Datei herunterladen. Die wichtigsten Datenpunkte finden Sie auch hier in der Schnellübersicht. Details zu den Inhalten der Datenpunkte finden Sie im Glossar.

Die Modbus-Tabelle ist dabei in Blöcken strukturiert. Jeder Block entspricht einer Komponente und unterteilt sich je nach dem, welche Eigenschaften ("Natures)" die Komponente unterstützt. Der blockweise Aufbau der Modbus-Tabelle orientiert sich an der SunSpec-Spezifikation und ist so gestaltet, dass die Blöcke auch komplett dynamisch ausgelesen werden können.

Ein OpenEMS-System kann mit dem "OpenEMS" im ersten Modbus-Register identifiziert werden:

Table 5. OpenEMS Identifikations-Header
Adresse Beschreibung Wert Datentyp

0

Hash des Wortes "OpenEMS"

0x6201

uint16

Jeder Block verfügt über einen Kopfdaten-Bereich ("Header"), der wie folgt aufgebaut ist:

Table 6. Kopfdaten-Bereich eines Blocks
Adress-Offset Beschreibung Datentyp

0

Komponenten-ID

string16

16

Länge des gesamten Blocks

uint16

17-19

reserviert

20

Hash des Nature-Namens, siehe Tabelle unten

uint16

21

Länge des Nature-Blocks

uint16

Table 7. Beispiel 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. Identifikations-Hash-Werte von Natures
Nature-Name Hash

OpenemsComponent

0xb3dc

Sum

0x462b

SymmetricEss

0x42ee

AsymmetricEss

0x958f

ManagedSymmetricEss

0xa3ed

ManagedAsymmetricEss

0x5470

Alle Komponenten-Blöcke und Nature-Blöcke zusammen ergeben die individuelle Modbus-Tabelle für ein FEMS. Im Weiteren finden Sie die Nature-Blöcke im Detail.

Das Offset in der Nature-Tabelle ist der Wert, der zur Basisadresse des Nature-Blocks addiert werden muss. Beispiel:

  • Basisadresse der Komponente: 200

  • Basisadresse der Nature "OpenemsComponent": 220 (= 200 + 20)

  • Offset des Registers für den Channel "State": 2

  • Modbus-Registeradresse für den Channel "State": 222 (= 220 + 2)

Zugriff unterscheidet in

RO

nur lesend (read-only)

RW

lesend und schreibend (read-write)

RO

nur schreibend (write-only)

1.5.2. Nature "OpenemsComponent"

Table 9. Nature "OpenemsComponent"
Offset Kanal Datentyp Zugriff

2

State

uint16

RO

1.5.3. Nature "SymmetricEss"

Table 10. Nature "OpenemsComponent"
Offset Kanal Datentyp Zugriff

2

Soc

uint16

RO

3

GridMode

uint16

RO

1.5.4. Nature "SymmetricEss"

Table 11. Nature "SymmetricEss"
Offset Kanal Datentyp Zugriff

2

Soc

uint16

RO

3

GridMode

uint16

RO

1.5.5. Nature "AsymmetricEss"

Table 12. Nature "AsymmetricEss"
Offset Kanal Datentyp Zugriff

2

ActivePowerL1

float32

RO

4

ActivePowerL2

float32

RO

6

ActivePowerL2

float32

RO

1.5.6. Nature "ManagedSymmetricEss"

Table 13. Nature "ManagedSymmetricEss"
Offset Kanal Datentyp Zugriff

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 Kanal Datentyp Zugriff

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-Schnittstellen

Cloud-Schnittstellen ermöglichen den Zugriff auf das FEMS über den FENECON Cloud-Server - also den Server, über den auch das FEMS Online-Monitoring umgesetzt ist. Diese Schnittstellen sind insbesondere dann interessant, wenn kein lokaler Zugriff auf das FEMS möglich ist, z. B. für die Umsetzung eines virtuellen Kraftwerks oder für den Zugriff über mobile Apps.

2.1. FEMS App Cloud REST/JSON-Api

Die REST/JSON-Api verwendet das Protokoll JSON-RPC.

2.1.1. Verbindungsdaten

Verwenden Sie für alle Verbindungen die folgenden Daten:

Method

POST

URL

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

Sowie als Kopfdaten ("Headers"):

Authorization

Basic <Encoded Username + Password>

Content-Type

application/json

Bei Verwendung der REST/JSON-Api sind die von JSON-RPC geforderten Parameter jsonrpc: '2.0' und id: UUID optional.

2.1.2. Status aller FEMSe

Liefert den Status aller FEMSe, auf die Sie Zugriff haben.

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. Datenpunkte aller FEMSe

Liest die aktuellen Werte bestimmter Kanäle.

2.1.4. Request

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

Beispiel:

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

Beispiel:

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

2.1.6. Zugriff auf ein spezifisches FEMS

Um auf ein spezifisches FEMS zuzugreifen, werden die spezifischen JSON-RPC Requests in einen übergeordneten JSON-RPC-Request edgeRpc verpackt:

{
  "method": "edgeRpc", (1)
  "params": {
    "edgeId": string, (2)
    "payload": {} (3)
  }
}
1 Der eindeutige Methodenname
2 Der Name des FEMS, z. B. fems1234
3 Die payload enthält den JSON-RPC Request, der an das FEMS weitergeleitet wird
2.1.6.1. Historische Datenpunkte

Abfrage der historischen Daten.

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

Beispiel

{
  "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. Historische Energiewerte
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 historischer Datenpunkte und Energiewerte
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. Aktuelle Konfiguration lesen
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. Neue Komponente anlegen
Request
{
  "method": "createComponentConfig",
  "params": {
    "factoryPid": string,
    "properties": [{
      "name": string,
      "value": any
    }]
  }
}
Response
{
  "jsonrpc": "2.0",
  "id": "UUID",
  "result": {}
}
2.1.6.6. Komponente umkonfigurieren
Request
{
  "method": "updateComponentConfig",
  "params": {
    "componentId": string,
    "properties": [{
      "name": string,
      "value": any
    }]
  }
}

Beispiel: Änderung der Konfiguration eines Fix Active-Power Controllers zur statischen Leistungsvorgabe an ein Stromspeichersystem:

{
  "method": "edgeRpc",
  "params": {
    "edgeId": "fems1234",
    "payload": {
      "method": "updateComponentConfig",
      "params": {
        "componentId": "ctrlFixActivePower0", (1)
        "properties": [{
          "name": "power",
          "value": -4000 (2)
        }]
      }
    }
  }
}
1 ID des Controllers
2 Leistungsvorgabe: positiv für Entladung; negativ für Beladung
Response
{
  "jsonrpc": "2.0",
  "id": "UUID",
  "result": {}
}
2.1.6.7. Komponente löschen
Request
{
  "method": "deleteComponentConfig",
  "params": {
    "componentId": string
  }
}
Response
{
  "jsonrpc": "2.0",
  "id": "UUID",
  "result": {}
}
2.1.6.8. Wertvorgabe

Über diesen Request kann z. B. eine Leistungsvorgabe an ein Stromspeichersystem (innerhalb der erlaubten Grenzen) gegeben werden.

Request
{
  "method": "setChannelValue",
  "params": {
    "componentId": string,
    "channelId": string,
    "value": any
  }
}
Response
{
  "jsonrpc": "2.0",
  "id": "UUID",
  "result": {}
}
2.1.6.9. Zugriff auf eine spezifische Komponente

Verschiedene Komponenten erlauben weiterführende, spezifische Zugriffe. Ähnlich zu edgeRpc wird der eigentliche Request an die Komponente hier in einen componentJsonApi Request verpackt.

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

2.2. FEMS App Cloud Websocket/JSON-Api

TODO…​ wir arbeiten daran.

2.2.1. Verbindungsdaten

Verwenden Sie für alle Verbindungen die folgenden Daten:

URL

https://fenecon.de/fems-backend-to-backend