|
Ne Regel die beim Einschalten den Zeitstempel nimmt und beim Ausschalten wieder. Die Differenz ist die Zeit die die Lampe eingeschaltet war. Die Differenz wird beim Ausschalten in einen Summenzähler addiert.
|
Das hab ich jetzt mal in einer ersten Version umgesetzt, ist aber ganz sicher noch deutlich verbesserungswürdig. Hier mal exemplarisch für eine Steckdose:
Items:
Code:
Number Steckdosen_Wohnen_Heizung_links_Zaehler "Steckdose Heizung li. [%d]" (gOperatingHours)
String Steckdosen_Wohnen_Heizung_links_Betriebsstunden "Steckdose Heizung li. [%s]" (gOperatingHoursFormated)
Die beiden Gruppen nutze ich vor allem um mir die Einträge in der db4o.persist zu vereinfachen.
Dazu eine Regel, die beim Ausschalten die Zeitdifferenz zum Zähler addiert:
Code:
import org.openhab.core.library.types.*
import java.util.Calendar
import java.util.Date
import java.util.TimeZone
var Calendar Steckdosen_Wohnen_Heizung_links_OnTime
rule "Aktualisiere Betriebsstunden Steckdosen_Wohnen_Heizung_links_Schalten"
when
Item Steckdosen_Wohnen_Heizung_links_Schalten changed
then
if (Steckdosen_Wohnen_Heizung_links_Schalten.state == ON) {
Steckdosen_Wohnen_Heizung_links_OnTime = java::util::Calendar::getInstance(TimeZone::getTimeZone("Europe/Berlin"))
} else if (Steckdosen_Wohnen_Heizung_links_Schalten.state == OFF) {
var Calendar now = java::util::Calendar::getInstance(TimeZone::getTimeZone("Europe/Berlin"))
var Number Diff = (now.getTimeInMillis() - Steckdosen_Wohnen_Heizung_links_OnTime.getTimeInMillis()) / 1000
var Number Zaehler = (Steckdosen_Wohnen_Heizung_links_Zaehler.state as DecimalType) + Diff
Steckdosen_Wohnen_Heizung_links_Zaehler.postUpdate(Zaehler)
var Number h = (Zaehler/3600).intValue
var Number m = ((Zaehler-h*3600)/60).intValue
var Number s = ((Zaehler-h*3600 - m*60)).intValue
var String TimeString = h + ":"
if (m < 10) {TimeString = TimeString + "0" + m.toString + ":"} else {TimeString = TimeString + m.toString + ":"}
if (s < 10) {TimeString = TimeString + "0" + s.toString } else {TimeString = TimeString + s.toString }
Steckdosen_Wohnen_Heizung_links_Betriebsstunden.postUpdate(TimeString)
logInfo("operating hours rules", "Updated operating counter for Steckdosen_Wohnen_Heizung_links_Schalten: " + Zaehler)
}
end
Initialisierung beim Start:
Code:
rule "Initialisiere Betriebsstundenzaehler"
when
System started
then
Steckdosen_Wohnen_Heizung_links_OnTime = java::util::Calendar::getInstance(TimeZone::getTimeZone("Europe/Berlin"))
if (Steckdosen_Wohnen_Heizung_links_Zaehler.state == Uninitialized) {
Steckdosen_Wohnen_Heizung_links_Zaehler.postUpdate(0)
}
end
Zusätzlich kann man bei lang laufenden Verbrauchern den Zähler auch periodisch, dann aber mit langem Intervall aktualisieren:
Code:
rule Betriebsstundenzaehler
when
Time cron "* 0/30 * * * ?" // Abfrage alle 30min
then
var Number Diff
var Number Zaehler
var Calendar now = java::util::Calendar::getInstance(TimeZone::getTimeZone("Europe/Berlin"))
if (Steckdosen_Wohnen_Heizung_links_Schalten.state == ON) {
Diff = (now.getTimeInMillis() - Steckdosen_Wohnen_Heizung_links_OnTime.getTimeInMillis()) / 1000
Zaehler = (Steckdosen_Wohnen_Heizung_links_Zaehler.state as DecimalType) + Diff
Steckdosen_Wohnen_Heizung_links_Zaehler.postUpdate(Zaehler)
Steckdosen_Wohnen_Heizung_links_OnTime = java::util::Calendar::getInstance(TimeZone::getTimeZone("Europe/Berlin"))
var Number h = (Zaehler/3600).intValue
var Number m = ((Zaehler-h*3600)/60).intValue
var Number s = ((Zaehler-h*3600 - m*60)).intValue
var String TimeString = h + ":"
if (m < 10) {TimeString = TimeString + "0" + m.toString + ":"} else {TimeString = TimeString + m.toString + ":"}
if (s < 10) {TimeString = TimeString + "0" + s.toString } else {TimeString = TimeString + s.toString }
Steckdosen_Wohnen_Heizung_links_Betriebsstunden.postUpdate(TimeString)
}
end
Ich bin noch beim Testen, Fehler sind also durchaus noch wahrscheinlich.
Natürlich ist das eine Sache bei der man sich, gerade bei vielen Verbrauchern, Funktionen in den Regeln wünscht...
Was mir überhaupt nicht gefällt ist die umständliche Formatierung des Strings zur Anzeige, eigentlich sogar schon nicht die Tatsache zwei Items zu benötigen. Wenn ich es richtig sehe, kennt das String Item aber keinen Format Operator mit dem man zumindest das Zusammensetzen des Strings etwas schöner umsetzen könnte. Vielleicht habe ich da aber auch andere Möglichkeiten übersehen.
Ein weiterer Schwachpunkt ist, dass der String erst beim Ausschalten des Verbrauchers (oder ggf. periodisch) aktualisiert wird. Deshalb hab ich in mit in die Persistence-Datenbank aufgenommen, damit er nach dem Start korrekt angezeigt wird. Alternativ könnte man ihn auch grundsätzlich peridisch aktualisieren oder Regeln erstellen, die auf das Ändern des Zählers triggern. Das sind mir dann aber doch deutlich zu viele Regeln. Bei meiner aktuellen Version mit 41 Verbrauchern reagiert der Designer beim Bearbeiten der Regel-Datei schon deutlich behäbig.
Als Kompromiss wäre auch eine Regel denkbar, die auf das Ändern aller Zähler triggert und dann jedes mal alle Strings aktualisiert. So etwas ist natürlich beim Start blöd.
Vielleicht habt ihr da ja noch Vorschläge?
P.S.: Warum der Browser das End im letzten Codeblock schluckt ist mir nicht klar, in meinem Posting ist es enthalten...