33 KiB
Belevo Energiemanagement fuer IP-Symcon
Stand: 2026-05-10
Diese Dokumentation ist als Arbeitsgrundlage fuer ChatGPT/Codex und fuer zukuenftige Software-Erweiterungen gedacht. Sie beschreibt die Funktion, Architektur, Modul-Schnittstellen und die wichtigsten Regeln, um neue Module sauber an den Energiemanager anzubinden.
1. Kurzueberblick
Das Repository ist eine IP-Symcon Modulbibliothek fuer ein Energiemanagementsystem der Belevo AG. Das System verteilt elektrische Leistung dynamisch auf steuerbare Verbraucher wie Ladestationen, Boiler, Pufferspeicher, Batterie, Waermepumpe und externe Schaltgruppen.
Die zentrale Idee:
- Der
Managerliest den aktuellen Netzbezug. - Der
Managerentscheidet zwischen Solarladen und Peak-Shaving. - Jeder Verbraucher meldet seine aktuell moeglichen Leistungsstufen als
PowerSteps. - Der
Managerverteilt die verfuegbare oder zu reduzierende Leistung nach Prioritaet und Fairness. - Die Verbraucher setzen die zugeteilte Leistung in konkrete Schaltkontakte, API-Aufrufe oder Geraetemodi um.
Das System ist fuer Einzelhaeuser, ZEV/V-ZEV-Anlagen und groessere Lastmanagement-Strukturen ausgelegt. Fuer verteilte Anlagen gibt es neben dem lokalen Manager den HauptManager, der mehrere untergeordnete Manager ueber JSON-Datenpunkte zusammenfassen kann.
2. Repository-Struktur
Jedes IP-Symcon Modul liegt in einem eigenen Ordner und enthaelt typischerweise:
module.php: PHP-Klasse mit der eigentlichen Logik.module.json: IP-Symcon Modul-Metadaten, GUID, Name, Typ, Hersteller, Prefix.form.json: Konfigurationsformular fuer IP-Symcon.README.md: Modulbeschreibung, aktuell oft noch Template oder veraltet.
Wichtige Dateien auf Root-Ebene:
library.json: Modulbibliothek, aktuell Version2.001, IP-Symcon-Kompatibilitaet8.0.README.md: vorhandene Systembeschreibung des Energiemanagers.DOKUMENTATION_CHATGPT.md: diese technische Gesamtuebersicht.
3. Modulgruppen
| Modul | Rolle | Manager-Anbindung |
|---|---|---|
Manager |
Lokaler Energiemanager, verteilt Leistung an Verbraucher | Zentrale Instanz |
HauptManager |
Aggregiert mehrere Manager/Unteranlagen ueber JSON | Uebergeordnete Instanz |
Ladestation_v2 |
Moderne Ladestationsanbindung mit Fahrzeugerkennung, Mindeststrom, 1p/3p, Easee/ECarUp/Smart-Me/Go-E | Verbraucher |
Ladestation_Universal |
Aeltere/einfachere Ladestation | Verbraucher |
Batterie |
Batterie mit Lade-/Entladeleistungssteuerung fuer Goodwe, Solaredge, Sig Energy | Verbraucher, bidirektional |
Boiler_2_Stufig_Mit_Fueler |
Boiler mit Teil- und Volllastkontakt, Temperatur- und Legionellenlogik | Verbraucher |
Boiler_x_Stufig |
Boiler mit frei konfigurierbaren Leistungsstufen | Verbraucher |
Ansteuerung_Askoheat |
Stufenlose/mehrstufige Askoheat-Ansteuerung ueber externe Leistungsvariable | Verbraucher |
Pufferspeicher |
Puffer mit Teil-/Volllastkontakt und Aussentemperatur-Funktion | Verbraucher |
Puffer_Speicher |
Puffer mit frei konfigurierbaren Leistungsstufen | Verbraucher |
Verbraucher_1_Stufig |
Einfacher Ein/Aus-Verbraucher mit Mindestlaufzeit/Nachtlogik | Verbraucher |
Verbraucher_Sperrbar |
Verbraucher, der im Peak-Fall gesperrt werden kann | Verbraucher |
Verbraucher_extern |
Buendelt externe Schaltverbraucher zu Leistungskombinationen | Verbraucher/Adapter |
WP_Steuerung |
Waermepumpe mit Sperr-/Erhoehungskontakten, Wetter-/Sonnenlogik | Verbraucher |
CC100_HW |
Hardwarezugriff auf digitale Ein-/Ausgaenge und PT-Fuehler | Hilfs-/Hardwaremodul |
Shelly_Parser_MQTT |
MQTT-Parser fuer Shelly-Geraete, legt Variablen dynamisch an | Hilfs-/Integrationsmodul |
Belevo_Server_Kommunikation |
Wetterdaten und Influx/Server-Kommunikation | Monitoring/Kommunikation |
Energy_Pie |
Visualisierung von Produktion, Netz, Einspeisung, Hausverbrauch | Visualisierung |
Belevo_Bezahl_Modul |
Experimentelles Google-Pay/Stripe HTML-Modul | Nebenmodul, nicht produktionsreif |
4. Grundarchitektur
4.1 Schichten
Die Software hat logisch vier Schichten:
-
Datenquellen:
- Netzbezug, Batterieladezustand, aktuelle Ladeleistung, Temperaturen, Schaltzustand, Wetterdaten.
- Meist als IP-Symcon Variablen konfiguriert.
-
Energiemanagement:
Managerfuer lokale Anlagen.HauptManagerfuer uebergeordnete Verteilung ueber mehrere Manager.
-
Verbraucheradapter:
- Module, die den gemeinsamen Verbraucher-Vertrag umsetzen.
- Beispiele:
Ladestation_v2,Batterie,Boiler_x_Stufig.
-
Aktoren und externe Systeme:
- Schaltkontakte, Wallbox HTTP APIs, Cloud APIs, Wechselrichtervariablen, Shelly MQTT, CC100 Linux-Dateisystem.
4.2 Normaler lokaler Ablauf
Ein typischer Zyklus laeuft so:
Managerwird ueberTimer_DistributeEnergyaufgerufen.ManagerliestNetzbezug,Peakleistung,UeberschussleistungundVerbraucher_Liste.- Der Modus wird bestimmt:
- Solarladen, wenn der Netzbezug unterhalb des Umschaltbereichs liegt.
- Peak-Shaving, wenn der Netzbezug ueber dem Umschaltbereich liegt.
- Fuer jeden Verbraucher werden die EMS-Variablen gelesen:
PowerBezogene_EnergiePV_PrioSperre_PrioIdlePowerStepsLeistung_Delta
- Der Manager fordert per
IPS_RequestAction($verbraucher, "GetCurrentData", $Is_Peak_Shaving)neue Daten an. - Wenn ein Verbraucher nicht
Idleist oder sich der Modus geaendert hat, bleiben alle aktuellen Leistungen im aktuellen Zyklus stehen. - Sonst sortiert der Manager Verbraucher nach Prioritaet und verteilt die Leistung.
- Die Zuteilung wird ueber
IPS_RequestAction($verbraucher, "SetAktuelle_Leistung", $leistung)an die Verbraucher gegeben. - Die Verbraucher setzen diese Vorgabe in ihrem eigenen
Do_UserCalc-Timer um.
Wichtig: Viele Verbraucher setzen die Leistung nicht direkt im RequestAction("SetAktuelle_Leistung"), sondern speichern den Wert zuerst in der Variable Power. Die reale Umsetzung erfolgt im naechsten Do_UserCalc.
4.3 Modusentscheidung
Der lokale Manager kennt zwei Betriebsarten:
Is_Peak_Shaving = false: Solarladen / Nutzung verfuegbarer Leistung.Is_Peak_Shaving = true: Peak-Shaving / Reduktion oder Begrenzung der Leistung.
Wenn UmschaltpunktStatisch = false, nutzt der Manager die Mitte zwischen Peakleistung und Ueberschussleistung:
Schwellwert = (Peakleistung + Ueberschussleistung) / 2
Netzbezug < Schwellwert -> Solarladen
Netzbezug >= Schwellwert -> Peak-Shaving
Wenn UmschaltpunktStatisch = true, werden Umschalt_Solarladen und Umschalt_Peakshaving als Hysterese verwendet. Zwischen den beiden Werten bleibt der bisherige Modus erhalten.
4.4 Leistungsverteilung
Der Manager arbeitet mit diskreten Leistungsstufen. Jeder Verbraucher liefert ein JSON-Array PowerSteps, zum Beispiel:
[0, 1500, 3000, 6000]
oder bei bidirektionalen Verbrauchern:
[-3000, -1000, 0, 1000, 3000]
Die Verteilung laeuft prioritaetsweise:
- Prioritaetsschluessel waehlen:
- Solarladen:
PV_Prio - Peak-Shaving:
Sperre_Prio
- Solarladen:
- Verbraucher sortieren:
- zuerst nach Prioritaet, niedriger Wert bedeutet hoeher priorisiert.
- bei gleicher Prioritaet nach
Bezogene_Energie / 2000, damit weniger versorgte Verbraucher bevorzugt werden.
- Verbraucher gleicher Prioritaet werden gruppiert.
- Innerhalb einer Gruppe werden alle moeglichen Schritte sortiert.
- Der Manager nimmt nur Schritte, die in die verbleibende Leistung passen.
- Verbraucher, die nicht
0annehmen koennen, werden gesondert behandelt.
Leistung_Delta korrigiert Soll-/Ist-Abweichungen. Das ist besonders wichtig bei Ladestationen, weil die effektive Ladeleistung von der Vorgabe abweichen kann.
5. Der gemeinsame Verbraucher-Vertrag
Jedes neue Modul, das vom Manager gesteuert werden soll, muss mindestens die folgenden Variablen und Actions anbieten.
5.1 Pflichtvariablen
| Ident | Typ | Bedeutung |
|---|---|---|
Sperre_Prio |
Integer | Prioritaet im Peak-Shaving. Niedriger = wichtiger. |
PV_Prio |
Integer | Prioritaet im Solarladen. Niedriger = wichtiger. |
Idle |
Boolean | true, wenn das Modul fuer eine neue Leistungszuteilung bereit ist. |
Aktuelle_Leistung |
Integer/Float | Aktuell umgesetzte oder zuletzt gesetzte Leistung in W. |
Bezogene_Energie |
Float | Aufsummierte Energie fuer Fairness. Aktuell in W * h gerechnet, faktisch Wh. |
PowerSteps |
String | JSON-Array moeglicher Leistungsstufen in W. |
Power |
Integer/Float | Vom Manager gewuenschte Leistung, oft als Zwischenspeicher. |
Is_Peak_Shaving |
Boolean | Letzter vom Manager uebergebener Modus. |
Leistung_Delta |
Integer/Float | Abweichung zwischen Soll und Ist, damit der Manager die reale Leistung beruecksichtigen kann. |
IdleCounter |
Integer | Hilfszaehler bis Idle wieder true wird. |
5.2 Pflicht-Actions
| Action | Parameter | Aufgabe |
|---|---|---|
GetCurrentData |
Boolean Peak |
Aktuellen Modus speichern und PowerSteps neu berechnen. |
SetAktuelle_Leistung |
Integer/Float power |
Neue Leistungsvorgabe entgegennehmen oder direkt umsetzen. |
Do_UserCalc |
leer | Interner zyklischer Modulschritt, setzt Power um und aktualisiert PowerSteps. |
5.3 Bedeutung der Vorzeichen
Im bestehenden Code gilt implizit:
- Positive Leistung: Verbraucher bezieht oder laedt Energie.
0: Verbraucher aus oder neutral.- Negative Leistung: Einspeisen, Entladen oder Gegenrichtung, aktuell vor allem fuer
Batterierelevant.
Neue Module sollten diese Vorzeichenregel konsequent einhalten. Wenn ein Geraet physikalisch anders arbeitet, sollte der Adapter intern umrechnen, aber gegenueber dem Manager diese Semantik behalten.
5.4 Idle-Regel
Idle = false bedeutet: Das Modul hat gerade eine Aenderung bekommen oder wartet auf Mindestlaufzeiten, Hardware-Reaktion oder Stabilisierung. Der Manager soll in dieser Zeit keine neue Verteilung erzwingen.
Typisches Muster:
- Wenn neue Leistung ungleich alter Leistung:
Idle = falseIdleCounter = IdleCounterMax
- Pro Zyklus:
IdleCounterdekrementieren.- Wenn
IdleCounter == 0, dannIdle = true.
Dieses Muster verhindert schnelles Takten von Relais, Wallboxen und Wechselrichtervorgaben.
6. Manager im Detail
6.1 Manager
Datei: Manager/module.php
Wichtige Properties:
Peakleistung: Sollwert bzw. Obergrenze fuer Peak-Shaving in W.Ueberschussleistung: Sollwert fuer Solarladen in W.Netzbezug: IP-Symcon Variable mit aktuellem Netzbezug.Verbraucher_Liste: Liste der zu steuernden Verbraucher-Instanzen.UmschaltpunktStatisch: aktiviert feste Umschaltpunkte.Umschalt_Solarladen: untere Schwelle bei statischer Hysterese.Umschalt_Peakshaving: obere Schwelle bei statischer Hysterese.HauptmanagerAktiv: aktiviert Kopplung anHauptManager.ManagerID: ID des Untermanagers fuer externe Strukturen.DatenHoch: String-Variable, in die lokale Daten fuer den Hauptmanager geschrieben werden.DatenZuruck: String-Variable, aus der Zuweisungen des Hauptmanagers gelesen werden.Interval: Zykluszeit in Sekunden.
Wichtige Funktionen:
DistributeEnergy(): lokale Verteilung.DistributeEnergy_Extern(): JSON-Austausch mit Hauptmanager.RequestAction("DistributeEnergy"): Einstieg des Timers.
6.2 HauptManager
Datei: HauptManager/module.php
Der HauptManager verbindet mehrere lokale Manager oder Teilanlagen. Er liest pro Unteranlage:
- eine JSON-Variable mit User-/Verbraucherdaten (
User_Up) - eine JSON-Variable fuer Rueckgabe/Zuweisung (
User_Down)
Er aggregiert alle Verbraucher, summiert den Netzbezug, entscheidet global zwischen Solarladen und Peak-Shaving und schreibt pro Untermanager ein JSON mit finalen Set_Leistung-Werten zurueck.
JSON-Erwartung vom Untermanager:
{
"User": [
{
"InstanceID": 12345,
"Aktuelle_Leistung": 0,
"Bezogene_Energie": 0,
"PV_Prio": 1,
"Sperre_Prio": 1,
"Idle": true,
"PowerSteps": [0, 1500, 3000],
"Leistung_Delta": 0
}
],
"Netzbezug": 0,
"Timestamp": 1710000000
}
Rueckgabe an Untermanager:
{
"Timestamp": 1710000000,
"Is_Peak_Shaving": false,
"User": [
{
"InstanceID": 12345,
"Set_Leistung": 1500
}
]
}
Wenn Daten aelter als 30 Sekunden sind, setzt der Hauptmanager fuer diese Unteranlage eine sichere Rueckgabe mit leerer User-Liste.
7. Verbraucher-Module
7.1 Ladestationen
Ladestation_v2
Das wichtigste Ladestationsmodul. Es kann fachlich bereits viele Elemente eines spaeteren OCPP-orientierten Moduls abbilden, aber aktuell noch mit herstellerspezifischer Logik direkt im Modul.
Unterstuetzte Typen laut Formular:
- Go-E Wallbox alte Version
- Go-E Gemini/Gemini Flex
- Smart-Me Pico
- Dummy Station
- Easee nur Solarladen
- Easee
Zentrale Eigenschaften:
IP_Adresse,ID,Seriennummer,Username,PasswordToken_Easee,Token_ECarUpMax_Current_absEin_Zeit,Aus_ZeitMindestaldestromals Variable mit Action
Zentrale Betriebsvariablen:
Ladebereit: Freigabe.Solarladen: PV-Lademodus.Car_detected: Fahrzeug erkannt.Car_is_full: Fahrzeug voll.Is_1_ph: erkannter 1-phasiger Betrieb.Max_Current: intern berechneter Maximalstrom.Fahrzeugstatus: herstellerspezifischer Status.Ladeleistung_Effektiv: gemessene Ladeleistung.Pending_Counter: Zaehler fuer ausbleibende Ist-Leistung.IsTimerActive,IsTimerActive_Null_Timer: Mindestlaufzeit-/Null-Timer.Letzer_User: Benutzerbezug fuer Easee/ECarUp-Logik.
Wichtige Funktionen:
Detect_Car(): Fahrzeugerkennung je Stationstyp.Get_Car_Status(): Statusabfrage je Stationstyp.Calc_Max_Current(): dynamische Ermittlung des maximalen Stroms aus effektiver Ladeleistung.Get_Current_From_Power(): Umrechnung W -> A fuer 1p/3p.Get_Array_From_Current(): erzeugt moegliche Leistungsstufen aus Stromstufen.SetAktuelle_Leistung(): setzt EMS-Vorgabe und sendet Stromvorgabe an Station.GetCurrentData(): erzeugtPowerStepsje Modus, Freigabe, Fahrzeugzustand und Timer.sendPowerToStation(): setzt Strom ueber Go-E, Smart-Me, Easee oder Dummy.Refresh_Token(): Easee Login und Token-Pufferung.
Ladestation_Universal
Aelteres, einfacheres Ladestationsmodul. Es arbeitet staerker mit Leistungsgrenzen in W statt mit dynamischer Strom-/Fahrzeuglogik.
Zentrale Unterschiede zu Ladestation_v2:
- Konfiguriert
MinLeistung,MaxLeistung,MinLeistung_1ph,MaxLeistung_1ph. - Hat
LademodusstattIs_1_ph. - Unterstuetzt Go-E, Smart-Me Pico und Dummy.
- Weniger ausgebaute Timer-/Pending-/Tokenlogik.
7.2 Batterie
Datei: Batterie/module.php
Das Batteriemodul ist bidirektional im Sinne des Managers: Es erzeugt positive und negative PowerSteps.
Eigenschaften:
MaxBatterieleistung: Variable fuer maximale Entladeleistung.MaxNachladen: Variable fuer maximale Ladeleistung.Batterieladezustand: SoC-Variable.AufdasNachladen: Zielwert fuer Nachladen.MinimumEntladen: untere SoC-Grenze.Batteriemanagement: 1 = Wechselrichter, 2 = Symcon EMS.Batterietyp: 1 = Goodwe, 2 = Solaredge, 3 = Sig Energy.Netzbezug: Netzbezug fuer Sonderlogik.
Besonderheiten:
GeneratePowerSteps()erzeugt ein Raster aus groben 250-W-Schritten und feinen 50-W-Schritten um die aktuelle Leistung.- Im Wechselrichter-Modus (
Batteriemanagement = 1) meldet das Modul nur[0]. - Im EMS-Modus werden je nach SoC, Hysterese und Modus Lade-/Entladestufen freigegeben.
SetAktuelle_Leistung()schreibt je Batterietyp andere Steuerwerte:- Goodwe:
Goodwe_EntLadeleistung,Laden_Entladen. - Solaredge:
Ladeleistung,Entladeleistung,Laden_Entladen. - Sig Energy: Leistung in kW und andere Moduswerte.
- Goodwe:
7.3 Boiler
Boiler_2_Stufig_Mit_Fueler
Boiler mit zwei Schaltkontakten:
Kontakt_TeillastKontakt_Volllast
Leistungsstufen:
[0, BoilerLeistungTeillast, BoilerLeistungVolllast]
Die PowerSteps werden aus Temperatur, Mindesttemperatur, Maximaltemperatur, Legionellenlogik, Zeitplan und Modus erzeugt.
Boiler_x_Stufig
Boiler mit frei konfigurierbarer Liste LeistungsStufen. Jede Stufe hat:
StufeLeistungSchaltkontakt_Stufe
Das Modul erzeugt daraus ein sortiertes Leistungsarray und schaltet genau die passende Stufe.
Ansteuerung_Askoheat
Askoheat-Modul mit 7-stufiger Leistungslogik:
BoilerLeistungist die Maximalleistung.Calc_Seven_Steps()erzeugt 8 Werte von 0 bis Volllast.SetAktuelle_Leistung()schreibt eine Stufe inVariable_Leistung.- Temperatur kommt aus
Variable_Temperatur_Ist.
7.4 Pufferspeicher
Pufferspeicher
Puffer mit zwei festen Leistungsstufen:
PufferTeilLeistungPufferLeistung
Schaltkontakte:
Heizkontakt_Puffer_TeillastHeizkontakt_Puffer
Die Zieltemperatur wird als lineare Funktion der Aussentemperatur berechnet:
VT = f(AT)
mit den Parametern:
MinVT_TempMaxVT_TempMinAT_TempMaxAT_Temp
Im Peak-Modus meldet der Puffer normalerweise [0]. Im Solarlade-Modus gibt er Stufen frei, wenn die Puffertemperatur unter dem berechneten Zielwert liegt.
Puffer_Speicher
Variante mit frei konfigurierbaren Leistungsstufen analog zu Boiler_x_Stufig.
7.5 Einfache und externe Verbraucher
Verbraucher_1_Stufig
Ein Ein/Aus-Verbraucher mit:
BoilerLeistungSchaltkontakt1Mindesttlaufzeit- Nachtlogik 22:00 bis 07:00
DailyOnTime- Mindestzeit zwischen Zustandswechseln
Im Solarlade-Modus kann er [0, BoilerLeistung] melden. Bei Nacht und nicht erreichter Mindestlaufzeit kann er Leistung erzwingen.
Verbraucher_Sperrbar
Ein Verbraucher, der im Peak-Fall gesperrt werden kann.
Eigenschaften:
Leistung: Variable mit aktueller Verbraucherleistung.Schaltkontakt1: Sperrkontakt.Mindestsperrleistung: Mindestwert, ab dem Sperre relevant wird.MaxSperrZeit: maximale Sperrzeit pro Tag.
Im Peak-Modus meldet das Modul je nach aktueller Leistung [0, Letzte_Sperrleistung]. Im Solarlade-Modus meldet es [0].
Verbraucher_extern
Adapter fuer mehrere externe Verbraucher. Es liest eine Liste von Paaren:
Read_Var: anfragende/aktive Variable.Write_Var: zu schaltende Variable.P_Nenn: Nennleistung.
Aus aktiven Einzelverbrauchern werden alle moeglichen Leistungskombinationen berechnet. Bei einer Manager-Zuweisung wird eine passende Kombination gesucht und die zugehoerigen Write_Var geschaltet.
7.6 Waermepumpe
Datei: WP_Steuerung/module.php
Die Waermepumpe nutzt:
SperrkontaktKontakt_ErhoeungWP_Leistung- Wetter-/Wolkenvariable
- Aussentemperatur
- Referenzzeit fuer Sonnenaufgang
- optionale Warmwasser-Schwellwertlogik
Sie hat interne Zustaende:
Zustand_WP = 1: Normalbetrieb.Zustand_WP = 2: Sperre.Zustand_WP = 3: Erhoehung.
GetCurrentData() meldet normalerweise [0, WP_Leistung], kann aber bei Mindestlaufzeit oder Warmwasser-Schwellwert auf einen festen Zustand begrenzen.
8. Hilfs- und Integrationsmodule
8.1 CC100_HW
Dieses Modul greift direkt auf Linux-Dateipfade eines CC100-Systems zu:
- Digitale Ausgaenge:
/sys/kernel/dout_drv/DOUT_DATA - Digitale Eingaenge:
/sys/devices/platform/soc/44009000.spi/spi_master/spi0/spi0.0/din - PT-Fuehler:
/sys/bus/iio/devices/iio:device2/...
Es stellt bereit:
Bit1bisBit4als digitale Ausgaenge.DI1bisDI8als digitale Eingaenge.PT1,PT2als Temperaturwerte.
Dieses Modul kann als Hardware-Abstraktion fuer Schaltkontakte und Sensorwerte dienen.
8.2 Shelly_Parser_MQTT
Das Shelly-Modul verbindet sich mit der IP-Symcon MQTT-Server-Instanz und subscribed auf #.
Es verarbeitet:
<device>/online<device>/events/rpc
Pro Shelly-Geraet wird ein Kategorieordner angelegt. Darin werden Variablen erzeugt:
OnlineTypOutput xInput xTemperatur
Outputs erhalten ein gemeinsames Action-Script. Beim Schalten wird ein RPC Switch.Set an <device>/rpc publiziert.
Die Parserlogik liegt in Shelly_Parser_MQTT/libs/ShellyParser.php.
8.3 Belevo_Server_Kommunikation
Aufgaben:
- Wetterdaten von
https://brain.belevo.ch/v2wetterabfragen. TemperaturundWolkenwarscheinlichkeitsetzen.- Zusatzvariablen als JSON sammeln.
- Daten an
BaseURL, standardmaessighttps://brain.belevo.ch/storedata, senden.
Die Aufzeichnung wird ueber InfluxJaNein aktiviert. Der Timer laeuft dann alle 5 Minuten.
8.4 Energy_Pie
Visualisierungsmodul fuer Produktions-/Verbrauchsdaten.
Konfigurierte Quellvariablen:
VarProductionVarConsumptionVarFeedInVarGrid
Das Modul liest geloggte Archivwerte, berechnet Differenzen fuer Tag, Woche, Monat, Jahr oder Total und schiebt ein JSON an das HTML-Tile module.html.
8.5 Belevo_Bezahl_Modul
Experimentelles Zahlungsmodul fuer Google Pay/Stripe. Es schreibt HTML in eine konfigurierte HTMLBox.
Aktueller Zustand:
- enthaelt einen Stripe Test-Publishable-Key.
- Backend-Pfad ist Platzhalter (
/path-to-your-backend.php). - keine produktive Zahlungslogik im Modul.
Dieses Modul sollte nicht als produktionsreif betrachtet werden.
9. Neue Module an den Energiemanager anbinden
9.1 Entscheidung: Verbraucher, Manager, Hilfsmodul oder Visualisierung?
Vor der Umsetzung klaeren:
- Muss das Modul vom Energiemanager Leistung zugeteilt bekommen? Dann ist es ein Verbraucher.
- Liefert es nur Daten oder Schaltkontakte? Dann ist es ein Hilfsmodul.
- Soll es mehrere Verbraucher aggregieren? Dann ist es ein Adapter oder Manager-nahes Modul.
- Zeigt es nur Daten an? Dann ist es eine Visualisierung.
Nur Verbraucher muessen den vollen Manager-Vertrag umsetzen.
9.2 Minimaler Verbraucher-Aufbau
Ein neues Verbraucher-Modul sollte in Create() mindestens registrieren:
$this->RegisterVariableInteger("Sperre_Prio", "Sperre_Prio");
$this->RegisterVariableInteger("PV_Prio", "PV_Prio");
$this->RegisterVariableBoolean("Idle", "Idle", "", true);
$this->RegisterVariableInteger("Aktuelle_Leistung", "Aktuelle_Leistung", "", 0);
$this->RegisterVariableFloat("Bezogene_Energie", "Bezogene_Energie", "", 0);
$this->RegisterVariableString("PowerSteps", "PowerSteps");
$this->RegisterVariableInteger("Power", "Power", "", 0);
$this->RegisterVariableBoolean("Is_Peak_Shaving", "Is_Peak_Shaving", "", false);
$this->RegisterVariableInteger("Leistung_Delta", "Leistung_Delta", "", 0);
$this->RegisterPropertyInteger("IdleCounterMax", 2);
$this->RegisterVariableInteger("IdleCounter", "IdleCounter", "", 0);
$this->RegisterPropertyInteger("Interval", 5);
$this->RegisterTimer(
"Timer_Do_UserCalc",
$this->ReadPropertyInteger("Interval") * 1000,
"IPS_RequestAction(" . $this->InstanceID . ', "Do_UserCalc", "");'
);
RequestAction() sollte mindestens diese Faelle enthalten:
public function RequestAction($Ident, $Value)
{
switch ($Ident) {
case "SetAktuelle_Leistung":
$this->SetValue("Power", (int)$Value);
break;
case "GetCurrentData":
$this->SetValue("Is_Peak_Shaving", (bool)$Value);
break;
case "Do_UserCalc":
$this->SetAktuelle_Leistung($this->GetValue("Power"));
$this->GetCurrentData($this->GetValue("Is_Peak_Shaving"));
break;
default:
throw new Exception("Invalid Ident");
}
}
9.3 GetCurrentData() richtig implementieren
GetCurrentData(bool $Peak) muss:
- den aktuellen Betriebsmodus beruecksichtigen.
- interne Sensoren/Statuswerte aktualisieren.
- die erlaubten Leistungsstufen als JSON in
PowerStepsschreiben. Leistung_Deltasetzen, falls Soll und Ist abweichen.- bei Mindestlaufzeiten oder Sperrzeiten nur die aktuelle Leistung melden.
Beispiel:
public function GetCurrentData(bool $Peak)
{
$this->SetValue("Is_Peak_Shaving", $Peak);
if (!$this->GetValue("Idle")) {
$this->SetValue("PowerSteps", json_encode([$this->GetValue("Aktuelle_Leistung")]));
return;
}
if ($Peak) {
$steps = [0, 1000];
} else {
$steps = [0, 1000, 2000, 3000];
}
$this->SetValue("PowerSteps", json_encode($steps));
$this->SetValue("Leistung_Delta", 0);
}
9.4 SetAktuelle_Leistung() richtig implementieren
SetAktuelle_Leistung() muss:
- Aenderung erkennen und
IdleCountersetzen. - Die physische Ansteuerung durchfuehren.
Aktuelle_Leistungsetzen.Bezogene_Energiefortschreiben.IdleCounterweiterverarbeiten.
Beispiel:
public function SetAktuelle_Leistung(int $power)
{
$lastPower = $this->GetValue("Aktuelle_Leistung");
if ($lastPower !== $power) {
$this->SetValue("Idle", false);
$this->SetValue("IdleCounter", $this->ReadPropertyInteger("IdleCounterMax"));
}
// Hier Geraet ansteuern, z.B. Relais, HTTP API oder Wechselrichtervariable.
// SetValue($this->ReadPropertyInteger("Schaltkontakt"), $power > 0);
$this->SetValue("Aktuelle_Leistung", $power);
$this->SetValue(
"Bezogene_Energie",
$this->GetValue("Bezogene_Energie") + ($power * ($this->ReadPropertyInteger("Interval") / 3600))
);
$this->ProcessIdleCounter();
}
9.5 Checkliste fuer neue Verbraucher
module.jsonmit neuer GUID, Name, Vendor und Prefix erstellen.form.jsonmit allen benoetigten Einstellungen erstellen.- Alle Pflichtvariablen des Verbraucher-Vertrags registrieren.
RequestActionmitSetAktuelle_Leistung,GetCurrentData,Do_UserCalcimplementieren.PowerStepsimmer als gueltiges JSON-Array schreiben.PowerStepsimmer numerisch sortierbar halten.0als Stufe anbieten, wenn das Geraet wirklich ausgeschaltet/neutral sein darf.- Negative Stufen nur verwenden, wenn das Modul Einspeisung/Entladung sauber unterstuetzt.
Idlebei Schaltvorgaengen und Mindestlaufzeiten korrekt auffalsesetzen.- Geraetefehler und Kommunikationsfehler abfangen.
- Bei Fehlern sichere
PowerStepssetzen, meist[0]oder aktuelle Leistung. - Im Manager unter
Verbraucher_Listeeintragen.
10. Empfehlungen fuer zukuenftige Verbesserungen
10.1 Gemeinsame Basisklasse oder Trait fuer Verbraucher
Der gleiche EMS-Vertrag ist in fast allen Verbrauchern mehrfach implementiert. Sinnvoll waere eine gemeinsame Datei, zum Beispiel:
libs/EmsConsumerTrait.phplibs/EmsPowerStepHelper.php
Diese koennte bereitstellen:
- Registrierung der Standardvariablen.
- Einheitliche
IdleCounter-Logik. - Energiezaehlung.
- JSON-Validierung fuer
PowerSteps. - Hilfen fuer Sortierung und Minimalstufen.
10.2 Manager-Zyklus robuster machen
Im aktuellen Manager::DistributeEnergy() werden Verbraucherdaten gelesen und danach GetCurrentData aufgerufen. Dadurch kann der Manager im selben Zyklus noch alte PowerSteps verwenden, sofern die Verbraucher nicht ohnehin ueber ihren eigenen Timer aktuell sind.
Robuster waere:
- Alle Verbraucher per
GetCurrentData($Is_Peak_Shaving)aktualisieren. - Danach
PowerSteps,Idle,Leistung_Deltaneu lesen. - Dann verteilen.
Alternativ koennte GetCurrentData() synchron Daten zurueckgeben statt nur Variablen zu schreiben.
10.3 Validierung und Fail-Safe
Viele Properties sind Variable-IDs. Hauefig ist 0 Default. Vor GetValue(0) oder SetValue(0) sollte konsequent geprueft werden:
$id = $this->ReadPropertyInteger("Netzbezug");
if ($id <= 0 || !IPS_VariableExists($id)) {
$this->SetStatus(201); // oder eigener Fehlerstatus
return;
}
Empfehlung:
- Konfigurationspruefung in
ApplyChanges(). - Statuscodes fuer unvollstaendige Konfiguration.
- sichere PowerSteps bei Kommunikationsfehlern.
10.4 Einheitliche Logging- und Diagnosevariablen
Aktuell gibt es viele IPS_LogMessage()-Eintraege, teils sehr haeufig in Schleifen. Besser waeren:
Letzter_Fehlerals String.Letzte_Aktionals String.Letzte_Kommunikationals Timestamp.Kommunikation_OKals Boolean.- Debug-Logging nur optional per Property.
10.5 Ladestation v3 / OCPP-orientierte Architektur
Ladestation_v2 enthaelt bereits viele Funktionen, die fuer ein OCPP-Modul relevant sind:
- Freigabe
- Solarladen
- Fahrzeugerkennung
- Statusabfrage
- effektive Ladeleistung
- Stromvorgabe
- Mindeststrom
- 1p/3p-Erkennung
- externe Leistungszuweisung
- PowerSteps
- Peak-Shaving-Einfluss
- Idle-/Pending-/Timer-Logik
- Token-/Login-Mechanismen
Fuer eine neue OCPP-orientierte Version sollte diese Logik fachlich erhalten bleiben, aber in Adapter aufgeteilt werden:
ChargePointModel: internes Datenmodell.ChargingSession: Ladevorgang, Benutzer, Energie.MeterValues: Messwerte.SmartCharging: Sollstrom/Sollleistung.ConnectorState: Status pro Ladepunkt.VendorAdapterInterface: Herstelleradapter.Ocpp16Adapter,Ocpp201Adapter,GoEAdapter,EaseeAdapter,SmartMeAdapter,ECarUpAdapter.
Die EMS-Schnittstelle zum Manager sollte gleich bleiben: PowerSteps, SetAktuelle_Leistung, GetCurrentData, Idle.
10.6 Tests und Simulation
Das Projekt hat aktuell keine automatisierten Tests. Sinnvoll waere ein Simulationsmodus:
- Fake-Verbraucher mit frei definierbaren
PowerSteps. - Fake-Netzbezug.
- Testfaelle fuer Solarladen und Peak-Shaving.
- Testfaelle fuer Verbraucher mit und ohne
0. - Testfaelle fuer negative PowerSteps.
- Testfaelle fuer gleiche Prioritaet/Fairness.
- Testfaelle fuer Hauptmanager-JSON.
11. Bekannte technische Risiken und Auffaelligkeiten
Diese Punkte sind aus dem aktuellen Code abgeleitet und sollten vor groesseren Erweiterungen geprueft werden:
- Mehrere Dateien zeigen Encoding-Probleme in deutschen Texten. Das deutet auf UTF-8/ANSI-Mischung hin.
Manager::DistributeEnergy()aktualisiert Verbraucher mitGetCurrentData, liest aber vorher bereits viele Verbraucherdaten. Das kann zu veraltetenPowerStepsfuehren.- Viele Module pruefen konfigurierte Variablen-IDs nicht konsequent vor
GetValue()oderSetValue(). Ansteuerung_AskoheatregistriertBoilertemperaturdoppelt, einmal Float und spaeter Integer.Boiler_x_Stufignutzt in der Zeitplanpruefung offenbar$vollLeistung, ohne diese Variable vorher eindeutig zu setzen.Ladestation_v2::GetCurrentData()verwendet in einem Zweig fuersolarladen && Peakdie Variable$is_1_ph, die dort nicht definiert ist. Gemeint ist wahrscheinlich$this->GetValue("Is_1_ph").Pufferspeicherprueft in der Glaettungslogik teilweiseGetIDForIdent("Boilertemperatur"), obwohl die VariablePuffertemperaturheisst.Batterie::CheckIdle()verwendetGetValue("Aktuelle_Leistung")mit String statt Variablen-ID. Die Funktion scheint aktuell nicht zentral genutzt zu werden, sollte aber korrigiert werden.Verbraucher_Sperrbar::ist_nachts()nutzt24:00als Startzeit. Das ist fachlich ungewoehnlich und sollte geprueft werden.- Mehrere Module setzen
date_default_timezone_set("Europe/Berlin"); fuer Schweizer Anlagen waereEurope/Zurichkonsistenter. Belevo_Bezahl_Modulist nur Prototyp/Teststand und enthaelt noch Platzhalter.- Logging in Schleifen kann im Dauerbetrieb sehr viele Meldungen erzeugen.
12. Arbeitsanweisung fuer ChatGPT/Codex bei zukuenftigen Aenderungen
Wenn ChatGPT/Codex spaeter an dieser Software weiterarbeitet, sollte es so vorgehen:
- Zuerst
DOKUMENTATION_CHATGPT.md,README.md,Manager/module.phpund das betroffene Modul lesen. - Vor jeder Aenderung pruefen, ob das Modul ein Verbraucher ist und den EMS-Vertrag einhalten muss.
- Bestehende Variablen-Idents nicht ohne Migrationsplan umbenennen, weil IP-Symcon Installationen davon abhaengen.
- Neue Module mit eigenem Ordner,
module.php,module.json,form.jsonanlegen. - Bei neuen Verbrauchern die Pflichtvariablen exakt gleich benennen.
PowerStepsundLeistung_Deltabesonders sorgfaeltig testen.- Bei Hardware/API-Modulen immer Fehlerfaelle abfangen und sichere Werte setzen.
- Keine bestehenden Benutzer- oder Anlagenkonfigurationen brechen.
- Bei Ladestationen die EMS-Schnittstelle stabil halten, auch wenn intern OCPP oder Herstelleradapter eingefuehrt werden.
- Nach Aenderungen mindestens PHP-Syntax pruefen und, wenn moeglich, mit einer simulierten Manager-Konfiguration testen.
13. Kurzreferenz fuer neue ChatGPT-Prompts
Wenn ein neues ChatGPT-Fenster mit dieser Software weiterarbeiten soll, kann folgender Kontext verwendet werden:
Dies ist eine IP-Symcon Modulbibliothek fuer das Belevo Energiemanagement.
Der zentrale Manager verteilt Leistung an Verbraucher ueber einen gemeinsamen Vertrag:
Variablen: Sperre_Prio, PV_Prio, Idle, Aktuelle_Leistung, Bezogene_Energie,
PowerSteps, Power, Is_Peak_Shaving, Leistung_Delta, IdleCounter.
Actions: GetCurrentData(bool Peak), SetAktuelle_Leistung(power), Do_UserCalc.
PowerSteps ist ein JSON-Array moeglicher Leistungsstufen in Watt.
Positive Werte bedeuten Verbrauch/Laden, negative Werte Entladen/Einspeisen.
Der Manager entscheidet zwischen Solarladen und Peak-Shaving und verteilt nach Prioritaet.
Neue steuerbare Module muessen diesen Vertrag exakt umsetzen.
Wichtige Dateien: Manager/module.php, HauptManager/module.php,
Ladestation_v2/module.php, Batterie/module.php, DOKUMENTATION_CHATGPT.md.