Seite 1 von 2
[GELÖST] Stoppuhr
Verfasst: 30. Okt 2022 21:08
von lenschith
Hallo zusammen,
ich möchte gerne eine Stoppuhr, die aktiviert wird wenn ein Gerät z.B. Waschmaschine startet und die Zeit stopp wenn das Gerät wieder aus ist. Ich habe leider nichts passendes gefunden. Gibt es da eine Möglichkeit die Werte zu ermitteln?
Danke Gruß
Lenschi
Re: Stoppuhr
Verfasst: 31. Okt 2022 00:16
von udo1toni
ja, das ist kein Problem. Du musst Dir einfach beim Start den Zeitpunkt merken und beim Stoppen die Differenz bestimmen.
Das geht so:
Code: Alles auswählen
var Long lStart = 0
var Integer iSeconds = 0
rule "Betriebsdauer messen"
when
Item Waschmaschine changed
then
if(newState == ON) {
lStart = now.toInstant.toEpochMilli
} else {
iSeconds = ((now.toInstant.toEpochMilli - lStart)/1000).intValue
logInfo("Dauer", "Gemessene Dauer in Sekunden: {}",iSeconds)
}
end
Re: Stoppuhr
Verfasst: 1. Nov 2022 11:28
von lenschith
Hallo Udo,
irgendwie klappt das nicht bei mir. Aber nach langer Überlegung und Testes bin ich zu Erkenntnis gekommen das ich eigentlich was anderes für mein Vorhaben benötige. Ich möchte wenn ein Item auf ON ist eine Uhr laufen lassen die alle 60 Sekunden ein Item mit der aktuellen Laufzeit in HH:MM:SS befüllt um zu sehen wie lange das Gerät bereits läuft. Wenn das Item wieder auf OFF geht sollte die Zeit wieder resettet werden auf 00:00:00 werden. Ich habe gestern Stunden mit Blockly und ECMA Scripte verbracht aber alles ohne Erfolg.
Hat hier noch jemand einen Tipp wie ich das mit Blocky/ECMA Script umsetzen kann?
Gruß Lenschi
Re: Stoppuhr
Verfasst: 1. Nov 2022 13:53
von udo1toni
AH, ja, das ist tatsächlich etwas anderes. Die einfachste Variante, mit einem String Item (im Beispiel myCounterItem):
Code: Alles auswählen
// globale Variablen werden zu Beginn der *.rules Datei definiert, vor der ersten Rule
var Timer tWasch = null // Timer Variable für Counter
var Integer iWasch = 0 // Minutenzähler für Waschmaschine
rule "Betriebsdauer messen"
when
Item Waschmaschine changed // wechselt auf ON oder OFF
then
tWasch?.cancel // Timer löschen, falls vorhanden
if(newState == OFF) { // falls neuer Zustand OFF
myCounterItem.postUpdate("00:00:00") // setze Anzeige auf 0
return; // und beende die Rule
} else { // falls neuer Zustand nicht OFF (also ON)
iWasch = 0 // setze Zähler auf 0
tWasch = createTimer(now.plusMinutes(1),[| // Lege Timer an, der in einer Minute auslöst
iWasch += 1 // erhöhe den Zähler um eins
val iHour = (iWasch/60).intValue // Stundenanteil bestimmen
val iMinute = iWasch - iHour * 60 // Minutenanteil bestimmen
var strState = if(iHour<10)"0" else "" // falls weniger als 10 Stunden führende 0
strState = strState + iHour.toString // Anzahl Stunden
strState = strState + if(iMinute<10) ":0" else ":" // Falls weniger als 10 Minuten führende 0
strState = strState + iMinute.toString+":00" // Anzahl Minuten
myCounterItem.postUpdate(strState) // Item updaten
tWasch.reschedule(now.plusMinutes(1)) // Timner erneut planen
])
}
end
Allgemein kann man das auch mit einem DateTime Item machen (und sich dann das Jonglieren mit führenden Nullen schenken). Allerdings ist das Hantieren mit DateTime deutlich komplexer als die gezeigte Variante. Der neue Status des Anzeigeitems kann auch in einer Zeile angegeben werden, hier nur der Übersichtlichkeit halber als mehrere getrennte Operationen...
Re: Stoppuhr
Verfasst: 1. Nov 2022 21:10
von lenschith
Hallo Udo,
ich wollte das jetzt implementieren aber irgendwie stehe ich voll auf der Leitung und bekomme das nicht gebacken über die UI in OH3?
ich habe eine Rule über die UI angelegt und bekommen diese Fehlermeldung im Log:
Code: Alles auswählen
[ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'Timer_Geschirrspueler' failed: var Timer tWasch = null
Code: Alles auswählen
1. Cannot refer to the non-final variable iWasch inside a lambda expression; line 11, column 872, length 6
2. Type mismatch: cannot convert from int to Integer; line 11, column 879, length 2
3. Cannot refer to the non-final variable iWasch inside a lambda expression; line 12, column 978, length 6
4. Cannot refer to the non-final variable iWasch inside a lambda expression; line 13, column 1070, length 6
5. Cannot refer to the non-final variable tWasch inside a lambda expression; line 19, column 1605, length 6
Was mache ich falsch bzw. wo liegt denn da bei mir der Fehler. Ich habe schon länger nichts mehr mit den DSL Rules gemacht und mach seit dem Umstieg auf OH3 alles über die UI.
CODE:
Code: Alles auswählen
configuration: {}
triggers:
- id: "1"
configuration:
itemName: TestSwitch
type: core.ItemStateChangeTrigger
conditions: []
actions:
- inputs: {}
id: "2"
configuration:
type: application/vnd.openhab.dsl.rule
script: >
var Timer tWasch = null // Timer
Variable für Counter
var Integer iWasch = 0 // Minutenzähler für Waschmaschine
tWasch?.cancel // Timer löschen, falls vorhanden
if(newState == OFF) { // falls neuer Zustand OFF
GeschirrspuelerTimer.postUpdate("00:00:00") // setze Anzeige auf 0
return; // und beende die Rule
} else { // falls neuer Zustand nicht OFF (also ON)
iWasch = 0 // setze Zähler auf 0
tWasch = createTimer(now.plusMinutes(1),[| // Lege Timer an, der in einer Minute auslöst
iWasch += 1 // erhöhe den Zähler um eins
val iHour = (iWasch/60).intValue // Stundenanteil bestimmen
val iMinute = iWasch - iHour * 60 // Minutenanteil bestimmen
var strState = if(iHour<10)"0" else "" // falls weniger als 10 Stunden führende 0
strState = strState + iHour.toString // Anzahl Stunden
strState = strState + if(iMinute<10) ":0" else ":" // Falls weniger als 10 Minuten führende 0
strState = strState + iMinute.toString+":00" // Anzahl Minuten
GeschirrspuelerTimer.postUpdate(strState) // Item updaten
tWasch.reschedule(now.plusMinutes(1)) // Timner erneut planen
])
}
type: script.ScriptAction
Das Item GeschirrspuelerTimer ist als STRING deklariert.
Oder muss ich hier wieder über Rule Files arbeiten und nicht über die UI?
Re: Stoppuhr
Verfasst: 2. Nov 2022 02:01
von udo1toni
Nein, die Rule kann nicht über die UI angelegt werden, das geht ausschließlich über die Rules Textdateien, das liegt daran, dass die verwendeten Variablen global sein müssen.
Grundsätzlich, wenn man Timer in der vorgeführten Version nutzen möchte (und das ist die einfachste Art, diese Aufgabe zu erledigen) wird das meistens nur über die ursprüngliche Form der DSL Rules gehen.
Re: Stoppuhr
Verfasst: 2. Nov 2022 14:55
von lenschith
Danke Udo, klapp wie gewollt.
Gruß Lenschi
Re: [GELÖST] Stoppuhr
Verfasst: 2. Nov 2022 17:44
von Harka
schön das es klappt.
Falls es doch mal jemand Udos Lösung, so wie ich gestern Abend (aus reiner Neugier und in abgewandelter Form) getan habe, mit Blockly nachbauen möchte -> geht.
Für die globale Variable einfach stored_value nutzen (wie? ist in der Hilfe beschrieben) und die Timer Funktionen inklusive reschedule sind auch von Haus aus enthalten. Damit kann die Lösung als Blockly/ECMA auch über die UI verwaltet werden.
Re: [GELÖST] Stoppuhr
Verfasst: 2. Nov 2022 18:01
von lenschith
Kannst du mal das blockly Script posten. Ich hab soviel getestet und gelesen aber habs nicht geschafft. Würde es interessieren damit ich fürs nächste mal ne weitere Option habe.
Re: [GELÖST] Stoppuhr
Verfasst: 2. Nov 2022 18:33
von Harka
Timer.jpg
musst halt innerhalb des Timers noch die Ausgabe entsprechend einfügen (was aber kein Problem sein sollte). Wie gesagt, habe die Regel etwas anders verwendet (aus reiner Neugier - ohne höheren Sinn) .