Deine Berechnungen der Startzeitpunkte sind verkehrt.
Code: Alles auswählen
rule "Stromverbrauch Tag Woche Monat Jahr" // Deutscher Zeichensatz zulässig
when
Item Heizung_Zaehlerstand_errechnet changed // changed reicht.
then
val ZonedDateTime zdt = ZonedDateTime.now() // jetzt
val ZonedDateTime start_of_day = zdt.with(LocalTime.MIDNIGHT) // heute, Mitternacht
val ZonedDateTime start_of_week = start_of_day.minusDays(start_of_day.getDayOfWeek.getValue - 1) // Montag
val ZonedDateTime start_of_month = start_of_day.withDayOfMonth(1) // Erster Tag des Monats
val ZonedDateTime start_of_year = start_of_day.withDayOfYear(1) // Erster Tag des Jahres
val strom_Heute = (Heizung_Zaehlerstand_errechnet.deltaSince(start_of_day) as Number).floatValue
val strom_Woche = (Heizung_Zaehlerstand_errechnet.deltaSince(start_of_week) as Number).floatValue
val strom_Monat = (Heizung_Zaehlerstand_errechnet.deltaSince(start_of_month) as Number).floatValue
val strom_Jahr = (Heizung_Zaehlerstand_errechnet.deltaSince(start_of_year) as Number).floatValue
Heizung_Verbrauch_Tag.postUpdate(strom_Heute)
Heizung_Verbrauch_Woche.postUpdate(strom_Woche)
Heizung_Verbrauch_Monat.postUpdate(strom_Monat)
Heizung_Verbrauch_Jahr.postUpdate(strom_Jahr)
end
Voraussetzung ist, dass Daten für den Zeitraum zur Verfügung stehen, versteht sich.
Erklärung der Berechnungen:
ZonedDateTime.now kennt diverse Funktionen.
.with kann Teile des Datums gezielt manipulieren, hier die Zeit auf 0:00:00 Uhr setzen (
LocalTime.MIDNIGHT).
.minusDays kann volle Tage vom Datum abziehen.
start_of_day ist eine Instanz von
zdt um Mitternacht, gerade ausgerechnet.
.getDayOfWeek liefert den Wochentag, allerdings als Text.
.getValue liefert eine Zahl, wobei Montag 1 ist und Sonntag 7. Wir wollen maximal 6 abziehen (Sonntags, um auf Montag zu kommen). Montag wollen wir nichts abziehen, deshalb das - 1.
.withDayOfMonth manipuliert den Tag und kann auf 1 bis 31 gesetzt werden. Möchte man den Monatsletzten, so ist es das Einfachste, den Ersten des Folgemonats zu berechnen und anschließend einen Tag abzuziehen
hier geht es um den Monatsersten, also eine 1...
.withDayOfYear ist die gleiche Manipulation, nur auf das komplette Jahr bezogen,
.withDayOfYear(1) zeigt also auf den 1. Januar des aktuellen Jahres, man könnte auch
.withMonth(1).withDayOfMonth(1) schreiben.
.floatValue stellt sicher, dass ein rein numerischer Wert ohne Einheit geliefert wird, ist eventuell nicht notwendig, schadet aber gewöhnlich auch nicht.
Die Methode
Item.postUpdate(Value) ist grundsätzlich der Action
postUpdate(Itemname as string,Value as string) vorzuziehen. Nur wenn man den Namen des Items berechnet, ist die Action eine einfache Möglichkeit, auf das Items selbst zuzugreifen.
Erklärung hierzu:
Die Methode kann mit unterschiedlichen Datentypen als Eingangswert umgehen, die Action braucht zwingend String für beide Parameter. Solange man mit Objekten arbeitet, steht
.toString als Methode zur Verfügung und openHAB verwendet diese automatisch, um das Objekt passend in einen String zu wandeln. Mit Primitives geht das aber schief.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet