Proposal - Connect OpenEMS to OpenEMS

Hallo Paul,

danke für das Proposal! (-> hier nochmal der Link zum Start-Thread: Rest API für Devices).

Mein Vorschlag für die Umsetzung wäre, sich dabei an die bestehende Edge-zu-Backend-Kommunikation anzulehnen. Das “Master”-Edge wäre dann das Backend, mit dem sich mehrere “Slave”-Edges verbinden. Auf Master-Seite bräuchte man einen Websocket-Server - ähnlich dem EdgeWebsocket im Backend; auf Slave-Seite einen Websocket-Client - ähnlich dem Backend-Api-Controller.

Nehmen wir als Beispiel einen Temperaturfühler.

  • Die Nature Thermometer definiert den Channel Temperature.
  • Im “Slave”-Edge laufen folgende Services:
    • Bridge.Onewire als physische Verbindung zur Temperaturfühler-Hardware
    • OneWire.Thermometer, das die Nature Thermometer implementiert
    • Controller.Api.OpenemsMaster, das eine Websocket-Verbindung zum “Master”-Edge herstellt. Authentifizierung über eine Art apikey.
  • Im “Master”-Edge laufen folgende Services:
    • Bridge.OpenemsSlave.Server, das den Websocket-Server für Controller.Api.OpenemsMaster bereitstellt
    • Bridge.OpenemsSlave, das die Verbindung zu einem bestimmten “Slave”-Edge repräsentiert. Es hat als Konfigurationsparameter:
      • slaveServerId: Component-ID der Bridge.OpenemsSlave.Websocket
      • apikey: zur Identifikation des “Slave”-Edge
    • Slave.Thermometer, das die Nature Thermometer implementiert und über die Bridge.OpenemsSlave kommuniziert. Es hat als Konfigurationsparameter:
      • slaveId: Component-ID der Bridge.OpenemsSlave
      • remoteComponentId: Component-ID des OneWire.Thermometer am “Slave”-Edge.

Slave.Thermometer ist unser Zwilling auf Seiten des “Master”-Edge. Sobald es aktiviert wird und die Verbindung über Bridge.OpenemsSlave und Bridge.OpenemsSlave.Server hergestellt ist, schickt es einen subscribeChannels JSON-RPC Request auf alle Channels, die für die Nature gebraucht werden (im Beispiel nur Temperature). Ab dann sendet das “Slave”-Edge ständig über currentData JSON-RPC Notifications die geänderten Werte über seinen Controller.Api.OpenemsMaster zurück.

Dazu ein Bild wie ich mir das vorstelle. (Die Namen sind noch nicht so ganz toll gewählt…)

Live-Edit

Ein paar Ideen/Gedanken dazu:

  • da der Zwilling die richtigen Interfaces implementiert, kann er genauso eingesetzt werden wie eine “native” Komponente
  • statt JSON-RPC könnten wir natürlich auch AMQP, MQTT usw. nehmen.
  • die Verbindung wird vom Slave zum Master hergestellt, was die Firewall-Problematik vereinfachen dürfte
  • da der Websocket-Client am Slave ein Controller ist, kann er von hier auch steuern und unterliegt den entsprechenden Einschränkungen in Bezug auf die Priorität
  • Nicht so einfach ist leider:
    • alles, was kein Channel ist (z. B. Methodenaufrufe in Natures - z. B. getStaticConstraints() bei ManagedSymmetricEss)
    • Übermittlung von Fehlermeldungen. Diese werden zwar im State-Channel gesammelt, dabei geht aber die eigentliche Fehlermeldung (der Fehler-Channel) verloren.
    • diese Probleme sollten sich aber über individuelle JSON-RPC-Requests lösen lassen - vgl. ComponentJsonApi

Würde das für euch funktionieren?
Hast du Bedenken?
Wie sieht das der Rest der Community? Sind damit auch eure Anforderungen abgedeckt?

(Sorry for using German language… please translate this page to your language and you are welcome to reply in Englisch anytime!)

1 Like