Seite 2 von 3
Re: Betriebsstundenzähler
Verfasst: 25. Jan 2016 12:36
von toto1975
In meiner mysql Datenbank habe ich folgende Einträge
Time | Value
2016-01-23 20:30:38 | 0
2016-01-23 20:33:48 | 0
usw.
Den Fehler erhalte ich immer dann wenn ich die Seite öfnen möchte auf dem das Item ist kommentiere ich das Item aus erhalte ich beim öffnen der Seite keine Fehlermeldung und die Seite öffnet sich.
Gruß
Torsten
Re: Betriebsstundenzähler
Verfasst: 25. Jan 2016 12:49
von seppy
Wie sieht denn Deine Itemdefinition aus?
Re: Betriebsstundenzähler
Verfasst: 27. Jan 2016 23:00
von seppy
Hallo Zusammen,
hier noch eine überarbeitete Variante:
Code: Alles auswählen
var long last_change = now.millis
rule "Betriebsdauerzähler"
when
Item DevSchalter changed
then
var Number sum = 0
var Number ontime = 0
if (previousState == OFF){
last_change = now.millis
logInfo("Homebox.DEV", "Schalter ON: " + last_change)
logInfo("Homebox.DEV", "Aktueller Zählerstand: " + Betriebsdauer.state)
} else if (previousState == ON) {
if (Betriebsdauer.state == Uninitialized){
logInfo("Homebox.DEV", "Betriebsdauer nicht initialisiert")
Betriebsdauer.postUpdate(0)
}
ontime = (now.millis - last_change)
sum = ((Betriebsdauer.state as DecimalType).longValue) + ontime
logInfo("Homebox.DEV", "Gerät angeschaltet: " + last_change)
logInfo("Homebox.DEV", "Gerät abgeschaltet: " + now.millis)
Betriebsdauer.postUpdate(sum)
Betriebsdauer.persist
logInfo("Homebox.DEV", "Laufzeit Gerät Abschaltzeitpunkt in Millisekunden - Anschaltzeitpunkt in Millisekunden = Laufzeit: " + ontime.toString )
logInfo("Homebox.DEV", "Betriebszeit (Std.) gesamt: " + (sum/60000))
}
end
Hier auf erfolgt die Speicherung auf Millisekundenbasis, da sonst beim Umrechnen auf Std. bzw. Minuten zu viel verloren geht!
Grüße,
Seppy
Re: Betriebsstundenzähler
Verfasst: 13. Mai 2020 08:26
von littleswabi
Hallo
das Thema ist schon alt aber ich wüsste gern wie die ITEM Definition dafür aussieht
Wäre sehr dankbar für eine Antwort
Grüße
Re: Betriebsstundenzähler
Verfasst: 14. Mai 2020 06:20
von udo1toni
Ist ja eigentlich weiter oben mit drin
Aber Vorsicht! Die Rules sind 4 Jahre alt, mit einer aktuellen Version von openHAB (OH2.5.4) wird der Code ohne Änderungen nicht sauber laufen.
Mein Vorschlag:
Code: Alles auswählen
// globale Variablen zu Beginn der Datei definieren!
var long dtStart = now.millis
rule "Betriebsdauer"
when
Item MySwitch changed // Überwachter Schalter
then
if (newState == ON){ // Schalter ein
dtStart = now.millis // Zeitpunkt retten
} else if (newState == OFF) { // Schalter aus
var Integer iSum = 0 // Variable initialisieren
if (MySwitchBZ.state instanceof Number) // Falls Zähler initialisiert
iSum = MySwitchBZ.state as Number // Zählerstand übernehmen
else // ansonsten
logWarn("oc.myswitch", "Betriebsdauer für MySwitch wird initialisiert!") // Meldung ausgeben
iSum = iSum + ((now.millis - dtStart + 500) / 1000).intValue // Einschaltdauer addieren
MySwitchBZ.postUpdate(iSum) // und speichern
}
end
Die Betriebsdauer wird hier in Sekunden gespeichert.
Da Sekunden schnell unübersichtlich werden, wird die Ausgabe per JS formatiert. Der JS Transformation Service muss installiert sein.
Die Items:
Code: Alles auswählen
Switch MySwitch "Mein Schalter [%s]" {...}
Number MySwitchBZ "Betriebsdauer [JS(secToHMS.js):%s]" // Item persistieren (everyChange, restoreOnStartup, mapDB reicht)
und das notwendige JavaScript Script:
secToHMS.js:
Code: Alles auswählen
(function(seconds){
var retval = "";
var hours = Math.floor(seconds / 3600)
seconds = seconds % 3600
var minutes = Math.floor(seconds / 60)
seconds = seconds % 60
retval = retval + hours + "h";
if (minutes < 10)
retval = retval + "0";
retval = retval + minutes+"m";
if (seconds < 10)
retval = retval + "0";
retval = retval + seconds+"s";
return retval;
})(input)
Die Betriebsdauer Anzeige wird erst beim Abschalten aktualisiert. Sollte der Zählerstand beim Abschalten nicht initialisiert sein, so startet der Zähler bei 0. Sollte der Schalter beim Start von openHAB bereits eingeschaltet sein, so wird der Einlesezeitpunkt der rules als Einschaltzeitpunkt angenommen.
Sollte man mehrere Zähler benötigen, so müssen auch mehrere Variablen für den Startzeitpunkt definiert werden. Dann sollte man das Konzept überdenken.

Re: Betriebsstundenzähler
Verfasst: 14. Mai 2020 08:42
von littleswabi
Hallo Udo,
vielen Dank für die schnelle und ausführliche Antwort. Habe das so übernommen und für meine Zwecke angepasst.
Allerdings bekomme ich bei ausschalten folgenden Fehler:
Code: Alles auswählen
2020-05-14 08:32:51.761 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Betriebsdauer': An error occurred during the script execution: Could not invoke method: org.eclipse.xtext.xbase.lib.IntegerExtensions.operator_plus(int,int) on instance: null
meine Rule sieht so aus:
Code: Alles auswählen
// globale Variablen zu Beginn der Datei definieren!
var long dtStart = now.millis
rule "Betriebsdauer"
when
Item Sandfilter_Power changed // Überwachter Schalter
then
if (newState == ON){ // Schalter ein
dtStart = now.millis // Zeitpunkt retten
} else if (newState == OFF) { // Schalter aus
var Integer iSum = 0 // Variable initialisieren
if (Sandfilterpumpe_Betriebsdauer.state instanceof Number) // Falls Zähler initialisiert
iSum = Sandfilterpumpe_Betriebsdauer.state as Number // Zählerstand übernehmen
else // ansonsten
logWarn("oc.myswitch", "Betriebsdauer für MySwitch wird initialisiert!") // Meldung ausgeben
iSum = iSum + ((now.millis - dtStart + 500) / 1000).intValue // Einschaltdauer addieren
Sandfilterpumpe_Betriebsdauer.postUpdate(iSum) // und speichern
}
end
Dein mySwitchBZ habe ich durch Sandfilterpumpe_Betriebsdauer ersetzt.
Code: Alles auswählen
Strategies {
everyMinute : "0 * * * * ?"
everyHour : "0 0 * * * ?"
everyDay : "0 0 0 * * ?"
}
Items {
Sandfilterpumpe_Betriebsdauer : strategy = everyChange, restoreOnStartup
Poolheizung_Betriebsdauer : strategy = everyChange, restoreOnStartup
Sandfilter_Power : strategy = everyChange, restoreOnStartup
Heizung_Power : strategy = everyChange, restoreOnStartup
}
Was mache ich noch verkehrt? In meiner Seitmap werden 0h00m00s angezeigt.
Grüße
Michael
Re: Betriebsstundenzähler
Verfasst: 14. Mai 2020 10:14
von udo1toni
Ach, vermutlich muss die Betriebsdauer auch explizit nach int gewandelt werden:
Code: Alles auswählen
iSum = (Sandfilterpumpe_Betriebsdauer.state as Number).intValue
Re: Betriebsstundenzähler
Verfasst: 14. Mai 2020 10:32
von littleswabi
Hi,
super!!! Funktioniert wunderbar!
VIELEN DANK!!!!

Re: Betriebsstundenzähler
Verfasst: 18. Mai 2020 07:39
von littleswabi
Hallo Udo,
ich habe noch eine Frage. Wenn ich die Betriebsstunden nicht vom bloßen einschalten abhängig machen will sondern vom Verbrauche reicht es dann wennn ich:
Code: Alles auswählen
when
Item Sandfilter_Power changed // Verbrauch der Pumpe
then
if (newState => 10){ // Verbrauch > 10w
dtStart = now.millis // Zeitpunkt retten
} else if (newState =< 10) { // Verbrauch <10 w
als Bedingung nehme?
Re: Betriebsstundenzähler
Verfasst: 18. Mai 2020 16:12
von udo1toni
Wie soll denn das gehen?
Entweder, das Gerät hat im ausgeschalteten Zustand keinen Verbrauch (also 0), oder es hat einen Verbrauch, dann müsste diese Zeit aber auch als Betriebszeit mit zählen.
Eine Unterscheidung nach Verbrauch ist auch recht kritisch, da der Verbrauch durchaus um den Schwellwert herum schwanken kann.
Mindestens solltest Du also eine Hysterese vorsehen. Z.B. beginne mit dem Zählen, wenn der Verbrauch höher als 12 ist, beende den Zählvorgang, wenn der Verbrauch unter 10 sinkt.
Die Werte müssen natürlich zum angeschlossenen Gerät passen, und der Verbrauch des Geräts darf während des Betriebs nie unter die Abschaltschwelle sinken.
Z.B. bei einer Waschmaschine ist der Energiebedarf höchst variabel und hängt auch noch stark vom genutzten Programm ab, das ist also keinesfalls trivial.
Mindestens musst Du dann über einen längeren Zeitraum Daten sammeln und auswerten, um die Rule einigermaßen schussfest zu bekommen.