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:
Spoiler
[
{
"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"
]
]
}
]