Weil mir solche iterativen Berechnungen immer zuwider sind...
Hier mal ein generalisierte Variante:
Notwendige Items:
Ein Number Item Counter (das ist der streng monoton wachsende Zählerstand)
Ein Group Item gGasSummen.
Vier String Items Summe_Day_Gas, Summe_Week_Gas, Summe_Month_Gas und Summe_Year_Gas
Je drei Number Items für Summe_Day_, Summe_Week_ , Summe_Month und Summe_Year, mit den Endungen Liter, Kosten und kwh (Natürlich kann man die Namen beliebig gestalten, die habe ich halt so in meiner Ruel verwendet)
Folgende Rule:
Code: Alles auswählen
rule "Verbrauch Tag Woche Monat Jahr"
when
Item Counter changed // persistierter Zähler
then
val kwprol = 0.1522 // Umrechnung kWh in Liter
val Preis = 1.50 // Preis pro Liter
val zdtd = ZonedDateTime.now.with(LocalTime.MIDNIGHT) // heute, Mitternacht
val zdtAL = newArrayList(zdtd,
zdtd.minusDays(zdtd.getDayOfWeek.getValue - 1),
zdtd.withDayOfMonth(1),
zdtd.withDayOfYear(1))
val hmPeriod = newHashMap("Day"->0,"Week"->1,"Month"->2,"Year"->3) // Itemnamensteil
// Itemnamen z.B. Summe_Day_Gas, Summe_Week_Gas, Summe_Month_Gas, Summe_Year_Gas, in der Gruppe gGasSummen
gGasSummen.members.forEach[i|
val pName = i.name.split("_").get(1) // Zeitraumnamen holen
val period = zdtAL.get(hmPeriod.get(pName)) // Zeitpunkt holen
var Number kwh = 0.0001
if(Counter.deltaSince(period) instanceof Number)
kwh = (Counter.deltaSince(period) as Number).floatValue // kwh aus Persistence auslesen
val liter = (kwh * kwprol * 1000).intValue/1000 // in Liter umrechnen (drei NAchkommastellen
val kosten = (liter * Preis * 100).intValue/100 // in € umrechnen (zwei Nachkommastellen)
logDebug("gas","{}: {} kWh / {} l / {} € {} ({})",period,kwh,liter,kosten,i.name,pName)
postUpdate("Summe_"+pName+"_Liter",liter.toString)
postUpdate("Summe_"+pName+"_Kosten",kosten.toString)
postUpdate("Summe_"+pName+"_kwh",kwh.toString)
i.postUpdate(kwh.toString + " kWh/" + liter.toString + " l/" + kosten.toString + " €") // Item updaten
]
end
Die Rule ist getestet unter openHAB 3.4, wird aber auch unter jeder anderen openHAB Version laufen (unter OH1 und OH2 werden allerdings eventuell imports nötig)
Was passiert?
Zunächst werden oben einige Konstanten definiert. - Wichtig für den Hinterkopf: die ganzen Berechnungen funktionieren natürlich nur mit fixen Werten, um saubere Zahlen zu haben müsste man die Summen täglich persistieren [also um 23:59:59] und die persistierten Tagessummern anschließend abfragen. Das gilt insbesondere beim Preis, der ja gerade momentan eher volatil ist.
In der vierten Zeile wird eine ArrayList mit den abzufragenden Zeitpunkten definiert. Die Zeitpunkte können nun mit zdtAL.get(0-3) angesprochen werden.
die fünfte Konstante ist eine HashMap, um aus den Worten Day, Week, Month und Year die Zahlen 0 bis 3 zu erzeugen. hmPeriod.get("Week") liefert also z.B. 1.
Nun durchläuft die Rule die Gruppe gGasSummen und bestimmt für jedes Item zunächst den Zeitraum (über den zweiten Teilstring des Namens). Sodann wird ein Verbrauch von 0.0001 gesetzt und überschrieben, falls ein gültiger Wert für den Zeitraum vorliegt (da ist noch Verbesserungspotential, ich weiß).
Es werden die auf drei bzw zwei Stellen gerundeten Werte für Liter und Kosten berechnet. Die Werte werden per postUpdate als Zahl in die passenden Items geschrieben und der String wird erzeugt.
Wahlweise könnte man statt des einfachen .toString hier auch mit Formatierung arbeiten und 0-Beträge mit Strichen darstellen, mir ging es hier nur um die Machbarkeit, die Daten mit minimalem Code in die Items zu bringen.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet