Ladestation für Elektrofahrzeuge (OCPP-Protokoll)

Hallo,

Ein etwas diskussionsorientiertes Thema, um zunächst die Stimmung zu testen: Würde eine Integration einer „Ladestation für Fahrzeuge“ jemanden interessieren?

Daraus ergeben sich dann mehrere Fragen:

  • OK, aber wofür? Zunächst denke ich, dass es hauptsächlich für den „Verbrauch“ von Daten sein würde… aber vielleicht nicht ausreichend?
  • OK, aber welcher Art von Integration?
    • Vollständig in Gladys integriert: Gladys hostet den Code auf seiner Seite… nicht sicher, ob das eine hervorragende Idee ist, aber warum nicht absolut. Vielleicht ist das am Ende das am besten integrierte?
    • Im ocpp2mqtt-Modus: ein bisschen wie Zigbee und Z-Wave: man stützt sich auf ein anderes Projekt, das als CSMS fungiert und die Nachrichten auf einen MQTT-Broker veröffentlicht. Der Broker kann auch dazu dienen, Befehle an die Ladestation zu senden. In diesem Modus kommuniziert die Ladestation nicht mehr mit dem nativen Cloud-Server der Ladestation
    • Im Relay 2 mqtt-Modus: In diesem Modus fungiert ein Programm als Vermittler, um die Nachrichten an den MQTT-Broker weiterzuleiten, während die Nachrichten zum nativen Cloud weitergeleitet werden. Gladys kann, vorläufig, nur Nachrichten empfangen, aber keine an die Ladestation senden (absolut ja, aber asynchron mit dem Cloud-CSMS… nicht sicher über die Auswirkungen).
    • Über Node-Red? In diesem Fall gibt es in Gladys nichts wirklich zu tun, eher eine Frage des Tutorials? (Ich bin gerade auf diese Lösung gekommen, als ich den Beitrag geschrieben habe, ich gebe es zu)

Ich habe einige erste Recherchen begonnen, ich habe noch etwas Schwierigkeiten, alles zu identifizieren, was man mit dem Protokoll machen könnte (wobei es 2/3 Versionen davon gibt). Daten empfangen scheint mehr oder weniger in Ordnung zu sein. Beim Senden von Befehlen habe ich noch nicht herausgefunden, was möglich ist, aber grundsätzlich warum nicht. Deshalb dieser Post: Sind Personen interessiert? Welche Informationen können zurückgemeldet werden? Welche Befehle können gesendet werden?

Für die verschiedenen Optionen gibt es mehr oder weniger unterschiedliche Vorgehensweisen:

Das ist alles, ich habe keine Antwort, ich habe noch keine vollständig klare Lösung… ich möchte die Stimmung testen, um zu sehen, ob es Interesse gibt oder nicht.

Hallo @Sescandell!
Ich bin sicher, dass das viele Leute interessieren würde, und ich denke, es ist ein hervorragender Kandidat für zukünftige externe Integrationen in Gladys :blush:

Hallo,

Ich bin heiß darauf, diesen Ansatz zu versuchen. Selbst erstmal an einem einfachen POC.

Ich habe eine Testumgebung zur Verfügung… Ich werde damit beginnen, zu erkunden, was außerhalb von Gladys überhaupt möglich ist, um mich mit allem vertraut zu machen.

Falls jemand Erfahrung mit diesem Protokoll hat, meldet euch, ich bin dankbar dafür :wink:

Das ist eine wertvolle Idee. Statt sie sofort vollständig in Gladys zu integrieren, wäre eine Verbindung über OCPP-to-MQTT möglicherweise praktischer; sie erleichtert das Testen und ermöglicht die erste Implementierung von Funktionen wie Ladezustand, Leistungsabgabe, Energieniveaus und Start/Stopp-Steuerung.

Eine tiefere native Integration kann in Betracht gezogen werden, sobald die spezifischen Nutzungsanforderungen klar sind.

Kleiner Fortschrittsbericht (ich gehe das trotzdem vorsichtig an, ich möchte die Ladestation nicht überlasten… oder das Auto… oder schon gar nicht das Haus :smiley: )

Aktuell habe ich eine relativ einfache Schleife, abseits von Gladys. Dank des Projekts GitHub - gyzod/ocpp2mqtt: OCPP <==> MQTT Gateway · GitHub & GitHub - ocpp-balanz/ocpp-2w-proxy: A 2 way OCPP proxy · GitHub konnte ich jedoch eine Weboberfläche erstellen, die mir den aktuellen Zustand meiner Ladestation anzeigt.
Die Idee des Projekts ocpp-2w-proxy ist, wie der Name schon sagt, als Proxy (eine Art Man-in-the-Middle) zwischen der Ladestation und dem nativen Cloud-Server zu agieren.

Damit bleibt die Steuerung über die native App erhalten. In meinem Fall funktioniert meine Autel Charger App weiterhin zu 100% (soweit ich es bisher getestet habe…). Mein MQTT empfängt auch alle Nachrichten. Dadurch kann ich eine Weboberfläche aktualisieren, die derzeit noch eine Art Placeholder ist.

Mein Problem liegt im Starten eines Ladevorgangs. Die Konfiguration ändern, das Anhalten, das Aktualisieren: alles funktioniert. Aber das Starten einer Ladung, da bin ich momentan blockiert.

Vielleicht wird der erste Schritt also sein, den Zustand der Ladestation anzuzeigen. Dann können wir später herausfinden, was nicht funktioniert.

Ich habe auch einige Bedenken, denn ich musste den Quellcode der referenzierten Projekte ändern, damit es funktioniert. Ich werde diesen Punkt noch einmal überprüfen, vielleicht ist es ein Fehler meinerseits.

Nichts, was mit Gladys zu tun hat, aber sobald ich sicher bin, dass es funktioniert: los geht’s mit dem Plugin :wink:

Wenn ich du wäre, würde ich Claude mit allen Informationen aus diesem Beitrag zum Thema hinzuziehen :slight_smile:

In 30 Minuten hast du eine externe Gladys-Integration, die mit hoher Wahrscheinlichkeit beim ersten Versuch funktioniert, testbar mit einem Klick in Gladys, und du kannst von dort aus iterieren.

Von Anfang bis Ende denke ich, dass eine externe Integration heute weniger als eine Stunde Arbeit bedeutet, ohne dass man sich mit der API oder dem Code beschäftigen muss.

Auf meiner Seite sind die Ergebnisse, die ich erhalte, wirklich sauber, oft besser als die Arbeit, die ein menschlicher Entwickler geleistet hätte, weil alle Randfälle gut verwaltet werden, es lohnt sich also, es auszuprobieren :smiley:

Es geht hier nicht so sehr um die Schnelligkeit oder die Handhabung der APIs: Das ist noch nicht der Schritt (dieser Punkt beunruhigt mich nicht, er wird schnell von der KI behandelt).

Das Thema ist, das Tool, das wir drumherum setzen, gut zu verstehen und zu beherrschen, was gemacht wird: die Fähigkeiten und die Organisation zwischen occp-2w-prxy und ocpp-2mqtt (und ob es überhaupt die richtigen Tools sind. Typischerweise die Einschränkung von Start, ich frage mich, ob das native HA-Plugin das gleiche Problem hat oder nicht: lbbrhzn/ocpp: Home Assistant Integration für Elektrofahrzeug-Ladegeräte, die das Open Charge Point Protocol (OCPP) unterstützen.)

Das ist es vorerst. Sobald alles klar ist, erstelle ich das Gladys-Plugin, das wird schnell gehen, denke ich :wink:

@Sescandell Warum werden ocpp-2w-prxy und ocpp-2mqtt verwendet?

Könnte die KI nicht direkt den gesamten Stack in die Gladys-Integration umschreiben? :slightly_smiling_face: So könnte man die Abhängigkeit von diesen externen Projekten vermeiden und gleichzeitig die Kontrolle über die Implementierung, die Weiterentwicklung und die Fehlerbehebung behalten. Das würde auch langfristig mehr Flexibilität bieten, oder?

Das war auch eine der möglichen Optionen, die im ursprünglichen Beitrag erwähnt wurden. Sind wir uns einig, dass, wenn du « die gesamte Stack in Gladys » sagst, wir bei der Idee eines « externen Plugins über die API » bleiben?

Die Frage lässt sich darauf reduzieren, warum man etwas neu entwickeln möchte, das bereits existiert. Ich übertreibe, aber im Grunde fragst du: Warum hat man sich für zigbee2mqtt entschieden, anstatt es neu zu entwickeln? Wenn es auf dem Markt Lösungen gibt, die den Job erledigen, warum möchte man sie neu implementieren? Interpretiere ich die Frage falsch?

Wenn diese beiden Projekte den Job erledigen, sollte man sie auch nutzen. Wenn sie jedoch einschränkend sind, schaue ich mir eine hausgemachte Implementierung an. Im Grunde genommen würde ich fast sagen, dass es als « externes Plugin » ein « Implementierungsdetail » ist?

Ich habe noch keine klare Meinung zu der Frage. Was mich betrifft, bin ich immer noch in der Erkundungsphase, was die Möglichkeiten angeht. Ich denke, dass ich dieses Wochenende etwas daran arbeiten werde, um eine Integration voranzutreiben.

Ja, das ist genau die Frage. :slightly_smiling_face: Aber genau das ist der Punkt: Wenn ich mir ocpp-2mqtt ansehe, handelt es sich um ein relativ einfaches Projekt, das sich kaum weiterentwickelt.

Das Repository umfasst nur 90 Commits, und ein großer Teil davon betrifft Dokumentations- oder CI-Updates. Am Ende gibt es nicht viel Geschäftslogik.

ocpp-2w-proxy ist noch schlimmer, nur 19 Commits, das letzte Update ist fünf Monate her.

Das ist genau die Art von Projekt, das eine KI heute in etwa 30 Minuten neu schreiben kann. Dadurch vermeidet man eine Abhängigkeit von einem Drittprojekt mit geringer Entwicklung, behält aber die Kontrolle über den Code und die Möglichkeit, ihn schnell weiterzuentwickeln oder Fehler zu beheben.

Im Gegensatz dazu ist Zigbee2MQTT eine ganz andere Liga: über 6.400 Commits, Hunderte von Mitwirkenden und eine sehr aktive Entwicklung. Hier gibt es echte Expertise und eine riesige Kompatibilitätsbasis mit Zigbee-Geräten. In diesem Fall ist es viel sinnvoller, auf ihre Arbeit aufzubauen, anstatt alles neu zu implementieren.

Ich habe diese Möglichkeit nicht ausgeschlossen. Ich habe darüber in Form eines Forks nachgedacht, aber man kann sich das auch als „from scratch“ vorstellen.
Ich teste die HA-Lösung, um zu sehen, ob das Problem, das ich identifiziere, spezifisch für mein Gerät oder die Bibliothek ist, und dann sehen wir uns das an :+1: :+1: :+1:

Das System nimmt Gestalt an

Aber ich muss die Funktionsweise und die Konfigurationsverwaltung überarbeiten.
Darüber arbeite ich am Wochenende weiter :wink:

Du bist also in den zusätzlichen Container-Modus gegangen? Ehrlich gesagt ist das meiner Meinung nach total übertrieben, du hättest das auch nativ machen können, schade um die Abhängigkeit :slight_smile:

Ich hätte auch nicht gedacht, dass ich das brauche. Aber entweder übersehe ich etwas in der Dokumentation, oder du bist nicht ganz im Bilde, wie OCPP funktioniert.
Für die OCPP-Integration benötigen wir einen neuen Websocket. Die Ladestationen verbinden sich mit diesem Websocket. Die Idee der Integration besteht darin, als Man-in-the-Middle zu agieren, um zu sehen, was passiert. Andernfalls: totale Unklarheit.

Aus der Dokumentation lese ich drei Dinge:

  • die Manifest-Felder: die nichts über die Fähigkeit zur Portfreigabe sagen
  • das Sicherheitsmodell, das erklärt, dass der Docker in einem isolierten Netzwerk lebt
  • die Companion-Container: die unter anderem dazu da sind, Protokollbrücken zu schaffen… für mich ist das genau dieser Fall

Also entweder übersehe ich eine Information, der Hauptcontainer kann perfekt Ports öffnen und diese im Netzwerk verfügbar machen, und in diesem Fall stimme ich dir zu, sag mir, wie man das macht, und ich ändere es ohne Probleme. Oder es ist nicht möglich, und dann ist es nicht übertrieben :wink:

Du hast recht, ich habe einen Fehler gemacht :smiley:

Ich habe die Spezifikation noch einmal überprüft: Der Hauptcontainer einer externen Integration hat absichtlich keine veröffentlichten Ports, sein einziger Eingangskanal ist die ausgehende WebSocket-Verbindung zu Gladys. Veröffentlichte Ports existieren nur auf den Subcontainern, die in containers[] deklariert sind. Für OCPP, wo es der Ladepunkt ist, der sich als WS-Client verbindet, ist der Begleitcontainer also heute die einzige Option. Überhaupt nicht overkill also :smiley:

Danach musst du nicht unbedingt ein Drittanbieter-Image im Subcontainer verwenden, containers[].docker_image akzeptiert auch deins. Du kannst also einen Subcontainer deklarieren, der deinen eigenen OCPP-Server ausführt, falls du externe Abhängigkeiten begrenzen möchtest!

Genau das habe ich umgesetzt: GitHub - sescandell/gladys-ocpp-integration: Gladys OCPP EV Charger External integration. · GitHub

Perfekt! :raising_hands:

Falls du irgendwelche Grenzen im aktuellen System bemerkst, zögere nicht, alles kann sich weiterentwickeln :slight_smile:

Hallo @pierre-gilles, ich habe eine Frage/Anmerkung,

Ich bin « eingeschränkt » in der Fähigkeit, die Funktionalität über das SDK zu integrieren. Und die Benutzererfahrung könnte möglicherweise nicht vollständig zufriedenstellend sein.

Mein Problem liegt im Bereich « Entdeckung » / « Konfiguration » / « Aktionen ».

Kleine Erklärung zur Funktionsweise von OCPP: Die Benutzer müssen tatsächlich die URL ändern, an die ihr Ladepunkt sich verbindet (von ihrer Cloud-nativen Anwendung der Plattform aus). Wenn sie dies tun, erwartet der Ladepunkt natürlich eine Antwort vom Endpunkt, an den er sich verbindet. Das Ziel der angestrebten Integration ist, dass die native App des Benutzers weiterhin nutzbar bleibt. Die Integration positioniert sich als RELAY. Sie überwacht, was passiert, überträgt die nützlichen Informationen an Gladys und leitet die Nachricht an den ursprünglichen Cloud-Server weiter.

Und das ist das Problem. Ich brauche eine Möglichkeit, um von der Integrationsschnittstelle aus zu sagen: « Diese Ladestation muss auf diesen Cloud-Dienst verweisen ». Was ich heute mache, ist, dass die Integration die URL anzeigt, die in der App angegeben werden muss, damit der Ladepunkt auf Gladys abzielt. Sie antwortet mit « fiktiven » Daten, damit der Ladepunkt verbunden bleibt. So « kennt » die Integration die Identität des Ladepunkts.

Die Idee wäre dann, diese verbundene Ladestation konfigurieren zu können (die Cloud-URL von Gladys aus definieren). Aber - es sei denn, ich übersehe die Info in der Dokumentation - habe ich keine Möglichkeit, « die entdeckten Ladestationen anzuzeigen und auf Konfigurationen einzuwirken ».

Heute kann ich nur eine Aktion durchführen, die die ID des Ladepunkts + Cloud-URL anfordert. Aber nicht mit den « identifizierten Ladestationen » verknüpft. Es ist statisch. Es funktioniert… aber es ist nicht ideal. Die ID muss in den Logs des Companion-Containers gesucht werden. Das ist nicht das Einfachste (obwohl ich die Informationen der verfügbaren IDs im Kopf habe). Verstehst du, was ich zu erklären versuche?

Glaubst du, dass wir an diesem Punkt arbeiten können (ich kann mir vorstellen, eine V1 des Plugins herauszubringen - vorbehaltlich des Mergens des dedizierten PRs auf der Core-Seite zu den neuen CATEGORY und TYPES) mit einem Konfigurationsmodus « per Aktionen », aber es gibt definitiv etwas zu tun, würde ich sagen.

Eine Meinung dazu?

Wenn ich nicht klar bin, sag es mir, ich formuliere es mit Diagrammen um :slight_smile:

Danke!

Hallo @Sescandell,

Vielen Dank für dein detailliertes Feedback, genau solche konkreten Fälle helfen uns, den SDK weiterzuentwickeln.

Allerdings denke ich, dass es hier ein Missverständnis darüber gibt, was der SDK bereits ermöglicht, denn dein Fall sollte eigentlich ohne das Lesen der Container-Logs abgedeckt sein:

1. Sobald sich eine Ladestation mit deinem OCPP-Server verbindet, kennst du ihre ID (sie ist in der Verbindungs-URL enthalten). Zu diesem Zeitpunkt kannst du sie über POST /discovered_device veröffentlichen. Sie erscheint dann im Tab „Entdeckung“ deiner Integration, mit ihrem Namen, und der Benutzer muss nur noch auf „Erstellen“ klicken. Das ist dasselbe Muster wie bei internen Integrationen (z. B. Zigbee2MQTT), und dein Fall ist sogar einfacher als ein Netzwerk-Scan, da die Entdeckung eingehend ist: Die Ladestation kommt zu dir.

2. Für die konfigurationsspezifische Ladestation (die URL der Hersteller-Cloud, die weitergeleitet werden soll), kannst du in deinem Manifest eine Aktion mit einem Select-Feld deklarieren, das « source »: « devices » hat. Das Formular wird dann automatisch mit den Geräten deiner Integration gefüllt (Label = Name der Ladestation), und du erhältst die gewählte external_id wie jeden anderen Feldwert. Der Benutzer wählt seine Ladestation aus einer Liste aus, er kopiert nie eine Kennung.

3. Und wenn du eine bereits erstellte Ladestation mit aktualisierten Parametern (weitergeleitete URL, erfasste Protokollversion usw.) neu veröffentlichst, werden diese in der Datenbank leise aktualisiert, ohne den Namen oder die Funktionen zu ändern.

Der vollständige V1-Prozess ist also: Die Ladestation verbindet sich mit deinem Relay, du veröffentlichst sie zur Entdeckung, der Benutzer erstellt sie über die UI und konfiguriert dann die Cloud-URL über deine Aktion mit dem Select. Keine Logs werden konsultiert.

Ein kleiner Hinweis aufgrund deiner Architektur: Wenn dein OCPP-Server im Untercontainer läuft, ist es der Hauptcontainer der Integration, der den Token zum Aufrufen der Host-API besitzt. Dein Untercontainer muss ihm also die Verbindungsinformation (über euer privates Netzwerk) weiterleiten, damit er die Entdeckung veröffentlichen kann.

Wo du Recht hast, ist, dass es heute eine persistente und pro Gerät sichtbare Konfiguration fehlt: Eine Aktion ist write-only, der Benutzer sieht nicht, welche URL für jede Ladestation konfiguriert ist. Das ist ein Bedarf, den wir bereits für die Phase 2 (Aktionen auf Geräteebene, direkt auf deren Karte) identifiziert hatten, und dein Feedback bestätigt, dass der Bedarf real ist. Aber ich bevorzuge, dass wir daran arbeiten, sobald deine V1 mit den aktuellen Bausteinen veröffentlicht ist, um dies mit Abstand und anderen Use Cases als deinem zu gestalten.

Wenn einer der drei oben genannten Punkte in deinem Fall nicht funktioniert, lass es mich wissen, das würde bedeuten, dass es entweder einen Bug oder eine Lücke in der SDK-Dokumentation gibt.

Ich bin an der Vorstellung von Quellgeräten vorbeigegangen. Das wird die Erfahrung etwas verbessern, aber ich denke, es bleibt noch etwas zu verbessern. Ich mache das und sage dir, wie es läuft. Der Rest entspricht bereits dem, was bereits umgesetzt ist.

Danke, ich halte dich auf dem Laufenden.