- Home
- Deutsch
- Skripten / Logik
- Node-Red
- Timer / Count Down Node
Timer / Count Down Node
-
Da mir die Funktionalität der fertigen Count-Down Node nicht ausreichend war und ich sowieso in dem Thread
Datum- und Zeitverarbeitung mit NodeRed bereits einen Count-Down Flow vorgestellt hatte, war die Idee (brauchte ich für mein Dashboard) gleich wieder mal einen eigenen Subflow in Form einer Timer Node zu erstellen.Ich hab die Node mal unter die Function Nodes eingeordnet:
Im Prinzip habe ich alles in den Hilfetext geschrieben. Man kann eine payload mitgeben, dann wird diese nach Ablauf des Timers gesendet. Gibt man keine payload mit, wird nach Ablauf des Timer false ausgegeben.
Hier mal der Text aus der Hilfebeschreibung der Node:
Timer - Countdown
Dieser Subflow bzw. Timer Node triggert zu einem bestimmten Zeitpunkt in der Zukunft.
Wird keine payload mitgegeben, triggert die Node einfalse
, anderenfalls wird nach Ablauf des Timers die payload getriggert.Der Trigger kann jederzeit mit einer
msg.reset
deaktiviert bzw. zurückgesetzt werden. Wird ein neues timer-Objekt oder date Objekt mitgegeben, so wird dies sofort übernommen und der Timer geändert.Der Status des Timers wird im Status der Node angezeigt. Dabei wird die verbleibende Zeit entweder in Textform, wie
3 Tage 3 Stunden 23 Minuten 43 Sekunden
angegeben oder im Format1T 10:33:45
angezeigt.
Letzters Format muss über den String00:00
in der Subflow Node im ParameterstatusFormat
angegeben werden.Fixer Timer
Der Timer kann über ein festes Timer-Objekt definiert werden, der zum Zeitpunkt des Triggerns addiert wird.
Das Timerobjekt muss inmsg.timer
definiert werden.Das Timerobjekt kann in verschiedenen Zeiteinheiten angegeben werden.
Will man den Status im Dashboard ausgeben, dann kann man den
status.text
mit Hilfe der Status Node ausgeben.{ "days": 1, "hours": 0, "minutes": 1, "seconds": 28 }
Es können auch nur einzelne Zeiteinheiten oder eine Mix angegeben werden:
{ "seconds": 300 }
oder
{"minutes":1,"seconds":90}
Fixes Datum
Alternativ zu einem fixen Timerobjekt, kann man auch ein festes Datum in Form eines moments-Objektes in der Eigenschaft
msg.date
mitgegeben werden.
Für das lokale Datum bzw. das moments-Objekt muss bei Verwendung der Date/Time Picker des Dashboard utc.(false) mitgegeben werden.In dem Flow - in dem die Node enthalten ist, sind auch im Dashboard ein paar Beispiele zum Ausprobieren:
Dort kann man ausprobieren, wie man moments Objekte zu bestimmten Zeitpunkten in der Zukunft konstruiert und damit ein fixes Datum vorgibt bzw. das Datum über Datums- und Uhrzeit Picker fix auswählt.
Der Countdown wird im Status der Node optional in 2 Formaten ausgegeben. Diesen fängt man über die Status Node ab.
Hier der Beispiel - Flow, der gleichzeitig die Timer-Node enthält:
[ { "id": "1a0828e5a33efb1e", "type": "subflow", "name": "Timer", "info": "# Timer - Countdown\r\n\r\nDieser Subflow bzw. Timer Node triggert zu einem bestimmten Zeitpunkt in der Zukunft.\r\nWird keine payload mitgegeben, triggert die Node ein `false`, anderenfalls wird nach Ablauf des Timers die payload getriggert.\r\n\r\nDer Trigger kann jederzeit mit einer `msg.reset` deaktiviert bzw. zurückgesetzt werden. Wird ein neues timer-Objekt oder date Objekt mitgegeben, so wird dies sofort übernommen und der Timer geändert.\r\n\r\nDer Status des Timers wird im Status der Node angezeigt. Dabei wird die verbleibende Zeit entweder in Textform, wie\r\n`3 Tage 3 Stunden 23 Minuten 43 Sekunden` angegeben oder im Format `1T 10:33:45` angezeigt.\r\nLetzters Format muss über den String `00:00` in der Subflow Node im Parameter `statusFormat` angegeben werden. \r\n### Fixer Timer\r\nDer Timer kann über ein festes Timer-Objekt definiert werden, der zum Zeitpunkt des Triggerns addiert wird. \r\nDas Timerobjekt muss in `msg.timer` definiert werden. \r\n\r\nDas Timerobjekt kann in verschiedenen Zeiteinheiten angegeben werden. \r\n\r\nWill man den Status im Dashboard ausgeben, dann kann man den `status.text` mit Hilfe der Status Node ausgeben.\r\n\r\n`{\r\n \"days\": 1,\r\n \"hours\": 0,\r\n \"minutes\": 1,\r\n \"seconds\": 28\r\n}`\r\n\r\nEs können auch nur einzelne Zeiteinheiten oder eine Mix angegeben werden:\r\n\r\n`{\r\n \"seconds\": 300\r\n}` oder\r\n`{\"minutes\":1,\"seconds\":90}`\r\n\r\n### Fixes Datum\r\nAlternativ zu einem fixen Timerobjekt, kann man auch ein festes Datum in Form eines **moments-Objektes** in der Eigenschaft `msg.date` mitgegeben werden.\r\nFür das lokale Datum bzw. das moments-Objekt muss bei Verwendung der Date/Time Picker des Dashboard utc.(false) mitgegeben werden. ", "category": "function", "in": [ { "x": 60, "y": 160, "wires": [ { "id": "b1979240dabd466b" } ] } ], "out": [ { "x": 1820, "y": 500, "wires": [ { "id": "14d51e8305f08b8d", "port": 0 }, { "id": "daa3497dedc3cdcb", "port": 0 } ] } ], "env": [ { "name": "statusFormat", "type": "str", "value": "00:00" } ], "meta": {}, "color": "#E6E0F8", "icon": "node-red/timer.svg", "status": { "x": 2200, "y": 160, "wires": [ { "id": "deba8660ab037921", "port": 0 } ] } }, { "id": "f6ddd0c99d7a2d0a", "type": "change", "z": "1a0828e5a33efb1e", "name": "Timer läuft ab", "rules": [ { "t": "set", "p": "sendPayload", "pt": "flow", "to": "payload", "tot": "msg" }, { "t": "set", "p": "payload", "pt": "msg", "to": "(\t $x := timer;\t $moment().add($x).format('DD.MM.YYYY HH:mm:ss');\t )", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 360, "y": 280, "wires": [ [ "293b1b773746de7a" ] ], "info": "akzeptiert Datumsformate ('DD.MM.YYYY HH:mm:ss') oder timestamps('x')" }, { "id": "72b3736e35deef67", "type": "trigger", "z": "1a0828e5a33efb1e", "name": "", "op1": "", "op2": "0", "op1type": "pay", "op2type": "str", "duration": "-1", "extend": false, "overrideDelay": false, "units": "s", "reset": "", "bytopic": "all", "topic": "topic", "outputs": 1, "x": 960, "y": 300, "wires": [ [ "b2fea3559b865565", "2d9471332357663a", "7d388c1e34c06775" ] ] }, { "id": "752809bd450b7149", "type": "comment", "z": "1a0828e5a33efb1e", "name": "Timer ausgabe", "info": "", "x": 140, "y": 60, "wires": [] }, { "id": "2d9471332357663a", "type": "switch", "z": "1a0828e5a33efb1e", "name": "Timer abgelaufen?", "property": "$moment(payload,['DD.MM.YYYY HH:mm:ss','x'],'de').isSameOrAfter($moment())", "propertyType": "jsonata", "rules": [ { "t": "false" } ], "checkall": "true", "repair": false, "outputs": 1, "x": 1230, "y": 420, "wires": [ [ "d65b789c451c2d37", "81a2e13297cc62c4" ] ] }, { "id": "d65b789c451c2d37", "type": "change", "z": "1a0828e5a33efb1e", "name": "Timer abgelaufen, dann reset", "rules": [ { "t": "set", "p": "reset", "pt": "msg", "to": "true", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 940, "y": 360, "wires": [ [ "72b3736e35deef67" ] ] }, { "id": "b2fea3559b865565", "type": "change", "z": "1a0828e5a33efb1e", "name": "timeA = payload; timeB =payload +x; diff timeB-timeA", "rules": [ { "t": "set", "p": "timeA", "pt": "msg", "to": "$moment().format('DD.MM.YYYY HH:mm:ss')", "tot": "jsonata" }, { "t": "set", "p": "timeB", "pt": "msg", "to": "$moment(payload,['DD.MM.YYYY HH:mm:ss','x'],'de').format('DD.MM.YYYY HH:mm:ss')", "tot": "jsonata" }, { "t": "set", "p": "payload", "pt": "msg", "to": "(\t $b := $moment(timeB,['DD.MM.YYYY HH:mm:ss','x'],'de');\t $a := $moment(timeA,['DD.MM.YYYY HH:mm:ss','x'],'de');\t \t /* $b.diff($a) */\t /* $moment.duration($b.diff($a)); */\t \t /* Kein Zugriff auf duration - also manuell berechnen*/\t \t $days := $b.diff($a, 'days');\t $hours := $b.diff($a, 'hours') - 24 * $b.diff($a, 'days');\t $minutes := $b.diff($a, 'minutes') - 60 * $b.diff($a, 'hours');\t $seconds := $b.diff($a, 'seconds') - 60 * $b.diff($a, 'minutes');\t \t $sec := $b.diff($a)/1000;\t \t\t \t $difference := {\t \"days\": $days,\t \"hours\":$hours,\t \"minutes\": $minutes,\t \"seconds\": $seconds\t }; \t \t\t)", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1340, "y": 260, "wires": [ [ "37327f7c4b6b9696" ] ], "info": "akzeptiert Datumsformate ('DD.MM.YYYY HH:mm:ss') oder timestamps('x')" }, { "id": "cb6b403b7eb1629e", "type": "change", "z": "1a0828e5a33efb1e", "name": "Ausgabe Timer", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "(\t $str := payload.days > 0 ? payload.days & (\t payload.days = 1 ? ' Tag ' : ' Tage ' \t ) : '';\t $str := payload.hours > 0 ? $str & payload.hours & (\t payload.hours = 1 ? ' Stunde ' : ' Stunden ' \t ) : $str & '';\t $str := payload.minutes > 0 ? $str & payload.minutes & (\t payload.minutes = 1 ? ' Minute ' : ' Minuten '\t ) : $str & '';\t $str := payload.seconds > 0 ? $str & payload.seconds & (\t payload.seconds = 1 ? ' Sekunde' : ' Sekunden'\t ) : $str & '';\t $str := (\t $str = '' or str = '-1 Sekunden'\t ) ? '---' : $str;\t $trim($str); \t)", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1920, "y": 320, "wires": [ [ "cf8e255e584ad4cb" ] ] }, { "id": "b1979240dabd466b", "type": "switch", "z": "1a0828e5a33efb1e", "name": "reset?", "property": "reset", "propertyType": "msg", "rules": [ { "t": "nnull" }, { "t": "else" } ], "checkall": "true", "repair": false, "outputs": 2, "x": 210, "y": 160, "wires": [ [ "48535d94822d97bc" ], [ "2491960236814d2b" ] ] }, { "id": "50d3265633dcd9ab", "type": "change", "z": "1a0828e5a33efb1e", "name": "", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1650, "y": 160, "wires": [ [ "deba8660ab037921" ] ] }, { "id": "81a2e13297cc62c4", "type": "change", "z": "1a0828e5a33efb1e", "name": "Timer beendet", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "sendPayload", "tot": "flow" }, { "t": "set", "p": "payload", "pt": "msg", "to": "payload ? payload : false", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1460, "y": 420, "wires": [ [ "14d51e8305f08b8d" ] ] }, { "id": "14d51e8305f08b8d", "type": "trigger", "z": "1a0828e5a33efb1e", "name": "", "op1": "", "op2": "", "op1type": "pay", "op2type": "nul", "duration": "250", "extend": true, "overrideDelay": false, "units": "ms", "reset": "", "bytopic": "all", "topic": "topic", "outputs": 1, "x": 1660, "y": 420, "wires": [ [] ] }, { "id": "37327f7c4b6b9696", "type": "switch", "z": "1a0828e5a33efb1e", "name": "statusFormat ?", "property": "statusFormat", "propertyType": "env", "rules": [ { "t": "eq", "v": "00:00", "vt": "str" }, { "t": "else" } ], "checkall": "true", "repair": false, "outputs": 2, "x": 1660, "y": 260, "wires": [ [ "eba09829a40c8e27" ], [ "cb6b403b7eb1629e" ] ] }, { "id": "eba09829a40c8e27", "type": "change", "z": "1a0828e5a33efb1e", "name": "Ausgabe Timer 00:00", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "(\t $str := payload.days > 0 ? $formatNumber(payload.days,'0T ') : '';\t $str := (payload.hours > 0 or $str != '') ? $str & $formatNumber(payload.hours,'00:') : $str & '';\t $str := $str & $formatNumber(payload.minutes, '00:');\t $str := $str & $formatNumber(payload.seconds, '00');\t $str := (\t $str = '00:00' or str = '-00:01'\t ) ? '00:00' : $str;\t $trim($str); \t)", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1900, "y": 240, "wires": [ [ "cf8e255e584ad4cb" ] ] }, { "id": "2491960236814d2b", "type": "switch", "z": "1a0828e5a33efb1e", "name": "timer?", "property": "timer", "propertyType": "msg", "rules": [ { "t": "nnull" }, { "t": "else" } ], "checkall": "true", "repair": false, "outputs": 2, "x": 170, "y": 340, "wires": [ [ "f6ddd0c99d7a2d0a" ], [ "e0d6c39117aea993" ] ] }, { "id": "e0d6c39117aea993", "type": "change", "z": "1a0828e5a33efb1e", "name": "Timer nach date läuft ab", "rules": [ { "t": "set", "p": "sendPayload", "pt": "flow", "to": "payload", "tot": "msg" }, { "t": "set", "p": "payload", "pt": "msg", "to": "$moment(date).format('DD.MM.YYYY HH:mm:ss')", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 390, "y": 480, "wires": [ [ "7ac035d9c2a79014" ] ], "info": "akzeptiert Datumsformate ('DD.MM.YYYY HH:mm:ss') oder timestamps('x')" }, { "id": "7ac035d9c2a79014", "type": "switch", "z": "1a0828e5a33efb1e", "name": "", "property": "$moment(payload,['DD.MM.YYYY HH:mm:ss','x'],'de').isSameOrAfter($moment())", "propertyType": "jsonata", "rules": [ { "t": "true" }, { "t": "false" } ], "checkall": "true", "repair": false, "outputs": 2, "x": 610, "y": 480, "wires": [ [ "293b1b773746de7a" ], [ "daa3497dedc3cdcb" ] ] }, { "id": "daa3497dedc3cdcb", "type": "change", "z": "1a0828e5a33efb1e", "name": "", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "Datum liegt in der Vergangenheit", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1230, "y": 500, "wires": [ [] ] }, { "id": "7d388c1e34c06775", "type": "trigger", "z": "1a0828e5a33efb1e", "name": "", "op1": "", "op2": "false", "op1type": "nul", "op2type": "bool", "duration": "15", "extend": true, "overrideDelay": false, "units": "s", "reset": "", "bytopic": "all", "topic": "topic", "outputs": 1, "x": 1210, "y": 200, "wires": [ [ "50d3265633dcd9ab" ] ] }, { "id": "48535d94822d97bc", "type": "junction", "z": "1a0828e5a33efb1e", "x": 660, "y": 160, "wires": [ [ "72b3736e35deef67", "50d3265633dcd9ab" ] ] }, { "id": "deba8660ab037921", "type": "junction", "z": "1a0828e5a33efb1e", "x": 2100, "y": 160, "wires": [ [] ] }, { "id": "cf8e255e584ad4cb", "type": "junction", "z": "1a0828e5a33efb1e", "x": 2040, "y": 280, "wires": [ [ "deba8660ab037921" ] ] }, { "id": "293b1b773746de7a", "type": "junction", "z": "1a0828e5a33efb1e", "x": 720, "y": 300, "wires": [ [ "72b3736e35deef67" ] ] }, { "id": "11330a0ee14c2250", "type": "subflow:1a0828e5a33efb1e", "z": "582b1bd74b95c464", "name": "", "x": 730, "y": 1380, "wires": [ [ "cf01b9c525446091" ] ] }, { "id": "cf01b9c525446091", "type": "debug", "z": "582b1bd74b95c464", "name": "payload", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 900, "y": 1380, "wires": [] }, { "id": "596a3c59f9cfe5ef", "type": "ui_text_input", "z": "582b1bd74b95c464", "name": "", "label": "", "tooltip": "", "group": "0c41d7e1dbc8ebab", "order": 2, "width": 0, "height": 0, "passthru": true, "mode": "datetime-local", "delay": 300, "topic": "topic", "sendOnBlur": true, "className": "", "topicType": "msg", "x": 250, "y": 1520, "wires": [ [ "eaa861da93d4746f" ] ] }, { "id": "eaa861da93d4746f", "type": "change", "z": "582b1bd74b95c464", "name": "bestimmtes Datum", "rules": [ { "t": "set", "p": "date", "pt": "msg", "to": "$moment(payload).utc(false)", "tot": "jsonata" }, { "t": "set", "p": "payload", "pt": "msg", "to": "$moment(payload).utc(false).format('DD.MM.YYYY HH:mm:ss')", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 490, "y": 1520, "wires": [ [ "11330a0ee14c2250", "28c295bbdbf03f14" ] ] }, { "id": "12681f73331ef1dd", "type": "ui_date_picker", "z": "582b1bd74b95c464", "name": "", "label": "date", "group": "0c41d7e1dbc8ebab", "order": 3, "width": 0, "height": 0, "passthru": true, "topic": "topic", "topicType": "msg", "className": "", "x": 290, "y": 1580, "wires": [ [ "eaa861da93d4746f" ] ] }, { "id": "84e36517a67172df", "type": "ui_dropdown", "z": "582b1bd74b95c464", "name": "", "label": "", "tooltip": "", "place": "Timer bis ... ", "group": "0c41d7e1dbc8ebab", "order": 1, "width": 0, "height": 0, "passthru": true, "multiple": false, "options": [ { "label": "zur nächsten Stunde", "value": "hour", "type": "str" }, { "label": "morgen", "value": "day", "type": "str" }, { "label": "zur nächsten Woche", "value": "week", "type": "str" }, { "label": "zum nächsten Monat", "value": "month", "type": "str" }, { "label": "Neujahr", "value": "year", "type": "str" } ], "payload": "", "topic": "topic", "topicType": "msg", "className": "", "x": 280, "y": 1460, "wires": [ [ "d58884105a8e8aee" ] ] }, { "id": "d58884105a8e8aee", "type": "change", "z": "582b1bd74b95c464", "name": "zum nächsten ...", "rules": [ { "t": "set", "p": "date", "pt": "msg", "to": "$moment().endOf($$.payload).add(1,s)", "tot": "jsonata" }, { "t": "set", "p": "payload", "pt": "msg", "to": "$moment().endOf($$.payload).add(1,s).format('DD.MM.YYYY HH:mm:ss')", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 460, "y": 1460, "wires": [ [ "11330a0ee14c2250", "28c295bbdbf03f14" ] ] }, { "id": "28c295bbdbf03f14", "type": "debug", "z": "582b1bd74b95c464", "name": "Timer zum Datum", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 850, "y": 1520, "wires": [] }, { "id": "3d06850529a56b11", "type": "inject", "z": "582b1bd74b95c464", "name": "timer: {\"minutes\":2,\"seconds\":28}", "props": [ { "p": "timer", "v": "{\"minutes\":2,\"seconds\":28}", "vt": "json" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "x": 390, "y": 1100, "wires": [ [ "40390df945ccc130" ] ] }, { "id": "6dd56547377e40b0", "type": "inject", "z": "582b1bd74b95c464", "name": "timer: {\"seconds\":300}", "props": [ { "p": "timer", "v": "{\"seconds\":300}", "vt": "json" }, { "p": "payload" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "Timer beendet", "payloadType": "str", "x": 420, "y": 1180, "wires": [ [ "40390df945ccc130" ] ] }, { "id": "f1b811c0be00b215", "type": "inject", "z": "582b1bd74b95c464", "name": "timer: {\"hours\":1,\"minutes\":1,\"seconds\":28}", "props": [ { "p": "timer", "v": "{\"hours\":1,\"minutes\":1,\"seconds\":28}", "vt": "json" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "x": 360, "y": 1060, "wires": [ [ "40390df945ccc130" ] ] }, { "id": "f0fecbfc68b61ecf", "type": "inject", "z": "582b1bd74b95c464", "name": "timer: {\"days\":1,\"hours\":0,\"minutes\":1,\"seconds\":28}", "props": [ { "p": "timer", "v": "{\"days\":1,\"hours\":0,\"minutes\":1,\"seconds\":28}", "vt": "json" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "x": 330, "y": 1020, "wires": [ [ "40390df945ccc130" ] ] }, { "id": "5ff97fe753c7cfa0", "type": "inject", "z": "582b1bd74b95c464", "name": "reset", "props": [ { "p": "reset", "v": "true", "vt": "bool" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "x": 490, "y": 1380, "wires": [ [ "11330a0ee14c2250" ] ] }, { "id": "e7dba7f27adb336c", "type": "inject", "z": "582b1bd74b95c464", "name": "timer: {\"minutes\":1,\"seconds\":90}", "props": [ { "p": "timer", "v": "{\"minutes\":1,\"seconds\":90}", "vt": "json" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "x": 390, "y": 1140, "wires": [ [ "40390df945ccc130" ] ] }, { "id": "2130cd6746d17c2e", "type": "status", "z": "582b1bd74b95c464", "name": "timer status", "scope": [ "11330a0ee14c2250" ], "x": 510, "y": 1700, "wires": [ [ "508d5d366d9d8701" ] ] }, { "id": "508d5d366d9d8701", "type": "ui_text", "z": "582b1bd74b95c464", "group": "0c41d7e1dbc8ebab", "order": 5, "width": 0, "height": 0, "name": "", "label": "verbleibend", "format": "{{msg.status.text}}", "layout": "row-spread", "className": "", "x": 730, "y": 1700, "wires": [] }, { "id": "2107680287095b4c", "type": "ui_button", "z": "582b1bd74b95c464", "name": "", "group": "0c41d7e1dbc8ebab", "order": 6, "width": 0, "height": 0, "passthru": false, "label": "Timer stop", "tooltip": "", "color": "", "bgcolor": "", "className": "", "icon": "", "payload": "true", "payloadType": "bool", "topic": "topic", "topicType": "msg", "x": 250, "y": 1340, "wires": [ [ "89702888fb7fe697" ] ] }, { "id": "89702888fb7fe697", "type": "change", "z": "582b1bd74b95c464", "name": "", "rules": [ { "t": "set", "p": "reset", "pt": "msg", "to": "true", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 460, "y": 1340, "wires": [ [ "11330a0ee14c2250" ] ] }, { "id": "411c1c8118daacdd", "type": "ui_text_input", "z": "582b1bd74b95c464", "name": "", "label": "Fixer Timer in [s]", "tooltip": "", "group": "0c41d7e1dbc8ebab", "order": 4, "width": 0, "height": 0, "passthru": true, "mode": "number", "delay": 300, "topic": "topic", "sendOnBlur": true, "className": "", "topicType": "msg", "x": 240, "y": 1300, "wires": [ [ "97f2d18036c084f7" ] ] }, { "id": "97f2d18036c084f7", "type": "change", "z": "582b1bd74b95c464", "name": "", "rules": [ { "t": "set", "p": "timer", "pt": "msg", "to": "{\"seconds\":payload}", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 460, "y": 1300, "wires": [ [ "11330a0ee14c2250" ] ] }, { "id": "40390df945ccc130", "type": "junction", "z": "582b1bd74b95c464", "x": 608.5, "y": 1117, "wires": [ [ "11330a0ee14c2250" ] ] }, { "id": "0c41d7e1dbc8ebab", "type": "ui_group", "name": "Datum und Uhrzeit", "tab": "20b3095113f94d70", "order": 2, "disp": true, "width": "6", "collapse": false, "className": "" }, { "id": "20b3095113f94d70", "type": "ui_tab", "name": "Home", "icon": "dashboard", "order": 1, "disabled": false, "hidden": false } ]
-
EDIT: 23.12.2022
Timer Node wurde angepasst, dass Status der Timer Node sich bei Inaktivität selbst löscht. (leerer String).
Falls also jemand die Node bereits importiert hat, selektiv den Subflow ersetzen:
[ { "id": "1a0828e5a33efb1e", "type": "subflow", "name": "Timer", "info": "# Timer - Countdown\r\n\r\nDieser Subflow bzw. Timer Node triggert zu einem bestimmten Zeitpunkt in der Zukunft.\r\nWird keine payload mitgegeben, triggert die Node ein `false`, anderenfalls wird nach Ablauf des Timers die payload getriggert.\r\n\r\nDer Trigger kann jederzeit mit einer `msg.reset` deaktiviert bzw. zurückgesetzt werden. Wird ein neues timer-Objekt oder date Objekt mitgegeben, so wird dies sofort übernommen und der Timer geändert.\r\n\r\nDer Status des Timers wird im Status der Node angezeigt. Dabei wird die verbleibende Zeit entweder in Textform, wie\r\n`3 Tage 3 Stunden 23 Minuten 43 Sekunden` angegeben oder im Format `1T 10:33:45` angezeigt.\r\nLetzters Format muss über den String `00:00` in der Subflow Node im Parameter `statusFormat` angegeben werden. \r\n### Fixer Timer\r\nDer Timer kann über ein festes Timer-Objekt definiert werden, der zum Zeitpunkt des Triggerns addiert wird. \r\nDas Timerobjekt muss in `msg.timer` definiert werden. \r\n\r\nDas Timerobjekt kann in verschiedenen Zeiteinheiten angegeben werden. \r\n\r\nWill man den Status im Dashboard ausgeben, dann kann man den `status.text` mit Hilfe der Status Node ausgeben.\r\n\r\n`{\r\n \"days\": 1,\r\n \"hours\": 0,\r\n \"minutes\": 1,\r\n \"seconds\": 28\r\n}`\r\n\r\nEs können auch nur einzelne Zeiteinheiten oder eine Mix angegeben werden:\r\n\r\n`{\r\n \"seconds\": 300\r\n}` oder\r\n`{\"minutes\":1,\"seconds\":90}`\r\n\r\n### Fixes Datum\r\nAlternativ zu einem fixen Timerobjekt, kann man auch ein festes Datum in Form eines **moments-Objektes** in der Eigenschaft `msg.date` mitgegeben werden.\r\nFür das lokale Datum bzw. das moments-Objekt muss bei Verwendung der Date/Time Picker des Dashboard utc.(false) mitgegeben werden. ", "category": "function", "in": [ { "x": 60, "y": 160, "wires": [ { "id": "b1979240dabd466b" } ] } ], "out": [ { "x": 1820, "y": 500, "wires": [ { "id": "14d51e8305f08b8d", "port": 0 }, { "id": "daa3497dedc3cdcb", "port": 0 } ] } ], "env": [ { "name": "statusFormat", "type": "str", "value": "00:00" } ], "meta": {}, "color": "#E6E0F8", "icon": "node-red/timer.svg", "status": { "x": 2200, "y": 160, "wires": [ { "id": "deba8660ab037921", "port": 0 } ] } }, { "id": "f6ddd0c99d7a2d0a", "type": "change", "z": "1a0828e5a33efb1e", "name": "Timer läuft ab", "rules": [ { "t": "set", "p": "sendPayload", "pt": "flow", "to": "payload", "tot": "msg" }, { "t": "set", "p": "payload", "pt": "msg", "to": "(\t $x := timer;\t $moment().add($x).format('DD.MM.YYYY HH:mm:ss');\t )", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 360, "y": 280, "wires": [ [ "293b1b773746de7a" ] ], "info": "akzeptiert Datumsformate ('DD.MM.YYYY HH:mm:ss') oder timestamps('x')" }, { "id": "72b3736e35deef67", "type": "trigger", "z": "1a0828e5a33efb1e", "name": "", "op1": "", "op2": "0", "op1type": "pay", "op2type": "str", "duration": "-1", "extend": false, "overrideDelay": false, "units": "s", "reset": "", "bytopic": "all", "topic": "topic", "outputs": 1, "x": 960, "y": 300, "wires": [ [ "b2fea3559b865565", "2d9471332357663a", "7d388c1e34c06775" ] ] }, { "id": "752809bd450b7149", "type": "comment", "z": "1a0828e5a33efb1e", "name": "Timer ausgabe", "info": "", "x": 140, "y": 60, "wires": [] }, { "id": "2d9471332357663a", "type": "switch", "z": "1a0828e5a33efb1e", "name": "Timer abgelaufen?", "property": "$moment(payload,['DD.MM.YYYY HH:mm:ss','x'],'de').isSameOrAfter($moment())", "propertyType": "jsonata", "rules": [ { "t": "false" } ], "checkall": "true", "repair": false, "outputs": 1, "x": 1230, "y": 420, "wires": [ [ "d65b789c451c2d37", "81a2e13297cc62c4" ] ] }, { "id": "d65b789c451c2d37", "type": "change", "z": "1a0828e5a33efb1e", "name": "Timer abgelaufen, dann reset", "rules": [ { "t": "set", "p": "reset", "pt": "msg", "to": "true", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 940, "y": 360, "wires": [ [ "72b3736e35deef67" ] ] }, { "id": "b2fea3559b865565", "type": "change", "z": "1a0828e5a33efb1e", "name": "timeA = payload; timeB =payload +x; diff timeB-timeA", "rules": [ { "t": "set", "p": "timeA", "pt": "msg", "to": "$moment().format('DD.MM.YYYY HH:mm:ss')", "tot": "jsonata" }, { "t": "set", "p": "timeB", "pt": "msg", "to": "$moment(payload,['DD.MM.YYYY HH:mm:ss','x'],'de').format('DD.MM.YYYY HH:mm:ss')", "tot": "jsonata" }, { "t": "set", "p": "payload", "pt": "msg", "to": "(\t $b := $moment(timeB,['DD.MM.YYYY HH:mm:ss','x'],'de');\t $a := $moment(timeA,['DD.MM.YYYY HH:mm:ss','x'],'de');\t \t /* $b.diff($a) */\t /* $moment.duration($b.diff($a)); */\t \t /* Kein Zugriff auf duration - also manuell berechnen*/\t \t $days := $b.diff($a, 'days');\t $hours := $b.diff($a, 'hours') - 24 * $b.diff($a, 'days');\t $minutes := $b.diff($a, 'minutes') - 60 * $b.diff($a, 'hours');\t $seconds := $b.diff($a, 'seconds') - 60 * $b.diff($a, 'minutes');\t \t $sec := $b.diff($a)/1000;\t \t\t \t $difference := {\t \"days\": $days,\t \"hours\":$hours,\t \"minutes\": $minutes,\t \"seconds\": $seconds\t }; \t \t\t)", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1340, "y": 260, "wires": [ [ "37327f7c4b6b9696" ] ], "info": "akzeptiert Datumsformate ('DD.MM.YYYY HH:mm:ss') oder timestamps('x')" }, { "id": "cb6b403b7eb1629e", "type": "change", "z": "1a0828e5a33efb1e", "name": "Ausgabe Timer", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "(\t $str := payload.days > 0 ? payload.days & (\t payload.days = 1 ? ' Tag ' : ' Tage ' \t ) : '';\t $str := payload.hours > 0 ? $str & payload.hours & (\t payload.hours = 1 ? ' Stunde ' : ' Stunden ' \t ) : $str & '';\t $str := payload.minutes > 0 ? $str & payload.minutes & (\t payload.minutes = 1 ? ' Minute ' : ' Minuten '\t ) : $str & '';\t $str := payload.seconds > 0 ? $str & payload.seconds & (\t payload.seconds = 1 ? ' Sekunde' : ' Sekunden'\t ) : $str & '';\t $str := (\t $str = '' or str = '-1 Sekunden'\t ) ? '---' : $str;\t $trim($str); \t)", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1920, "y": 320, "wires": [ [ "cf8e255e584ad4cb" ] ] }, { "id": "b1979240dabd466b", "type": "switch", "z": "1a0828e5a33efb1e", "name": "reset?", "property": "reset", "propertyType": "msg", "rules": [ { "t": "nnull" }, { "t": "else" } ], "checkall": "true", "repair": false, "outputs": 2, "x": 210, "y": 160, "wires": [ [ "48535d94822d97bc" ], [ "2491960236814d2b" ] ] }, { "id": "50d3265633dcd9ab", "type": "change", "z": "1a0828e5a33efb1e", "name": "", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1650, "y": 160, "wires": [ [ "deba8660ab037921" ] ] }, { "id": "81a2e13297cc62c4", "type": "change", "z": "1a0828e5a33efb1e", "name": "Timer beendet", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "sendPayload", "tot": "flow" }, { "t": "set", "p": "payload", "pt": "msg", "to": "payload ? payload : false", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1460, "y": 420, "wires": [ [ "14d51e8305f08b8d" ] ] }, { "id": "14d51e8305f08b8d", "type": "trigger", "z": "1a0828e5a33efb1e", "name": "", "op1": "", "op2": "", "op1type": "pay", "op2type": "nul", "duration": "250", "extend": true, "overrideDelay": false, "units": "ms", "reset": "", "bytopic": "all", "topic": "topic", "outputs": 1, "x": 1660, "y": 420, "wires": [ [] ] }, { "id": "37327f7c4b6b9696", "type": "switch", "z": "1a0828e5a33efb1e", "name": "statusFormat ?", "property": "statusFormat", "propertyType": "env", "rules": [ { "t": "eq", "v": "00:00", "vt": "str" }, { "t": "else" } ], "checkall": "true", "repair": false, "outputs": 2, "x": 1660, "y": 260, "wires": [ [ "eba09829a40c8e27" ], [ "cb6b403b7eb1629e" ] ] }, { "id": "eba09829a40c8e27", "type": "change", "z": "1a0828e5a33efb1e", "name": "Ausgabe Timer 00:00", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "(\t $str := payload.days > 0 ? $formatNumber(payload.days,'0T ') : '';\t $str := (payload.hours > 0 or $str != '') ? $str & $formatNumber(payload.hours,'00:') : $str & '';\t $str := $str & $formatNumber(payload.minutes, '00:');\t $str := $str & $formatNumber(payload.seconds, '00');\t $str := (\t $str = '00:00' or str = '-00:01'\t ) ? '00:00' : $str;\t $trim($str); \t)", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1900, "y": 240, "wires": [ [ "cf8e255e584ad4cb" ] ] }, { "id": "2491960236814d2b", "type": "switch", "z": "1a0828e5a33efb1e", "name": "timer?", "property": "timer", "propertyType": "msg", "rules": [ { "t": "nnull" }, { "t": "else" } ], "checkall": "true", "repair": false, "outputs": 2, "x": 170, "y": 340, "wires": [ [ "f6ddd0c99d7a2d0a" ], [ "e0d6c39117aea993" ] ] }, { "id": "e0d6c39117aea993", "type": "change", "z": "1a0828e5a33efb1e", "name": "Timer nach date läuft ab", "rules": [ { "t": "set", "p": "sendPayload", "pt": "flow", "to": "payload", "tot": "msg" }, { "t": "set", "p": "payload", "pt": "msg", "to": "$moment(date).format('DD.MM.YYYY HH:mm:ss')", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 390, "y": 480, "wires": [ [ "7ac035d9c2a79014" ] ], "info": "akzeptiert Datumsformate ('DD.MM.YYYY HH:mm:ss') oder timestamps('x')" }, { "id": "7ac035d9c2a79014", "type": "switch", "z": "1a0828e5a33efb1e", "name": "", "property": "$moment(payload,['DD.MM.YYYY HH:mm:ss','x'],'de').isSameOrAfter($moment())", "propertyType": "jsonata", "rules": [ { "t": "true" }, { "t": "false" } ], "checkall": "true", "repair": false, "outputs": 2, "x": 610, "y": 480, "wires": [ [ "293b1b773746de7a" ], [ "daa3497dedc3cdcb" ] ] }, { "id": "daa3497dedc3cdcb", "type": "change", "z": "1a0828e5a33efb1e", "name": "", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "Datum liegt in der Vergangenheit", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1230, "y": 500, "wires": [ [] ] }, { "id": "7d388c1e34c06775", "type": "trigger", "z": "1a0828e5a33efb1e", "name": "", "op1": "", "op2": "false", "op1type": "nul", "op2type": "bool", "duration": "15", "extend": true, "overrideDelay": false, "units": "s", "reset": "", "bytopic": "all", "topic": "topic", "outputs": 1, "x": 1210, "y": 200, "wires": [ [ "50d3265633dcd9ab" ] ] }, { "id": "48535d94822d97bc", "type": "junction", "z": "1a0828e5a33efb1e", "x": 660, "y": 160, "wires": [ [ "72b3736e35deef67", "50d3265633dcd9ab" ] ] }, { "id": "deba8660ab037921", "type": "junction", "z": "1a0828e5a33efb1e", "x": 2100, "y": 160, "wires": [ [] ] }, { "id": "cf8e255e584ad4cb", "type": "junction", "z": "1a0828e5a33efb1e", "x": 2040, "y": 280, "wires": [ [ "deba8660ab037921" ] ] }, { "id": "293b1b773746de7a", "type": "junction", "z": "1a0828e5a33efb1e", "x": 720, "y": 300, "wires": [ [ "72b3736e35deef67" ] ] }, { "id": "11330a0ee14c2250", "type": "subflow:1a0828e5a33efb1e", "z": "582b1bd74b95c464", "name": "", "x": 730, "y": 1380, "wires": [ [ "cf01b9c525446091" ] ] } ]