Ebenen Modell Einleitung Konzepte Die Konzepte im Ebenenmodell dienen als Design-Pattern und Nomenklatur. Sie geben Beispiel für die Implementierung und Abbildung auf eine individuelle Problemstellung SaldoId Eines der Ziele jeder Ebene ist die Bildung einer Energiebilanz. Damit auch asynchron mit Sensordaten gearbeitet werden kann, wird eine SaldoId verwendet. Auf jeder Ebene wird die SaldoId mit Hilfe eines Inject einmal zum Start des Flows und dann in regelmäßigen Intervallen neu definiert und als Flow Variable den Komponenten der jeweiligen Ebene (Flow) zur Verfügung gestellt. Gleichzeitig werden die Summen des Flows zurückgesetzt. flow.set("Consumption",0); flow.set("Generation",0); flow.set("SaldoID",new Date().toLocaleString()); return msg; Hinweis Die SadoId sollte nicht zu häufig aktualisiert werden, damit bei der Bildung der Bilanz für die Ebene alle Messwerte berücksichtigt werden. Bilanzierung einer Ebene (Saldo) Jede Ebene bildet für sich eine Bilanz (Saldo). Hierbei wird in der Einheit Watt gerechnet (nicht WattStunde!), da die Sensoren so oft wie möglich einen Messwert liefern sollen. msg.payload = flow.get('Consumption') - flow.get('Generation'); flow.set('Saldo',msg.payload); node.status({text:"P: "+msg.payload+" W"}); return msg; Zweistufige Prognoseerstellung Die Vorhersagen in den Ebenen werden in zwei Schritten durchgeführt. Zunächst wird eine generische Abbildung auf Abhängige Werte vorgenommen und im Anschluss in einen Graphen (=konkrete Zeitreihe) überführt. Schritt 1: Abbildung // Create empty array if not exists let hours = {}; for(let i=0;i<24;i++) { hours["h"+i] = { latest: {}, outcome: { sum: 0, cnt: 0, mean: 0, min: 9999999, max:0, min_gsi:999999 } }; } for(let i=0;i max) max = saldo[i].fields.w ; if(saldo[i].fields.w < min) min = saldo[i].fields.w ; } let delta = max - min; for(let i=0; i max) max = saldo[i].fields.w ; if(saldo[i].fields.w < min) min = saldo[i].fields.w ; } let delta = max - min; for(let i=0; i 2000) msg.payload = 2000; msg.payload += flow.get('Consumption') + global.get('FlexConsumption'); node.status({text:"P: "+msg.payload+" W"}); return msg; Vorhersage / Prognose Die Vorhersage in Ebene 1 erfolgt durch Fortschreibung der Prognose in Ebene 0. Basierend auf den Ebene 0 Werten, wird der Speicherfüllstand vorhergesagt und die flexiblen Lasten ergänzt. Funktion Vorhersage SoC und Flex Integration let saldo = flow.get("Saldo") - flow.get("Consumption"); let options = global.get("FlexOptions"); for(let i=0; i 2000) w = 2000; if(w < -2000) w = -2000; if(saldo + w > 5500) w = 5500-saldo; if(saldo + w < 0) w = saldo; saldo += w; msg.payload[i].fields.w -= w; msg.payload[i].fields.flex = flex; msg.payload[i].fields.wh = saldo; } flow.set("forecastSaldo",msg.payload); node.status({text:""+new Date().toLocaleString()}); return msg; Optionen für Flexibilitäten werden im globalen Array FlexOptions gehalten (Zeile 2). Dort gespeichert werden sie durch das individuelle Fahrplanmanagement zum Gerät. Diese einzelnen Vorhersagen werden vor der Berücksichtigung des Speichers integriert (Zeile 9-14). Eine Besonderheit hier ist, dass der Speicher der Referenzimplementierung maximal mit 2.000 beladen und entladen werden kann. Entsprechend kann der Speicherfüllstand innerhalb von einer Stunde maximal um +/- 2 kWh verändert werden (Zeile 17-18).GrünstromIndex Basierend auf dem prognostizierten Saldo der Ebene wird ein GrünstromIndex gebildet und zur Visualisierung mittels Grafana in die InfluxDB gespeichert. Vergleiche: GrünstromIndex je Ebene Funktion Ebenen GSI let saldo = flow.get("forecastSaldo"); let min = 9999999999; let max = -999999999999; for(let i=0; i max) max = saldo[i].fields.w ; if(saldo[i].fields.w < min) min = saldo[i].fields.w ; } let delta = max - min; for(let i=0; i