diff --git a/CHANGELOG.md b/CHANGELOG.md index 613d19c..c74646c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,19 @@ Install of a specific Version in Redmatic (on a Homematic): This can be also used to go back to an older Version. +### 2.0.7: maintenance release + +- blind-control + clock-time + - fixed blind-control example 3 and 4; clock-time example #388 + - the function node in the example can now simulate different days for testing at the same time on different days #389 + - renamed external given time property from `.dNow` to `.now` to maintain consistency to other nodes + - nodes can be completely disables and enabled by incoming message (topic must be `enableNode` and `disableNode`) #365 + +- blind-control + - after expire of manual override with -1 force to send output #387 + - add possibility to force output to first output when topic contains `forceOutput` + - add possibility to add offset for the open/close position of the blind in active sun control #371 + ### 2.0.6: bug fixes - time-inject fix for next property #364 diff --git a/examples/blind-control/wiki-3 overrides and sun-position.json b/examples/blind-control/wiki-3 overrides and sun-position.json index 7181019..ca67500 100644 --- a/examples/blind-control/wiki-3 overrides and sun-position.json +++ b/examples/blind-control/wiki-3 overrides and sun-position.json @@ -37,11 +37,12 @@ "z": "c224c971b366d1da", "g": "f154222105f64635", "name": "30min 1sec", - "func": "\nconst minutesEachLoop = 30; // minutes to add\nconst loopCycle = 1; // seconds delay\nlet timeObj = context.get(\"timeObj\");\n\nif (timeObj && msg.topic.includes('stop')) {\n clearInterval(timeObj);\n context.set(\"timeObj\", null);\n context.set(\"orgtopic\", null);\n let d = new Date(context.get(\"date\"));\n node.log(\"STOP \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\n node.log('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ' + d.toISOString());\n node.status({fill:\"red\",shape:\"ring\",text:\"stopped - \" + d.toLocaleTimeString()});\n return null;\n} else if (!timeObj && msg.topic.includes('start')) {\n context.set(\"message\", msg);\n context.set(\"orgtopic\", msg.topic);\n let d = new Date();\n let num = Number(msg.payload);\n if (isNaN(num) && num < 24) {\n d.setHours(num);\n d.setMinutes(0);\n } else {\n let dt = new Date(msg.payload);\n if (dt instanceof Date && !isNaN(dt)) {\n d = dt;\n } else {\n d.setHours(0);\n d.setMinutes(0);\n }\n }\n context.set(\"date\", d.getTime());\n msg.tsISO = d.toISOString();\n msg.ts = d.getTime();\n msg.topic += ' ' + d.toLocaleTimeString();\n node.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');\n node.log(\"START \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\n node.send(msg);\n\n let timeObj = setInterval(function(){\n let msg = context.get(\"message\");\n let topic = context.get(\"orgtopic\");\n let d = new Date(context.get(\"date\"));\n //d.setHours(d.getHours()+1);\n let dt = d.getDate();\n let dm = d.getMonth();\n d.setMinutes(d.getMinutes() + minutesEachLoop)\n d.setDate(dt);\n d.getMonth(dm);\n context.set(\"date\", d.getTime());\n msg.tsISO = d.toISOString();\n msg.ts = d.getTime();\n msg.topic = topic + ' ' + d.toLocaleTimeString();\n node.status({fill:\"green\",shape:\"dot\",text:\"run - \" + d.toLocaleTimeString()});\n node.log(\"sending \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\n node.send(msg);\n\t}, (1000 * loopCycle));\n context.set(\"timeObj\", timeObj);\n node.status({fill:\"green\",shape:\"ring\",text:\"start - \" + d.toLocaleTimeString()});\n return null;\n}\n\nlet d = new Date(context.get(\"date\"));\nif (!(d instanceof Date) || isNaN(d)) {\n d = new Date();\n}\nd.setMinutes(d.getMinutes() + 1)\n//d.setHours(d.getHours()+1);\nmsg.tsISO = d.toISOString();\nmsg.ts = d.getTime();\nmsg.topic += ' ' + d.toLocaleTimeString();\nnode.status({fill:\"yellow\",shape:\"dot\",text:\"interposed - \" + d.toLocaleTimeString() + ' - ' + msg.payload});\nnode.log(\"sending interposed msg \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\nnode.send(msg);\nreturn null;\n", + "func": "\nconst minutesEachLoop = 20; // minutes to add\nconst loopCycle = 2; // 0.3; // seconds delay\nlet timeObj = context.get(\"timeObj\");\n\nconst days = ['sun','mon','tue','wed','thu','fri','sat'];\n\nif (timeObj && msg.topic.includes('stop')) {\n clearInterval(timeObj);\n context.set(\"timeObj\", null);\n context.set(\"orgtopic\", null);\n let d = new Date(context.get(\"date\"));\n node.log(\"STOP \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\n node.log('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ' + d.toISOString());\n node.status({fill:\"red\",shape:\"ring\",text:\"stopped - \" + d.toLocaleTimeString() + ' (' + d.getDay() + ' ' + days[d.getDay()] + ')'});\n return null;\n} else if (!timeObj && msg.topic.includes('start')) {\n context.set(\"message\", msg);\n context.set(\"orgtopic\", msg.topic);\n context.set(\"dateroll\", -1);\n let d = new Date();\n if (typeof msg.payload === 'string' && msg.payload.length > 0) {\n for (let i=0; i<7; i++) {\n\t \t if (msg.payload.includes(days[i])) {\n\t \t msg.payload = msg.payload.replace(days[i],'').trim();\n \t d.setDate(d.getDate() + (i+(7-d.getDay())) % 7);\n \t break;\n }\n }\n if (msg.payload.includes('days')) {\n d.setDate(d.getDate() + (1+(7-d.getDay())) % 7);\n msg.payload = msg.payload.replace('days','').trim();\n context.set(\"dateroll\", 1);\n }\n }\n let num = Number(msg.payload);\n if (!isNaN(num) && num < 24) {\n d.setHours(num);\n d.setMinutes(0);\n } else {\n let dt = new Date(msg.payload);\n if (dt instanceof Date && !isNaN(dt)) {\n d = dt;\n } else {\n d.setHours(0);\n d.setMinutes(0);\n }\n }\n context.set(\"date\", d.getTime());\n msg.tsISO = d.toISOString();\n msg.ts = d.getTime();\n msg.topic += ' ' + d.toLocaleTimeString();\n node.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');\n node.log(\"START \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\n node.send(msg);\n\n let timeObj = setInterval(function(){\n let msg = context.get(\"message\");\n let topic = context.get(\"orgtopic\");\n let dr = context.get(\"dateroll\");\n let d = new Date(context.get(\"date\"));\n let dt = d.getDate();\n let dm = d.getMonth();\n if (dr >0) {\n dr++;\n if (dr>8) { dr=1; }\n d.setDate(d.getDate() + (dr+(7-d.getDay())) % 7);\n context.set(\"dateroll\", dr);\n } else {\n //d.setHours(d.getHours()+1);\n d.setMinutes(d.getMinutes() + minutesEachLoop)\n d.setDate(dt);\n d.getMonth(dm);\n }\n context.set(\"date\", d.getTime());\n msg.tsISO = d.toISOString();\n msg.ts = d.getTime();\n msg.topic = topic + ' ' + d.toLocaleTimeString();\n node.status({fill:\"green\",shape:\"dot\",text:\"run - \" + d.toLocaleTimeString() + ' (' + d.getDay() + ' ' + days[d.getDay()] + ')'});\n node.log(\"sending \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\n node.send(msg);\n\t}, (1000 * loopCycle));\n context.set(\"timeObj\", timeObj);\n node.status({fill:\"green\",shape:\"ring\",text:\"start - \" + d.toLocaleTimeString() + ' (' + d.getDay() + ' ' + days[d.getDay()] + ')'});\n return null;\n}\n\nlet d = new Date(context.get(\"date\"));\nif (!(d instanceof Date) || isNaN(d)) {\n d = new Date();\n}\nd.setMinutes(d.getMinutes() + 1)\n//d.setHours(d.getHours()+1);\nmsg.tsISO = d.toISOString();\nmsg.ts = d.getTime();\nmsg.topic += ' ' + d.toLocaleTimeString();\nnode.status({fill:\"yellow\",shape:\"dot\",text:\"interposed - \" + d.toLocaleTimeString() + ' (' + d.getDay() + ' ' + days[d.getDay()] + ') - ' + msg.payload});\nnode.log(\"sending interposed msg \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\nnode.send(msg);\nreturn null;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", + "libs": [], "x": 530, "y": 580, "wires": [ diff --git a/examples/blind-control/wiki-4 usage of message properties.json b/examples/blind-control/wiki-4 usage of message properties.json index 7db42a8..2b30909 100644 --- a/examples/blind-control/wiki-4 usage of message properties.json +++ b/examples/blind-control/wiki-4 usage of message properties.json @@ -45,11 +45,12 @@ "z": "c224c971b366d1da", "g": "c76466a96ba836b1", "name": "30min 0.5sec", - "func": "\nconst minutesEachLoop = 30; // minutes to add\nconst loopCycle = 0.5; // seconds delay\nlet timeObj = context.get(\"timeObj\");\n\nif (timeObj && msg.topic.includes('stop')) {\n clearInterval(timeObj);\n context.set(\"timeObj\", null);\n context.set(\"orgtopic\", null);\n let d = new Date(context.get(\"date\"));\n node.log(\"STOP \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\n node.log('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ' + d.toISOString());\n node.status({fill:\"red\",shape:\"ring\",text:\"stopped - \" + d.toLocaleTimeString()});\n return null;\n} else if (!timeObj && msg.topic.includes('start')) {\n context.set(\"message\", msg);\n context.set(\"orgtopic\", msg.topic);\n let d = new Date();\n let num = Number(msg.payload);\n if (isNaN(num) && num < 24) {\n d.setHours(num);\n d.setMinutes(0);\n } else {\n let dt = new Date(msg.payload);\n if (dt instanceof Date && !isNaN(dt)) {\n d = dt;\n } else {\n d.setHours(0);\n d.setMinutes(0);\n }\n }\n context.set(\"date\", d.getTime());\n msg.tsISO = d.toISOString();\n msg.ts = d.getTime();\n msg.topic += ' ' + d.toLocaleTimeString();\n node.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');\n node.log(\"START \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\n node.send(msg);\n\n let timeObj = setInterval(function(){\n let msg = context.get(\"message\");\n let topic = context.get(\"orgtopic\");\n let d = new Date(context.get(\"date\"));\n //d.setHours(d.getHours()+1);\n let dt = d.getDate();\n let dm = d.getMonth();\n d.setMinutes(d.getMinutes() + minutesEachLoop)\n d.setDate(dt);\n d.getMonth(dm);\n context.set(\"date\", d.getTime());\n msg.tsISO = d.toISOString();\n msg.ts = d.getTime();\n msg.topic = topic + ' ' + d.toLocaleTimeString();\n node.status({fill:\"green\",shape:\"dot\",text:\"run - \" + d.toLocaleTimeString()});\n node.log(\"sending \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\n node.send(msg);\n\t}, (1000 * loopCycle));\n context.set(\"timeObj\", timeObj);\n node.status({fill:\"green\",shape:\"ring\",text:\"start - \" + d.toLocaleTimeString()});\n return null;\n}\n\nlet d = new Date(context.get(\"date\"));\nif (!(d instanceof Date) || isNaN(d)) {\n d = new Date();\n}\nd.setMinutes(d.getMinutes() + 1)\n//d.setHours(d.getHours()+1);\nmsg.tsISO = d.toISOString();\nmsg.ts = d.getTime();\nmsg.topic += ' ' + d.toLocaleTimeString();\nnode.status({fill:\"yellow\",shape:\"dot\",text:\"interposed - \" + d.toLocaleTimeString() + ' - ' + msg.payload});\nnode.log(\"sending interposed msg \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\nnode.send(msg);\nreturn null;\n", + "func": "\nconst minutesEachLoop = 20; // minutes to add\nconst loopCycle = 2; // 0.3; // seconds delay\nlet timeObj = context.get(\"timeObj\");\n\nconst days = ['sun','mon','tue','wed','thu','fri','sat'];\n\nif (timeObj && msg.topic.includes('stop')) {\n clearInterval(timeObj);\n context.set(\"timeObj\", null);\n context.set(\"orgtopic\", null);\n let d = new Date(context.get(\"date\"));\n node.log(\"STOP \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\n node.log('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ' + d.toISOString());\n node.status({fill:\"red\",shape:\"ring\",text:\"stopped - \" + d.toLocaleTimeString() + ' (' + d.getDay() + ' ' + days[d.getDay()] + ')'});\n return null;\n} else if (!timeObj && msg.topic.includes('start')) {\n context.set(\"message\", msg);\n context.set(\"orgtopic\", msg.topic);\n context.set(\"dateroll\", -1);\n let d = new Date();\n if (typeof msg.payload === 'string' && msg.payload.length > 0) {\n for (let i=0; i<7; i++) {\n\t \t if (msg.payload.includes(days[i])) {\n\t \t msg.payload = msg.payload.replace(days[i],'').trim();\n \t d.setDate(d.getDate() + (i+(7-d.getDay())) % 7);\n \t break;\n }\n }\n if (msg.payload.includes('days')) {\n d.setDate(d.getDate() + (1+(7-d.getDay())) % 7);\n msg.payload = msg.payload.replace('days','').trim();\n context.set(\"dateroll\", 1);\n }\n }\n let num = Number(msg.payload);\n if (!isNaN(num) && num < 24) {\n d.setHours(num);\n d.setMinutes(0);\n } else {\n let dt = new Date(msg.payload);\n if (dt instanceof Date && !isNaN(dt)) {\n d = dt;\n } else {\n d.setHours(0);\n d.setMinutes(0);\n }\n }\n context.set(\"date\", d.getTime());\n msg.tsISO = d.toISOString();\n msg.ts = d.getTime();\n msg.topic += ' ' + d.toLocaleTimeString();\n node.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');\n node.log(\"START \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\n node.send(msg);\n\n let timeObj = setInterval(function(){\n let msg = context.get(\"message\");\n let topic = context.get(\"orgtopic\");\n let dr = context.get(\"dateroll\");\n let d = new Date(context.get(\"date\"));\n let dt = d.getDate();\n let dm = d.getMonth();\n if (dr >0) {\n dr++;\n if (dr>8) { dr=1; }\n d.setDate(d.getDate() + (dr+(7-d.getDay())) % 7);\n context.set(\"dateroll\", dr);\n } else {\n //d.setHours(d.getHours()+1);\n d.setMinutes(d.getMinutes() + minutesEachLoop)\n d.setDate(dt);\n d.getMonth(dm);\n }\n context.set(\"date\", d.getTime());\n msg.tsISO = d.toISOString();\n msg.ts = d.getTime();\n msg.topic = topic + ' ' + d.toLocaleTimeString();\n node.status({fill:\"green\",shape:\"dot\",text:\"run - \" + d.toLocaleTimeString() + ' (' + d.getDay() + ' ' + days[d.getDay()] + ')'});\n node.log(\"sending \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\n node.send(msg);\n\t}, (1000 * loopCycle));\n context.set(\"timeObj\", timeObj);\n node.status({fill:\"green\",shape:\"ring\",text:\"start - \" + d.toLocaleTimeString() + ' (' + d.getDay() + ' ' + days[d.getDay()] + ')'});\n return null;\n}\n\nlet d = new Date(context.get(\"date\"));\nif (!(d instanceof Date) || isNaN(d)) {\n d = new Date();\n}\nd.setMinutes(d.getMinutes() + 1)\n//d.setHours(d.getHours()+1);\nmsg.tsISO = d.toISOString();\nmsg.ts = d.getTime();\nmsg.topic += ' ' + d.toLocaleTimeString();\nnode.status({fill:\"yellow\",shape:\"dot\",text:\"interposed - \" + d.toLocaleTimeString() + ' (' + d.getDay() + ' ' + days[d.getDay()] + ') - ' + msg.payload});\nnode.log(\"sending interposed msg \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\nnode.send(msg);\nreturn null;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", + "libs": [], "x": 530, "y": 1060, "wires": [ diff --git a/examples/clock-timer/general example of usage.json b/examples/clock-timer/general example of usage.json index 9dede70..51ea23a 100644 --- a/examples/clock-timer/general example of usage.json +++ b/examples/clock-timer/general example of usage.json @@ -38,11 +38,12 @@ "z": "c224c971b366d1da", "g": "f1d64eab81895d2b", "name": "30min 0.5sec", - "func": "\nconst minutesEachLoop = 30; // minutes to add\nconst loopCycle = 0.5; // seconds delay\nlet timeObj = context.get(\"timeObj\");\n\nif (timeObj && msg.topic.includes('stop')) {\n clearInterval(timeObj);\n context.set(\"timeObj\", null);\n context.set(\"orgtopic\", null);\n let d = new Date(context.get(\"date\"));\n node.log(\"STOP \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\n node.log('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ' + d.toISOString());\n node.status({fill:\"red\",shape:\"ring\",text:\"stopped - \" + d.toLocaleTimeString()});\n return null;\n} else if (!timeObj && msg.topic.includes('start')) {\n context.set(\"message\", msg);\n context.set(\"orgtopic\", msg.topic);\n let d = new Date();\n let num = Number(msg.payload);\n if (isNaN(num) && num < 24) {\n d.setHours(num);\n d.setMinutes(0);\n } else {\n let dt = new Date(msg.payload);\n if (dt instanceof Date && !isNaN(dt)) {\n d = dt;\n } else {\n d.setHours(0);\n d.setMinutes(0);\n }\n }\n context.set(\"date\", d.getTime());\n msg.tsISO = d.toISOString();\n msg.ts = d.getTime();\n msg.topic += ' ' + d.toLocaleTimeString();\n node.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');\n node.log(\"START \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\n node.send(msg);\n\n let timeObj = setInterval(function(){\n let msg = context.get(\"message\");\n let topic = context.get(\"orgtopic\");\n let d = new Date(context.get(\"date\"));\n //d.setHours(d.getHours()+1);\n let dt = d.getDate();\n let dm = d.getMonth();\n d.setMinutes(d.getMinutes() + minutesEachLoop)\n d.setDate(dt);\n d.getMonth(dm);\n context.set(\"date\", d.getTime());\n msg.tsISO = d.toISOString();\n msg.ts = d.getTime();\n msg.topic = topic + ' ' + d.toLocaleTimeString();\n node.status({fill:\"green\",shape:\"dot\",text:\"run - \" + d.toLocaleTimeString()});\n node.log(\"sending \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\n node.send(msg);\n\t}, (1000 * loopCycle));\n context.set(\"timeObj\", timeObj);\n node.status({fill:\"green\",shape:\"ring\",text:\"start - \" + d.toLocaleTimeString()});\n return null;\n}\n\nlet d = new Date(context.get(\"date\"));\nif (!(d instanceof Date) || isNaN(d)) {\n d = new Date();\n}\nd.setMinutes(d.getMinutes() + 1)\n//d.setHours(d.getHours()+1);\nmsg.tsISO = d.toISOString();\nmsg.ts = d.getTime();\nmsg.topic += ' ' + d.toLocaleTimeString();\nnode.status({fill:\"yellow\",shape:\"dot\",text:\"interposed - \" + d.toLocaleTimeString() + ' - ' + msg.payload});\nnode.log(\"sending interposed msg \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\nnode.send(msg);\nreturn null;\n", + "func": "\nconst minutesEachLoop = 20; // minutes to add\nconst loopCycle = 2; // 0.3; // seconds delay\nlet timeObj = context.get(\"timeObj\");\n\nconst days = ['sun','mon','tue','wed','thu','fri','sat'];\n\nif (timeObj && msg.topic.includes('stop')) {\n clearInterval(timeObj);\n context.set(\"timeObj\", null);\n context.set(\"orgtopic\", null);\n let d = new Date(context.get(\"date\"));\n node.log(\"STOP \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\n node.log('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ' + d.toISOString());\n node.status({fill:\"red\",shape:\"ring\",text:\"stopped - \" + d.toLocaleTimeString() + ' (' + d.getDay() + ' ' + days[d.getDay()] + ')'});\n return null;\n} else if (!timeObj && msg.topic.includes('start')) {\n context.set(\"message\", msg);\n context.set(\"orgtopic\", msg.topic);\n context.set(\"dateroll\", -1);\n let d = new Date();\n if (typeof msg.payload === 'string' && msg.payload.length > 0) {\n for (let i=0; i<7; i++) {\n\t \t if (msg.payload.includes(days[i])) {\n\t \t msg.payload = msg.payload.replace(days[i],'').trim();\n \t d.setDate(d.getDate() + (i+(7-d.getDay())) % 7);\n \t break;\n }\n }\n if (msg.payload.includes('days')) {\n d.setDate(d.getDate() + (1+(7-d.getDay())) % 7);\n msg.payload = msg.payload.replace('days','').trim();\n context.set(\"dateroll\", 1);\n }\n }\n let num = Number(msg.payload);\n if (!isNaN(num) && num < 24) {\n d.setHours(num);\n d.setMinutes(0);\n } else {\n let dt = new Date(msg.payload);\n if (dt instanceof Date && !isNaN(dt)) {\n d = dt;\n } else {\n d.setHours(0);\n d.setMinutes(0);\n }\n }\n context.set(\"date\", d.getTime());\n msg.tsISO = d.toISOString();\n msg.ts = d.getTime();\n msg.topic += ' ' + d.toLocaleTimeString();\n node.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');\n node.log(\"START \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\n node.send(msg);\n\n let timeObj = setInterval(function(){\n let msg = context.get(\"message\");\n let topic = context.get(\"orgtopic\");\n let dr = context.get(\"dateroll\");\n let d = new Date(context.get(\"date\"));\n let dt = d.getDate();\n let dm = d.getMonth();\n if (dr >0) {\n dr++;\n if (dr>8) { dr=1; }\n d.setDate(d.getDate() + (dr+(7-d.getDay())) % 7);\n context.set(\"dateroll\", dr);\n } else {\n //d.setHours(d.getHours()+1);\n d.setMinutes(d.getMinutes() + minutesEachLoop)\n d.setDate(dt);\n d.getMonth(dm);\n }\n context.set(\"date\", d.getTime());\n msg.tsISO = d.toISOString();\n msg.ts = d.getTime();\n msg.topic = topic + ' ' + d.toLocaleTimeString();\n node.status({fill:\"green\",shape:\"dot\",text:\"run - \" + d.toLocaleTimeString() + ' (' + d.getDay() + ' ' + days[d.getDay()] + ')'});\n node.log(\"sending \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\n node.send(msg);\n\t}, (1000 * loopCycle));\n context.set(\"timeObj\", timeObj);\n node.status({fill:\"green\",shape:\"ring\",text:\"start - \" + d.toLocaleTimeString() + ' (' + d.getDay() + ' ' + days[d.getDay()] + ')'});\n return null;\n}\n\nlet d = new Date(context.get(\"date\"));\nif (!(d instanceof Date) || isNaN(d)) {\n d = new Date();\n}\nd.setMinutes(d.getMinutes() + 1)\n//d.setHours(d.getHours()+1);\nmsg.tsISO = d.toISOString();\nmsg.ts = d.getTime();\nmsg.topic += ' ' + d.toLocaleTimeString();\nnode.status({fill:\"yellow\",shape:\"dot\",text:\"interposed - \" + d.toLocaleTimeString() + ' (' + d.getDay() + ' ' + days[d.getDay()] + ') - ' + msg.payload});\nnode.log(\"sending interposed msg \" + d.toLocaleTimeString() + ' ####################################### payload='+msg.payload+' topic='+msg.topic);\nnode.send(msg);\nreturn null;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", + "libs": [], "x": 550, "y": 2520, "wires": [ @@ -394,7 +395,6 @@ "autoTrigger": true, "autoTriggerTime": 1200000, "startDelayTime": 10000, - "storeName": "", "results": [ { "p": "", diff --git a/nodes/blind-control.html b/nodes/blind-control.html index 33c5418..0d8b698 100644 --- a/nodes/blind-control.html +++ b/nodes/blind-control.html @@ -244,6 +244,34 @@ blindPosMaxType: { value: 'levelFixed' }, + blindOpenPosOffset: { + value: 0.00, + required: false, + validate(v) { + if (typeof v === 'undefined' || v === '') return true; + const n = parseFloat(v); + const mm = getMinMaxBlindPos(this); + return n === 0.00 || + (RED.validators.number()(v) && + (Number.isInteger(n / parseFloat(getVal(this, 'blindIncrement')))) && + (n < mm.max) && + (n > mm.min)); + } + }, + blindClosedPosOffset: { + value: 0.00, + required: false, + validate(v) { + if (typeof v === 'undefined' || v === '') return true; + const n = parseFloat(v); + const mm = getMinMaxBlindPos(this); + return n === 0.00 || + (RED.validators.number()(v) && + (Number.isInteger(n / parseFloat(getVal(this, 'blindIncrement')))) && + (n < mm.max) && + (n > mm.min)); + } + }, sunSlat: { value: '', validate: RED.validators.typedInput('sunSlatType') @@ -3777,16 +3805,6 @@ -
- - - - -
@@ -3813,6 +3831,32 @@
+
+ +
+ +
+
+ + + + +
+
+ +
+
+ + +
+
+ + +