Du willst also die Energie bei negativen Leistungswerten für eine gewisse Dauer erfassen.
Ich hatte davon zunächst eine andere Vorstellung ...
Da ich derzeit keine solche Anlage besitze, kann ich nur assistieren.
Frage: Woraus ergibt sich die vom Shelly gelieferte Information zur Energie?
Ich vermute, dass aenergy hierfür nicht genutzt werden kann.
Das Prinzip sollte folgendermaßen gelingen.
Man erstellt einen Eventhandler, in welchem man das Ereignis mit den gewünschten Daten selektiert.
Das eintreffende Event liegt in einem Objekt vor, welches man sich anzeigenlassen kann, um dessen Struktur zu analysieren.
Es sind sowohl die Leistung (Komponente apower) als auch der Zeitstempel (Komponente ts = timestamp) zu nutzen
let Overage = 0;
let Timestamp = null;
Shelly.addEventHandler(
function(e) {
print(JSON.stringify(e)); // zeigt die Struktur des Event e
let comp = e.info.component;
if(comp===undefined) return; // nicht zwingend, kann aber nicht schaden
if (comp===<Komponentenname>) { // <Komponentenname> muss durch die passende Komponente ersetzt werden
// Evtl. ist die Selektion mit einer anderen Objektkomponante als e.info.component erforderlich
let t = e.info.ts; // oder ähnlich
if(Timestamp===null) {
Timestamp = t;
return;
}
let p = e.info.apower; // oder ähnlich
let dt = t - Timestamp;
Timestamp = t;
if(p<0) {
Overage -= p * dt; // dt in s -> Einheit Ws, evtl. prüfen
// Nachricht mit Overage Wert senden, bspw. per MQTT
MQTT.publish("Dein/Topic/Overage", JSON.stringify(Overage));
}
}
}
);
Alles anzeigen
Dies kann allerdings nicht genau sein, da hierbei nur Mittelwerte genutzt werden.
Verbesserungsansatz (wäre zu testen, muss nicht zwingend funktionieren):
Man definiert eine sog. Epsilon-Umgebung vor dem Wert 0, per
let Epsilon = 1; // in Watt
Liegt apower innerhalb dieser Umgebung, wird ts in Timestamp gespeichert.
if(p<0 && p>-Epsilon) Timestamp = ts;
Zu negativen apower-Werten wird jeweils die Energie wie oben berechnet und in Overage gespeichert.
Sobald apower wieder innerhalb der Epsilon-Umgebung liegt oder positiv ist, wird der gespeicherte Overage-Wert gesendet.
let Overage = 0;
let Timestamp = null;
let Epsilon = -1; // in Watt, muss realistisch gewählt werden
Shelly.addEventHandler(
function(e) {
print(JSON.stringify(e)); // zeigt die Struktur des Event e
let comp = e.info.component;
if(comp===undefined) return; // nicht zwingend, kann aber nicht schaden
if (comp===<Komponentenname>) { // <Komponentenname> muss durch die passende Komponente ersetzt werden
// Evtl. ist die Selektion mit einer anderen Objektkomponante als e.info.component erforderlich
let t = e.info.ts; // oder ähnlich
let p = e.info.apower; // oder ähnlich
if(p<0) {
if(Timestamp===null) {
Timestamp = ts;
return;
}
Overage -= p * (ts - Timestamp); // ts in s -> Einheit Ws, evtl. prüfen
}
if(p>Epsilon && Timestamp!==null) {
Timestamp = null; // ungültig machen
// Nachricht mit Overage Wert senden, bspw. per MQTT
MQTT.publish("Dein/Topic/Overage", JSON.stringify(Overage));
}
}
}
);
Alles anzeigen
Ich kann dies derzeit nicht testen, voraussichtlich in 2024.
Der Epsilon-Wert ergibt sich aus realistischen apower-Werten und ist passend zur Anlage zu wählen.
Die Genauigkeit hängt u.a. von der Abtastrate und den Änderungsschwellen zum Auslösen des Event in der Firmware ab.
Edit:
Eine Zeitspanne zum saldieren von Overage ist bisher nicht festgelegt.
Hierzu wäre noch eine kleine Funktion overageReset() {Overage = 0;} einzubauen und ein Schedule Job anzulegen, welcher diese Funktion per Methode "Script.Eval" aufruft.
Hierzu habe ich inzwischen eine Webseite erstellt, die das Anlegen eines solchen Jobs unterstützt. Das geht mit der WebUI derzeit nicht.
Link dazu: https://tools.eichelsdoerfer.net/schedjob.html
Edit 2:
Alternativ oder ergänzend kann man auch dieses Overage-Rücksetzen per Nachricht vornehmen lassen, bspw. per MQTT Subscriber.