diff --git a/docs/module/Ladestation-Stand-Alone/README.md b/docs/module/Ladestation-Stand-Alone/README.md index cbfd032..718e441 100644 --- a/docs/module/Ladestation-Stand-Alone/README.md +++ b/docs/module/Ladestation-Stand-Alone/README.md @@ -1,63 +1,296 @@ # Ladestation Stand-Alone -> Status: Implementiert. Eigenstaendiges Verbrauchermodul mit direkter -> Geraeteanbindung; keine Beziehung zur Ladestation Gateway. +> Status: implementiert fuer IP-Symcon 8 und den Enelix-2-Vertrag `4.0`. + +Das Modul bindet eine einzelne Ladestation direkt an Enelix EMS an. Es liest +den Fahrzeug- und Ladezustand ueber die Geraete-API, ermittelt die Phasenzahl +wie Enelix 1 und setzt den vom Manager gewaehlten Ladestrom. Es benoetigt keine +Gateway-Instanz und hat keine technische Beziehung zum separaten Modul +**Ladestation Gateway**. + +## Funktionsumfang + +- direkte Statusabfrage und Steuerung der unterstuetzten Ladestationen, +- Fahrzeug-, Lade- und Phasenerkennung nach der Enelix-1-Logik, +- Leistungsangebote fuer PV- und Peakbetrieb, +- lokale Freigabe und Umschaltung zwischen Solar- und Normalbetrieb, +- Kommunikation mit dem Enelix Manager ueber den Nachrichtenvertrag `4.0`, +- optional sichtbare Diagnosevariablen und schaltbares Debug-Logging, +- automatisierte Tests mit Fake-HTTP-Transport ohne reale Ladestation. ## Unterstuetzte Geraete -| Geraetetyp | Status | Steuerung | +| Geraetetyp | Statusabfrage | Steuerung | Erforderliche Konfiguration | +| --- | --- | --- | --- | +| go-e Charger, alte API | `GET /mqtt?payload=` | `alw` und `amp` | IP-Adresse oder Hostname | +| go-e Charger Gemini / Gemini flex | `GET /api/status` | `frc` und `amp` | IP-Adresse oder Hostname | +| smart-me Pico | Pico-Charging-API | Load-Management-Current-API | Geraete-ID, Seriennummer, Benutzername und Passwort | + +Bei go-e wird die lokale HTTP-API verwendet. Die Geraeteadresse wird ohne +`http://`, Pfad oder Parameter eingetragen. Die Pico-Anbindung verwendet HTTPS +und HTTP Basic Auth gegen `api.smart-me.com`. Zugangsdaten werden weder als +Variable noch im Debug-Protokoll oder im Diagnosefeld +`LetzterGeraetebefehl` ausgegeben. + +## Fahrzeug- und Phasenerkennung + +Die Auswertung folgt bewusst dem Verhalten der bisherigen Enelix-1-Ladestation: + +1. Bei go-e gilt das Fahrzeug als verbunden, wenn `car != 1` ist. Bei Pico + wird entsprechend `State != 1` ausgewertet. +2. Die gemessene Leistung wird bei der alten go-e-API mit Faktor 10, bei + Gemini direkt in Watt und bei Pico von kW in Watt umgerechnet. +3. Bei einer Leistung ueber 7500 W wird dreiphasiges Laden erkannt. Darunter + wird bei verbundenem Fahrzeug einphasiges Laden angenommen. +4. Der Ladestrom wird aus der Leistung mit `230 V` einphasig beziehungsweise + `1.71 * 400 V` dreiphasig berechnet. +5. War das Fahrzeug bereits im vorherigen Zyklus verbunden und liegt der + ermittelte Maximalstrom aus Ladestrom plus `2.5 A` unter `6 A`, wird + `FahrzeugGeladen=true` gesetzt. + +Der normalisierte `Fahrzeugstatus` verwendet folgende Werte: + +| Wert | Bedeutung | +| ---: | --- | +| `0` | unbekannt oder noch nicht ermittelt | +| `1` | kein Fahrzeug verbunden | +| `2` | Fahrzeug verbunden und bereit | +| `3` | Fahrzeug laedt | +| `4` | Fahrzeug geladen | + +## Leistungsregelung + +Ein Leistungsangebot groesser als `0 W` wird nur erzeugt, wenn das Modul +aktiviert, die Ladefreigabe gesetzt, ein Fahrzeug verbunden und das Fahrzeug +noch nicht als geladen erkannt ist. Andernfalls meldet das Modul `[0]` und +stoppt die Ladestation. + +| Betriebsart | Solarladen | Leistungsangebot | | --- | --- | --- | -| go-e Charger, alte API | `GET /mqtt?payload=` | `alw` und `amp` | -| go-e Charger Gemini / Gemini flex | `GET /api/status` | `frc` und `amp` | -| smart-me Pico | Pico-Charging-API | Load-Management-Current-API mit Basic Auth | +| PV | ein | `0 W` und alle Ladestufen von 6 A bis zum konfigurierten Maximum | +| PV | aus | ausschliesslich die maximale Ladeleistung | +| Peak | ein | ausschliesslich `[0]`; die Ladestation wird gestoppt | +| Peak | aus | `0 W` und alle Ladestufen von 6 A bis zum konfigurierten Maximum | -Die Routen, Leistungsfaktoren und Erkennung wurden gezielt aus Enelix 1 -uebernommen. Zugangsdaten werden weder als Variable noch im Diagnoseprotokoll -ausgegeben. +Die festen ein- und dreiphasigen Leistungsstufen sowie deren Rundung wurden aus +Enelix 1 uebernommen. Ohne gueltige Manager-Vorgabe faehrt das Modul bei +aktivem Solarladen mit `0 A`; bei ausgeschaltetem Solarladen verwendet es die +maximale angebotene Leistung. -## Verhalten +## Bedienung -- `FahrzeugVerbunden` entspricht bei go-e `car != 1` und bei Pico `State != 1`. -- Die Phasenerkennung verwendet wie Enelix 1 die gemessene Ladeleistung: - ueber 7500 W sind dreiphasig, sonst einphasig. -- Ein bereits verbundenes Fahrzeug gilt bei einem ermittelten Maximalstrom - unter 6 A als geladen. -- PV mit Solarladen bietet `0 W` und alle Ladestufen von 6 A bis zum - konfigurierten Maximum an. -- PV ohne Solarladen bietet ausschliesslich die Maximalleistung an. -- Peak mit Solarladen bietet nur `[0]` an und stoppt die Ladestation. -- Peak ohne Solarladen bietet `[0, ...Ladestufen]` an, damit der Manager die - Ladeleistung wie in Enelix 1 stufenweise reduzieren kann. -- Ohne gueltige Manager-Vorgabe wird bei Solarladen mit 0 A und ohne - Solarladen mit maximaler Leistung gefahren. +| Ident | Wirkung | +| --- | --- | +| `Aktiv` | Gemeinsame lokale EMS-Freigabe. `false` setzt das Angebot auf `[0]` und stoppt die Ladestation. | +| `Ladefreigabe` | Lokale Freigabe fuer das Laden. Diese Variable ist nur mit `EinstellungenInVisu=true` sichtbar. | +| `Solarladen` | Schaltet das oben beschriebene PV-/Peak-Verhalten um. Diese Variable ist nur mit `EinstellungenInVisu=true` sichtbar. | + +Die Properties `Ladefreigabe` und `Solarladen` definieren die Startwerte. Eine +Aenderung der jeweiligen Property wird beim Anwenden der Konfiguration in den +lokalen Zustand uebernommen. Eine Bedienung der Variablen verwirft eine noch +gueltige Manager-Vorgabe und berechnet das Leistungsangebot sofort neu. + +## Konfiguration + +### Gemeinsame EMS-Einstellungen + +| Property | Typ | Standard | Beschreibung | +| --- | --- | ---: | --- | +| `PrioritaetPV` | Integer | `0` | Prioritaet des Verbrauchers im PV-Betrieb. | +| `PrioritaetPeak` | Integer | `0` | Prioritaet des Verbrauchers im Peakbetrieb. | +| `Meldeintervall` | Integer | `10 s` | Intervall fuer die periodische Vollmeldung an zugeordnete Manager. | +| `VorgabeTimeout` | Integer | `120 s` | Gueltigkeitsdauer einer Manager-Vorgabe ohne Erneuerung. | +| `EinstellungenInVisu` | Boolean | `false` | Blendet `Ladefreigabe` und `Solarladen` als bedienbare Variablen ein. | +| `LoggingEin` | Boolean | `false` | Aktiviert das laufende Debug-Protokoll des Moduls. | + +### Ladestation und Diagnose + +| Property | Typ | Standard | Beschreibung | +| --- | --- | ---: | --- | +| `Geraetetyp` | Integer | `0` | `1` go-e alt, `2` go-e Gemini, `3` smart-me Pico; `0` ist nicht konfiguriert. | +| `Geraeteadresse` | String | leer | IP-Adresse oder Hostname fuer beide go-e-Varianten. | +| `GeraeteID` | String | leer | Geraete-ID fuer die Pico-Statusabfrage. | +| `Seriennummer` | String | leer | Seriennummer fuer die Pico-Stromvorgabe. | +| `Benutzername` | String | leer | Benutzername fuer die Pico-API. | +| `Passwort` | String | leer | Passwort fuer die Pico-API; im Formular als Passwortfeld dargestellt. | +| `MaximalerLadestrom` | Integer | `16 A` | Obergrenze der angebotenen Ladestufen; zulaessig sind 6 bis 32 A. | +| `Abfrageintervall` | Integer | `5 s` | Intervall der Geraetestatusabfrage. | +| `Ladefreigabe` | Boolean | `false` | Startwert der lokalen Ladefreigabe. | +| `Solarladen` | Boolean | `true` | Startwert der lokalen Solarlogik. | +| `DiagnosevariablenAnzeigen` | Boolean | `false` | Blendet gemeinsame und ladestationsspezifische Diagnosevariablen ein. | + +Die internen Properties `Testmodus` und `Testantwort` gehoeren ausschliesslich +zum automatisierten Symcon-Funktionstest und erscheinen nicht im +Konfigurationsformular. ## Variablen +Immer sichtbar: + | Ident | Typ / Zugriff | Beschreibung | | --- | --- | --- | -| `FahrzeugVerbunden` | Boolean / Anzeige | Geraet meldet ein verbundenes Fahrzeug. | -| `FahrzeugGeladen` | Boolean / Anzeige | Enelix-1-Erkennung unter 6 A. | -| `Fahrzeugstatus` | Integer / Anzeige | `0` unbekannt, `1` getrennt, `2` bereit, `3` laedt, `4` geladen. | -| `Ladestrom` | Float / Anzeige | Aus der gemessenen Leistung ermittelter Strom in A. | -| `Phasenzahl` | Integer / Anzeige | `0` unbekannt, `1` einphasig, `3` dreiphasig. | -| `Ladefreigabe` | Boolean / bedienbar | Nur bei `EinstellungenInVisu`; lokale Ladeerlaubnis. | -| `Solarladen` | Boolean / bedienbar | Nur bei `EinstellungenInVisu`; variable Ladestufen ein/aus. | +| `Aktiv` | Boolean / bedienbar | Lokale EMS-Freigabe; der Initialwert ist `false`. | +| `FahrzeugVerbunden` | Boolean / Anzeige | Zeigt, ob die API ein verbundenes Fahrzeug meldet. | +| `FahrzeugGeladen` | Boolean / Anzeige | Ergebnis der kompatiblen Enelix-1-Voll-Erkennung. | +| `Fahrzeugstatus` | Integer / Anzeige | Normalisierter Status von `0` bis `4`. | +| `Ladestrom` | Float / Anzeige | Aus der gemessenen Leistung ermittelter Ladestrom in A. | +| `Phasenzahl` | Integer / Anzeige | `0` unbekannt, `1` einphasig oder `3` dreiphasig. | -## Properties +Nur mit `EinstellungenInVisu=true` sichtbar und bedienbar: -Neben den gemeinsamen Verbraucher-Properties werden Geraetetyp, Adresse, -Pico-ID, Seriennummer, Zugangsdaten, maximaler Ladestrom, Abfrageintervall -sowie die Startwerte fuer Ladefreigabe und Solarladen konfiguriert. +- `Ladefreigabe` +- `Solarladen` -Die gemeinsamen Verbraucher- und Diagnosevariablen entsprechen der -EMS-Schnittstelle Version 4.0. `LoggingEin` steuert ausschliesslich das -laufende Debug-Protokoll. +Nur mit `DiagnosevariablenAnzeigen=true` sichtbar: + +| Ident | Beschreibung | +| --- | --- | +| `Istleistung` | Von der Ladestation gemessene Leistung in W. | +| `Leistungsquelle` | Immer `2` fuer eine gemessene Leistung. | +| `Sollleistung` | Letzte angenommene Manager-Vorgabe in W. | +| `SollwertGueltig` | Zeigt, ob die Vorgabe noch gueltig und im aktuellen Angebot enthalten ist. | +| `Verfuegbar` | Zeigt, ob die Ladestation grundsaetzlich Leistung aufnehmen kann. | +| `AenderungMoeglich` | Zeigt, ob das aktuelle Angebot mehr als eine Leistungsstufe enthaelt. | +| `Stoerung` | Sammelstatus fuer Konfigurations- und Kommunikationsfehler. | +| `Stoertext` | Letzte verstaendliche Fehlerbeschreibung. | +| `LetzterGeraetebefehl` | Letzte HTTP-Methode und URL ohne Zugangsdaten. | +| `LeistungsangebotDiagnose` | Aktuelles Leistungsangebot als JSON-Liste in W. | + +Die Regellogik speichert ihren Zustand unabhaengig von der Sichtbarkeit der +Diagnosevariablen. Das Ein- oder Ausblenden veraendert daher nicht das +Regelverhalten. + +## Managerkommunikation + +Das Modul implementiert +`VerbraucherSchnittstelle::ManagerdatenEmpfangen()` und verwendet +[ausschliesslich den Nachrichtenvertrag `4.0`](../../Schnittstelle.md). Eine +separate Manager-ID wird nicht konfiguriert. Das Modul akzeptiert Vorgaben nur +von einem Manager, in dessen manueller oder automatischer +Verbraucherzuordnung die Ladestation aktiv eingetragen ist. + +An den Manager werden neben den gemeinsamen Feldern diese Zustaende gemeldet: + +- `Sollleistung_W` +- `FahrzeugVerbunden` +- `FahrzeugGeladen` +- `Fahrzeugstatus` +- `Phasenzahl` +- `Ladestrom_A` +- `Ladefreigabe` +- `Solarladen` +- `Ladefehler` mit Stoertext + +Eine Sollleistung wird nur angenommen, wenn sie im zuletzt berechneten +Leistungsangebot enthalten ist. Nach `VorgabeTimeout` ohne Erneuerung wird sie +ungueltig. Statusaenderungen werden kurz verzoegert und zusaetzlich alle +`Meldeintervall` Sekunden an alle zugeordneten Manager gemeldet. + +## Instanzstatus und Fehlerbehandlung + +| Status | Bedeutung | +| ---: | --- | +| `102` | Konfiguration und letzte Geraetekommunikation sind gueltig. | +| `201` | Konfiguration ungueltig, beispielsweise fehlende Adresse oder Pico-Zugangsdaten. | +| `202` | Geraetekommunikation oder Antwortauswertung fehlgeschlagen. | + +Bei einem Fehler meldet das Modul `Verfuegbar=false`, +`AenderungMoeglich=false` und setzt `Stoerung` sowie `Stoertext`. HTTP-Anfragen +verwenden 5 Sekunden Verbindungs- und 10 Sekunden Gesamt-Timeout. Antworten ab +HTTP-Status 400 sowie unvollstaendige oder ungueltige JSON-Antworten gelten als +Kommunikationsfehler. + +## Installation und Inbetriebnahme + +1. Im IP-Symcon Module Control den Testing-Branch `develop` der Bibliothek + `https://git.belevo.ch/ENELIX/Enelix-EMS.git` installieren oder + aktualisieren. +2. Unter **Instanz hinzufuegen** nach **Ladestation Stand-Alone** suchen und + eine Instanz anlegen. +3. Den Geraetetyp auswaehlen und die dazugehoerigen Verbindungsdaten eintragen: + bei go-e nur IP-Adresse oder Hostname, bei Pico Geraete-ID, Seriennummer, + Benutzername und Passwort. +4. Den maximal zulaessigen Ladestrom der Installation zwischen 6 und 32 A + einstellen. Diese Grenze ersetzt keine elektrische Absicherung. +5. `Abfrageintervall`, `Meldeintervall`, `VorgabeTimeout` sowie die beiden + Prioritaeten festlegen. +6. Die gewuenschten Startwerte fuer `Ladefreigabe` und `Solarladen` setzen. +7. Fuer die Erstinbetriebnahme `EinstellungenInVisu`, + `DiagnosevariablenAnzeigen` und bei Bedarf `LoggingEin` aktivieren. +8. Die Instanz im Manager manuell aktiv zuordnen oder bei automatischer Suche + in der gefundenen Liste aktivieren. +9. Zuerst ohne Fahrzeug kontrollieren, ob die Statusabfrage fehlerfrei ist. + Danach unter Aufsicht ein Fahrzeug verbinden und `Aktiv` einschalten. + +Fuer go-e muss IP-Symcon das Geraet im lokalen Netz per HTTP erreichen koennen. +Fuer Pico ist ausgehender HTTPS-Zugriff auf `api.smart-me.com` erforderlich. +Passwoerter gehoeren ausschliesslich in das dafuer vorgesehene Passwortfeld und +niemals in Repository-Dateien, Skripte oder Screenshots. + +## Abnahmecheckliste + +- Die Instanz erreicht Status `102`, und `Stoerung` bleibt `false`. +- Ohne Fahrzeug sind `FahrzeugVerbunden=false`, `Phasenzahl=0` und das + Leistungsangebot `[0]`. +- Nach dem Anstecken wird das Fahrzeug erkannt und die gemessene Leistung + plausibel in `Istleistung` und `Ladestrom` abgebildet. +- Bei einer Ladeleistung bis 7500 W wird eine Phase, darueber werden drei + Phasen angezeigt. +- `Aktiv=false` oder `Ladefreigabe=false` stoppt die Ladestation. +- PV mit `Solarladen=true` bietet `0 W` und die Ladestufen an. +- PV mit `Solarladen=false` bietet nur die maximale Leistung an. +- Peak mit `Solarladen=true` stoppt die Ladestation und bietet nur `[0]` an. +- Peak mit `Solarladen=false` bietet `0 W` und die Ladestufen an. +- Eine Manager-Vorgabe ausserhalb des gemeldeten Angebots wird abgewiesen. +- Nach Ablauf des Vorgabe-Timeouts gilt wieder das lokale Ersatzverhalten. +- Im Debug-Protokoll und in `LetzterGeraetebefehl` erscheinen keine + Zugangsdaten. + +## Fehlersuche + +- Status `201`: Geraetetyp und Pflichtfelder kontrollieren. Bei go-e darf die + Adresse kein Protokoll, keinen Pfad und keine Parameter enthalten. Bei Pico + muessen alle vier Zugangsfelder befuellt sein. +- Status `202`: Erreichbarkeit, DNS, lokale Firewall und API-Antwort pruefen. + `Stoertext` enthaelt den konkreten Kommunikations- oder JSON-Fehler. +- Fahrzeug wird nicht erkannt: Rohstatus der Geraete-API kontrollieren. Der + Adapter erwartet bei go-e `car` und `nrg[11]`, bei Pico `State` und + `ActiveChargingPower`. +- Falsche Phasenzahl bei sehr kleiner oder stehender Ladung: Die kompatible + Enelix-1-Erkennung basiert auf der momentanen Leistung. Fuer eine sichere + Dreiphasenerkennung muss waehrend der Erkennung mehr als 7500 W anliegen. +- Manager-Vorgabe wird abgewiesen: aktive Zuordnung im Manager sowie + `LeistungsangebotDiagnose` und die Betriebsart kontrollieren. ## Tests -Die Adaptertests verwenden einen injizierten Fake-HTTP-Transport. Dadurch -werden fuer alle drei Geraetevarianten Statusantworten, URL, HTTP-Methode, -Authentisierung und Steueraufrufe geprueft, ohne ein reales Geraet anzusprechen. -Der Symcon-Funktionstest nutzt den internen, nicht im Konfigurationsformular -sichtbaren `Testmodus` und prueft zusaetzlich Fahrzeug-/Phasenerkennung, -die vier PV-/Peak-Angebote sowie die Umschaltung ueber den `Solarladen`-Button. +Die Unit- und Adaptertests verwenden einen injizierten Fake-HTTP-Transport. +Damit werden fuer go-e alt, go-e Gemini und smart-me Pico Statusantworten, +URL, HTTP-Methode, Authentisierung und Steueraufrufe ohne reale Hardware +geprueft. + +Der Symcon-Funktionstest verwendet den internen `Testmodus` mit simulierten +API-Antworten. Er prueft alle drei Geraetevarianten, Fahrzeug- und +Phasenerkennung, die Leistungsangebote in PV und Peak sowie die Umschaltung +ueber den `Solarladen`-Button. + +PHP-Syntax, Struktur- und Unit-Tests des gesamten Repositorys: + +```bash +composer check +``` + +Funktionstest nur fuer die Ladestation gegen IP-Symcon 8: + +```bash +tests/Symcon/bin/run-symcon-tests.sh single LadestationStandAlone +``` + +Vollstaendiger Symcon-Modultestlauf: + +```bash +tests/Symcon/bin/run-symcon-tests.sh all +``` + +Aufbau, Testvertrag und Ergebnisdateien sind unter +[`docs/testing/README.md`](../../testing/README.md) beschrieben.