node-red-contrib-sun-position
Advanced tools
Comparing version 2.0.6 to 2.1.1
@@ -0,0 +0,0 @@ --- |
@@ -17,3 +17,54 @@ # node-red-contrib-sun-position | ||
This can be also used to go back to an older Version. | ||
### 2.1.1: bug fixes | ||
- clock-timer | ||
- merged with blind-control | ||
### 2.1.0: bug fixes | ||
- blind-control | ||
- fix bug of handling not time constrained rules be first to last evaluated | ||
### 2.0.13: bug fixes | ||
- general | ||
- Fixed bug with string with placeholder, if value is 0 it was replaced with an empty string #400 | ||
### 2.0.12: bug fixes | ||
- general | ||
- Fixed bug with wrong default values for Input type in blind-control and within-time-switch node, added console error in case it occurs again. | ||
- additional check for missing position configuration | ||
### 2.0.10: maintenance release | ||
- rerelease, no changed | ||
### 2.0.9: maintenance release | ||
- general | ||
- code cleanup | ||
- added string with placeholder as property value for more nodes (time-input, time comp, within-time, time-compare) | ||
- clock-timer | ||
- `isDisabled` now stored to context as already implemented in blind-control | ||
### 2.0.8: bug fixes | ||
- general, but only used in blind-control + clock-time | ||
- added node.path (Node-Red 2.2) as possible output configuration, fallback to node.name or node.id if not defined | ||
- fixed string with placeholder output (string could not be entered) | ||
### 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 | ||
@@ -20,0 +71,0 @@ |
@@ -0,0 +0,0 @@ [ |
@@ -0,0 +0,0 @@ [ |
@@ -40,3 +40,3 @@ [ | ||
"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, | ||
@@ -46,2 +46,3 @@ "noerr": 0, | ||
"finalize": "", | ||
"libs": [], | ||
"x": 530, | ||
@@ -48,0 +49,0 @@ "y": 580, |
@@ -48,3 +48,3 @@ [ | ||
"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, | ||
@@ -54,2 +54,3 @@ "noerr": 0, | ||
"finalize": "", | ||
"libs": [], | ||
"x": 530, | ||
@@ -56,0 +57,0 @@ "y": 1060, |
@@ -41,3 +41,3 @@ [ | ||
"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, | ||
@@ -47,2 +47,3 @@ "noerr": 0, | ||
"finalize": "", | ||
"libs": [], | ||
"x": 550, | ||
@@ -399,3 +400,2 @@ "y": 2520, | ||
"startDelayTime": 10000, | ||
"storeName": "", | ||
"results": [ | ||
@@ -402,0 +402,0 @@ { |
@@ -0,0 +0,0 @@ [ |
@@ -0,0 +0,0 @@ [ |
@@ -0,0 +0,0 @@ [ |
@@ -0,1 +1,23 @@ | ||
/* | ||
* This code is licensed under the Apache License Version 2.0. | ||
* | ||
* Copyright (c) 2022 Robert Gester | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions | ||
* are met: | ||
* | ||
* 1. Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* | ||
* 2. Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* | ||
* 3. Neither the name of the copyright holder nor the names of its | ||
* contributors may be used to endorse or promote products derived from | ||
* this software without specific prior written permission. | ||
* | ||
*/ | ||
/******************************************** | ||
@@ -96,3 +118,3 @@ * clock-timer: | ||
if (Number.isFinite(nExpire) || (nImportance <= 0)) { | ||
// will set expiring if importance is 0 or if expire is explizit defined | ||
// will set expiring if importance is 0 or if expire is explicit defined | ||
node.debug(`set expiring - expire is explicit defined "${nExpire}"`); | ||
@@ -137,3 +159,3 @@ ctrlLib.setExpiringOverwrite(node, oNow, nExpire, 'set expiring time by message'); | ||
function changeRules(node, rulePos, ruleName, ruleData) { | ||
node.debug(`changeRules: ${ node.rules.count } ruleData:' ${util.inspect(ruleData, {colors:true, compact:10})}`); | ||
// node.debug(`changeRules: ${ node.rules.count } ruleData:' ${util.inspect(ruleData, {colors:true, compact:10})}`); | ||
for (let i = 0; i <= node.rules.count; ++i) { | ||
@@ -159,3 +181,3 @@ const rule = node.rules[i]; | ||
const livingRuleData = {}; | ||
ctrlLib.prepareRules(node, msg, tempData, oNow.dNow); | ||
ctrlLib.prepareRules(node, msg, tempData, oNow.now); | ||
// node.debug(`checkRules rules.count=${node.rules.count}, rules.lastUntil=${node.rules.lastUntil}, oNow=${util.inspect(oNow, {colors:true, compact:10})}`); | ||
@@ -172,15 +194,8 @@ | ||
// const res = fktCheck(rule, r => (r >= nowNr)); | ||
let res = null; | ||
if (!rule.time || rule.time.operator === cRuleFrom) { | ||
res = ctrlLib.compareRules(node, msg, rule, r => (r <= oNow.nowNr), oNow); | ||
} else { | ||
res = ctrlLib.compareRules(node, msg, rule, r => (r >= oNow.nowNr), oNow); | ||
} | ||
const res = ctrlLib.compareRules(node, msg, rule, r => (r >= oNow.nowNr), oNow); | ||
if (res) { | ||
// node.debug('1. ruleSel ' + util.inspect(res, { colors: true, compact: 10, breakLength: Infinity })); | ||
// node.debug(`1. ruleSel ${rule.name} (${rule.pos}) data=${ util.inspect(res, { colors: true, compact: 10, breakLength: Infinity }) }`); | ||
ruleSel = res; | ||
ruleindex = i; | ||
if (rule.time && rule.time.operator !== cRuleFrom) { | ||
break; | ||
} | ||
break; | ||
} | ||
@@ -193,3 +208,3 @@ } | ||
const rule = node.rules.data[i]; | ||
// node.debug('rule ' + rule.time.operator + ' - ' + (rule.time.operator !== cRuleUntil) + ' - ' + util.inspect(rule, {colors:true, compact:10, breakLength: Infinity })); | ||
// node.debug(`rule ${rule.name} (${rule.pos}) enabled=${rule.enabled} operator=${rule.time.operator} noUntil=${rule.time.operator !== cRuleUntil} data=${util.inspect(rule, {colors:true, compact:10, breakLength: Infinity })}`); | ||
if (!rule.enabled) { continue; } | ||
@@ -199,3 +214,3 @@ if (rule.time && rule.time.operator === cRuleUntil) { continue; } // - From: timeOp === cRuleFrom | ||
if (res) { | ||
// node.debug('2. ruleSel ' + util.inspect(res, { colors: true, compact: 10, breakLength: Infinity })); | ||
// node.debug(`2. ruleSel ${rule.name} (${rule.pos}) data=${ util.inspect(res, { colors: true, compact: 10, breakLength: Infinity }) }`); | ||
ruleSel = res; | ||
@@ -264,3 +279,3 @@ break; | ||
} | ||
if (ruleSel.time) { | ||
if (ruleSel.time && ruleSel.timeData) { | ||
livingRuleData.time = ruleSel.timeData; | ||
@@ -322,2 +337,10 @@ livingRuleData.time.timeLocal = node.positionConfig.toTimeString(ruleSel.timeData.value); | ||
const node = this; | ||
if (!this.positionConfig) { | ||
node.status({ | ||
fill: 'red', | ||
shape: 'dot', | ||
text: 'Node not properly configured!!' | ||
}); | ||
return; | ||
} | ||
@@ -360,2 +383,3 @@ if (!Array.isArray(config.results)) { | ||
node.nodeData = { | ||
isDisabled: node.context().get('isDisabled', node.contextStore) || false, | ||
/** The Level of the window */ | ||
@@ -440,3 +464,6 @@ payloadDefault: config.payloadDefault, | ||
// allow to overwrite settings by incomming message | ||
if (msg.topic && (typeof msg.topic === 'string') && msg.topic.startsWith('set')) { | ||
if (msg.topic && (typeof msg.topic === 'string') && | ||
(msg.topic.startsWith('set') || | ||
msg.topic.startsWith('disable') || | ||
msg.topic.startsWith('enable'))) { | ||
switch (msg.topic) { | ||
@@ -451,3 +478,3 @@ /* Default Settings */ | ||
break; | ||
case 'setCntextStore': | ||
case 'setContextStore': | ||
node.contextStore = msg.payload || node.contextStore; | ||
@@ -467,2 +494,15 @@ break; | ||
break; | ||
case 'enableNode': | ||
node.nodeData.isDisabled = false; | ||
node.context().set('isDisabled', false, node.contextStore); | ||
break; | ||
case 'disableNode': | ||
node.nodeData.isDisabled = true; | ||
node.context().set('isDisabled', true, node.contextStore); | ||
node.status({ | ||
fill: 'grey', | ||
shape: 'dot', | ||
text: (typeof msg.payload === 'string') ? msg.payload : 'disabled' | ||
}); | ||
break; | ||
default: | ||
@@ -472,2 +512,6 @@ break; | ||
} | ||
if (node.nodeData.isDisabled) { | ||
done(); | ||
return null; | ||
} | ||
@@ -499,3 +543,3 @@ // initialize | ||
} | ||
}, true, oNow.dNow); | ||
}, true, oNow.now); | ||
} | ||
@@ -508,3 +552,5 @@ const timeCtrl = { | ||
name: node.name || node.id, | ||
id: node.addId || node.id | ||
id: node.addId || node.id, | ||
srcId: node.id, | ||
path: node._path || node.id | ||
}; | ||
@@ -524,2 +570,3 @@ | ||
if (overwrite && timeCtrl.rule.resetOverwrite && timeCtrl.rule.id !== previousData.usedRule) { | ||
node.debug(`Overwrite expired caused by rule rule=${timeCtrl.rule.id}, previousRule=${previousData.usedRule}`); | ||
ctrlLib.posOverwriteReset(node); | ||
@@ -532,3 +579,3 @@ overwrite = false; | ||
if (timeCtrl.rule.payloadData) { | ||
node.payload.current = node.positionConfig.getOutDataProp(node, msg, timeCtrl.rule.payloadData, oNow.dNow); | ||
node.payload.current = node.positionConfig.getOutDataProp(node, msg, timeCtrl.rule.payloadData, oNow.now); | ||
} | ||
@@ -554,2 +601,4 @@ node.payload.topic = timeCtrl.rule.topic; | ||
id: timeCtrl.id, | ||
srcId: timeCtrl.srcId, | ||
path: timeCtrl.path, | ||
code: node.reason.code, | ||
@@ -585,3 +634,3 @@ state: node.reason.state, | ||
} else { | ||
resultObj = node.positionConfig.getPropValue(this, msg, prop, false, oNow.dNow); | ||
resultObj = node.positionConfig.getPropValue(this, msg, prop, false, oNow.now); | ||
} | ||
@@ -588,0 +637,0 @@ if (typeof resultObj !== 'undefined') { |
@@ -5,2 +5,4 @@ /* | ||
https://github.com/mourner/suncalc | ||
Reworked and enhanced by Robert Gester | ||
*/ | ||
@@ -7,0 +9,0 @@ 'use strict'; |
@@ -0,1 +1,23 @@ | ||
/* | ||
* This code is licensed under the Apache License Version 2.0. | ||
* | ||
* Copyright (c) 2022 Robert Gester | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions | ||
* are met: | ||
* | ||
* 1. Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* | ||
* 2. Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* | ||
* 3. Neither the name of the copyright holder nor the names of its | ||
* contributors may be used to endorse or promote products derived from | ||
* this software without specific prior written permission. | ||
* | ||
*/ | ||
/******************************************** | ||
@@ -260,3 +282,3 @@ * dateTimeHelper.js: | ||
function getRuleTimeData(node, msg, rule, dNow) { | ||
rule.time.dNow = dNow; | ||
rule.time.now = dNow; | ||
rule.timeData = node.positionConfig.getTimeProp(node, msg, rule.time); | ||
@@ -271,5 +293,6 @@ if (rule.timeData.error) { | ||
rule.timeData.ts = rule.timeData.value.getTime(); | ||
// node.debug(`time=${rule.timeData.value} -> ${new Date(rule.timeData.value)}`); | ||
rule.timeData.dayId = hlp.getDayId(rule.timeData.value); | ||
if (rule.timeMin) { | ||
rule.timeMin.dNow = dNow; | ||
rule.timeMin.now = dNow; | ||
rule.timeDataMin = node.positionConfig.getTimeProp(node, msg, rule.timeMin); | ||
@@ -284,5 +307,3 @@ const numMin = rule.timeDataMin.value.getTime(); | ||
if (numMin > rule.timeData.ts) { | ||
const tmp = rule.timeData; | ||
rule.timeData = rule.timeDataMin; | ||
rule.timeDataMin = tmp; | ||
[rule.timeData, rule.timeDataMin] = [rule.timeDataMin, rule.timeData]; | ||
rule.timeData.ts = numMin; | ||
@@ -294,3 +315,3 @@ rule.timeData.dayId = hlp.getDayId(rule.timeDataMin.value); | ||
if (rule.timeMax) { | ||
rule.timeMax.dNow = dNow; | ||
rule.timeMax.now = dNow; | ||
rule.timeDataMax = node.positionConfig.getTimeProp(node, msg, rule.timeMax); | ||
@@ -305,5 +326,3 @@ const numMax = rule.timeDataMax.value.getTime(); | ||
if (numMax < rule.timeData.ts) { | ||
const tmp = rule.timeData; | ||
rule.timeData = rule.timeDataMax; | ||
rule.timeDataMax = tmp; | ||
[rule.timeData, rule.timeDataMax] = [rule.timeDataMax, rule.timeData]; | ||
rule.timeData.ts = numMax; | ||
@@ -329,3 +348,3 @@ rule.timeData.dayId = hlp.getDayId(rule.timeDataMax.value); | ||
* @name ITimeObject Data | ||
* @param {Date} dNow | ||
* @param {Date} now | ||
* @param {number} nowNr | ||
@@ -349,6 +368,7 @@ * @param {number} dayNr | ||
function compareRules(node, msg, rule, cmp, data) { | ||
// node.debug('fktCheck rule ' + util.inspect(rule, {colors:true, compact:10})); | ||
// node.debug(`compareRules rule ${rule.name} (${rule.pos}) data=${util.inspect(rule, {colors:true, compact:10})}`); | ||
if (rule.conditional) { | ||
try { | ||
if (!rule.conditon.result) { | ||
node.debug(`compareRules rule ${rule.name} (${rule.pos}) conditon does not match`); | ||
return null; | ||
@@ -365,18 +385,25 @@ } | ||
} | ||
if (rule.time.days && !rule.time.days.includes(data.dayNr)) { | ||
node.debug(`compareRules rule ${rule.name} (${rule.pos}) invalid days`); | ||
return null; | ||
} | ||
if (rule.time.months && !rule.time.months.includes(data.monthNr)) { | ||
node.debug(`compareRules rule ${rule.name} (${rule.pos}) invalid month`); | ||
return null; | ||
} | ||
if (rule.time.onlyOddDays && (data.dateNr % 2 === 0)) { // even | ||
node.debug(`compareRules rule ${rule.name} (${rule.pos}) invalid even days`); | ||
return null; | ||
} | ||
if (rule.time.onlyEvenDays && (data.dateNr % 2 !== 0)) { // odd | ||
node.debug(`compareRules rule ${rule.name} (${rule.pos}) invalid odd days`); | ||
return null; | ||
} | ||
if (rule.time.onlyOddWeeks && (data.weekNr % 2 === 0)) { // even | ||
node.debug(`compareRules rule ${rule.name} (${rule.pos}) invalid even week`); | ||
return null; | ||
} | ||
if (rule.time.onlyEvenWeeks && (data.weekNr % 2 !== 0)) { // odd | ||
node.debug(`compareRules rule ${rule.name} (${rule.pos}) invalid odd week`); | ||
return null; | ||
@@ -389,3 +416,4 @@ } | ||
// in the current year | ||
if (data.dNow < rule.time.dateStart || data.dNow > rule.time.dateEnd) { | ||
if (data.now < rule.time.dateStart || data.now > rule.time.dateEnd) { | ||
node.debug(`compareRules rule ${rule.name} (${rule.pos}) invalid date range within year`); | ||
return null; | ||
@@ -395,3 +423,4 @@ } | ||
// switch between year from end to start | ||
if (data.dNow < rule.time.dateStart && data.dNow > rule.time.dateEnd) { | ||
if (data.now < rule.time.dateStart && data.now > rule.time.dateEnd) { | ||
node.debug(`compareRules rule ${rule.name} (${rule.pos}) invalid date range over year`); | ||
return null; | ||
@@ -401,7 +430,8 @@ } | ||
} | ||
const num = getRuleTimeData(node, msg, rule, data.dNow); | ||
// node.debug(`pos=${rule.pos} type=${rule.time.operatorText} - ${rule.time.value} - num=${num} - rule.timeData = ${ util.inspect(rule.timeData, { colors: true, compact: 40, breakLength: Infinity }) }`); | ||
const num = getRuleTimeData(node, msg, rule, data.now); | ||
// node.debug(`compareRules ${rule.name} (${rule.pos}) type=${rule.time.operatorText} - ${rule.time.value} - num=${num} - rule.timeData = ${ util.inspect(rule.timeData, { colors: true, compact: 40, breakLength: Infinity }) }`); | ||
if (data.dayId === rule.timeData.dayId && num >=0 && (cmp(num) === true)) { | ||
return rule; | ||
} | ||
// node.debug(`compareRules rule ${rule.name} (${rule.pos}) dayId=${data.dayId} rule-DayID=${rule.timeData.dayId} num=${num} cmp=${cmp(num)} invalid time`); | ||
return null; | ||
@@ -461,3 +491,3 @@ } | ||
function initializeCtrl(REDLib, node, config) { | ||
node.debug(`initialize ${ node.name || node.id}`); | ||
node.debug(`initialize ${ node.name || node._path || node.id}`); | ||
RED = REDLib; | ||
@@ -464,0 +494,0 @@ |
@@ -14,2 +14,4 @@ { | ||
"blindClosedPos": "Rollladen geschlossen (min)", | ||
"blindOpenPosOffset": "Rollladen offen offset", | ||
"blindClosedPosOffset": "Rollladen geschlossen offset", | ||
"blindLevelDefault": "Standard Rollladenposition", | ||
@@ -62,2 +64,4 @@ "slatPosDefault": "Standard Lamellenposition", | ||
"blindClosedPos": "0", | ||
"blindOpenPosOffset": "offset für die Position geöffnet", | ||
"blindClosedPosOffset": "offset für die Position geschlossen", | ||
"blindLevelDefault": "Rollladenposition, wenn keine andere zutrifft", | ||
@@ -64,0 +68,0 @@ "slatPosDefault": "Lamellenposition, wenn keine andere zutrifft", |
@@ -0,0 +0,0 @@ { |
@@ -44,2 +44,3 @@ { | ||
"nodeName":"Node ID", | ||
"nodePath":"Node Pfad", | ||
"timeentered": "Uhrzeit (nächste)", | ||
@@ -443,2 +444,4 @@ "dateentered": "Datum (spezieller Zeitpunkt)", | ||
"oversteer": "erlaubt das Übersteuern der Position in Abhängigkeit von der Sonne unter definierten Bedingungen wie Sonnenwinkel oder Wetter (z. B. Wolkenhimmel, Beleuchtung, etc.). Hiermit kann auch eine minimale oder maximaler Höhenwinkel definiert werden, wenn Berge/Gebäude, etc das Fenster verdecken.", | ||
"sunAdvanced": "Erweiterte Einstellungen für die Sonnensteuerung", | ||
"blindPosOffset": "Wenn der Fensterbereich kleiner als der Rollladen öffnen/schließenBereichs entspricht, weil ein breiter Fensterrahmen vorhanden ist oder verzögerte öffnen/schließen vorliegt (durch beispielsweise Schlitze welche sich erst Öffnen/schließen müssen), kann hier ein Offset dafür eingestellt werden.", | ||
"sunControlMaximization": "<ul><li>Wenn keine Regel oder Überschreiben (Override) zutrifft,<ul><li>Wenn die Sonne <em>nicht</ em> in das Fenster scheint, wird die Rollladenhöhe die definierte <strong>Minimalposition</ strong> gesetzt. (Übersteuern wird ignoriert)</ li><li>Wenn sich die Sonne im Fenster befindet</ li><li>Wenn eine Übersteueruzng aufgesetzt ist und die bedingung zutrifft, wird der Behang auf die Höhe des Übersteuerns gesetzt.< / li><li>Andernfalls wird die Behanghöhe auf die definierte <strong>Maximalposition</ strong> gesetzt.</ li></ ul></ li></ ul>", | ||
@@ -445,0 +448,0 @@ "sunControlMinimization": "<ul><li>Wenn keine Regel oder Überschreiben (Override) zutrifft,<ul><li>Wenn die Sonne <em>nicht</ em> in das Fenster scheint, wird die Rollladenhöhe die definierte <strong>Maximalposition</ strong> gesetzt. (Übersteuern wird ignoriert)</ li><li>Wenn sich die Sonne im Fenster befindet</ li><li>Wenn eine Übersteueruzng aufgesetzt ist und die bedingung zutrifft, wird der Behang auf die Höhe des Übersteuerns gesetzt.< / li><li>Andernfalls wird die Behanghöhe auf die definierte <strong>Minimalposition</ strong> gesetzt.</ li></ ul></ li></ ul>", |
@@ -0,0 +0,0 @@ { |
@@ -0,0 +0,0 @@ { |
@@ -0,0 +0,0 @@ { |
@@ -14,2 +14,4 @@ { | ||
"blindClosedPos": "closed position (min)", | ||
"blindOpenPosOffset": "open position offset", | ||
"blindClosedPosOffset": "closed position offset", | ||
"blindLevelDefault": "default position", | ||
@@ -62,2 +64,4 @@ "slatPosDefault": "default slat", | ||
"blindClosedPos": "0", | ||
"blindOpenPosOffset": "offset for the open position", | ||
"blindClosedPosOffset": "offset for the closed position", | ||
"blindLevelDefault": "blind position if no other used", | ||
@@ -130,5 +134,7 @@ "slatPosDefault": "slat position if no other used", | ||
"getBlindPosData": "error getting blind level: __message__", | ||
"smoothTimeToolong": "The selected smooth is too long!!" | ||
"smoothTimeToolong": "The selected smooth is too long!!", | ||
"invalidOpenPosOffset":"Invalid value for blind open position offset for the sun control!", | ||
"invalidClosedPosOffset":"Invalid value for blind closed position offset for the sun control!" | ||
} | ||
} | ||
} |
@@ -0,0 +0,0 @@ { |
@@ -0,0 +0,0 @@ { |
@@ -44,2 +44,3 @@ { | ||
"nodeName":"node ID", | ||
"nodePath":"node path", | ||
"timeentered":"time (next)", | ||
@@ -458,2 +459,4 @@ "dateentered":"date", | ||
"oversteer": "allows to oversteer the position depending on the sun under defined condition such as elevation, weather (for example sky covered by clouds, lighting, ...) This can also be used to define a minimum or maximum elevation angle if mountains / buildings, etc. cover the window.", | ||
"sunAdvanced": "advanced settigns for sun control", | ||
"blindPosOffset": "If the window free space does not match the blind open and closed position, here can be defined an offset to this. Example for this is a wide window frame or a delay in opening the blind caused by open/close the slits between the slats.", | ||
"sunControlMaximization": "<ul><li>If no rule or override matches<ul><li>If the sun is <em>not</em> in the window the blind will set to defined <strong>minimum position</strong>. (oversteer will be ignored)</li><li>If the sun is in the window</li><li>If any oversteer data are setup and oversteer conditions are fulfilled the blind will set to the defined oversteer blind position.</li><li>otherwise the blind level is set to defined <strong>maximum position</strong>.</li></ul></li></ul>", | ||
@@ -460,0 +463,0 @@ "sunControlMinimization": "<ul><li>If no rule or override matches<ul><li>If the sun is <em>not</em> in the window the blind will set to defined <strong>maximum position</strong>. (oversteer will be ignored)</li><li>If the sun is in the window</li><li>If any oversteer data are setup and oversteer conditions are fulfilled the blind will set to the defined oversteer blind position.</li><li>otherwise the blind level is set to defined <strong>minimum position</strong>.</li></ul></li></ul>", |
@@ -0,0 +0,0 @@ { |
@@ -0,0 +0,0 @@ { |
@@ -0,0 +0,0 @@ { |
@@ -0,0 +0,0 @@ { |
@@ -0,0 +0,0 @@ { |
@@ -0,1 +1,23 @@ | ||
/* | ||
* This code is licensed under the Apache License Version 2.0. | ||
* | ||
* Copyright (c) 2022 Robert Gester | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions | ||
* are met: | ||
* | ||
* 1. Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* | ||
* 2. Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* | ||
* 3. Neither the name of the copyright holder nor the names of its | ||
* contributors may be used to endorse or promote products derived from | ||
* this software without specific prior written permission. | ||
* | ||
*/ | ||
/******************************************** | ||
@@ -24,2 +46,10 @@ * moon-position: | ||
const node = this; | ||
if (!this.positionConfig) { | ||
node.status({ | ||
fill: 'red', | ||
shape: 'dot', | ||
text: 'Node not properly configured!!' | ||
}); | ||
return; | ||
} | ||
@@ -26,0 +56,0 @@ this.on('input', function (msg, send, done) { |
@@ -0,1 +1,23 @@ | ||
/* | ||
* This code is licensed under the Apache License Version 2.0. | ||
* | ||
* Copyright (c) 2022 Robert Gester | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions | ||
* are met: | ||
* | ||
* 1. Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* | ||
* 2. Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* | ||
* 3. Neither the name of the copyright holder nor the names of its | ||
* contributors may be used to endorse or promote products derived from | ||
* this software without specific prior written permission. | ||
* | ||
*/ | ||
/************************************************************************/ | ||
@@ -228,3 +250,4 @@ /** | ||
label: node._('node-red-contrib-sun-position/position-config:common.types.strPlaceholder'), | ||
hasValue: false | ||
icon: 'icons/node-red-contrib-sun-position/inputTypeStrPlaceholder.svg', | ||
hasValue: true | ||
}, | ||
@@ -248,2 +271,7 @@ numPercent: { | ||
}, | ||
nodePath: { | ||
value: 'nodePath', | ||
label: node._('node-red-contrib-sun-position/position-config:common.types.nodePath','node name'), | ||
hasValue: false | ||
}, | ||
TimeEntered: { | ||
@@ -870,2 +898,7 @@ value: 'entered', | ||
} | ||
if (Array.isArray(data.types) && !data.types.find(el => (el === type || el.value === type))) { | ||
console.error(`unknown typeInput type: ${data.typeProp} = '${type}', using default '${data.defaultType}' allowed types=`,data.types); // eslint-disable-line no-console | ||
type = data.defaultType; | ||
$typeField.val(type); | ||
} | ||
if (typeof node[data.valueProp] === 'undefined' || node[data.valueProp] === null) { | ||
@@ -872,0 +905,0 @@ if (typeof data.defaultValue !== 'undefined') { |
@@ -0,1 +1,23 @@ | ||
/* | ||
* This code is licensed under the Apache License Version 2.0. | ||
* | ||
* Copyright (c) 2022 Robert Gester | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions | ||
* are met: | ||
* | ||
* 1. Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* | ||
* 2. Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* | ||
* 3. Neither the name of the copyright holder nor the names of its | ||
* contributors may be used to endorse or promote products derived from | ||
* this software without specific prior written permission. | ||
* | ||
*/ | ||
/******************************************** | ||
@@ -33,2 +55,10 @@ * sun-position: | ||
const node = this; | ||
if (!this.positionConfig) { | ||
node.status({ | ||
fill: 'red', | ||
shape: 'dot', | ||
text: 'Node not properly configured!!' | ||
}); | ||
return; | ||
} | ||
@@ -35,0 +65,0 @@ this.on('input', function (msg, send, done) { |
@@ -0,1 +1,23 @@ | ||
/* | ||
* This code is licensed under the Apache License Version 2.0. | ||
* | ||
* Copyright (c) 2022 Robert Gester | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions | ||
* are met: | ||
* | ||
* 1. Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* | ||
* 2. Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* | ||
* 3. Neither the name of the copyright holder nor the names of its | ||
* contributors may be used to endorse or promote products derived from | ||
* this software without specific prior written permission. | ||
* | ||
*/ | ||
/******************************************** | ||
@@ -94,2 +116,10 @@ * time-comp: | ||
const node = this; | ||
if (!this.positionConfig) { | ||
node.status({ | ||
fill: 'red', | ||
shape: 'dot', | ||
text: 'Node not properly configured!!' | ||
}); | ||
return; | ||
} | ||
@@ -96,0 +126,0 @@ this.on('input', (msg, send, done) => { |
@@ -0,1 +1,23 @@ | ||
/* | ||
* This code is licensed under the Apache License Version 2.0. | ||
* | ||
* Copyright (c) 2022 Robert Gester | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions | ||
* are met: | ||
* | ||
* 1. Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* | ||
* 2. Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* | ||
* 3. Neither the name of the copyright holder nor the names of its | ||
* contributors may be used to endorse or promote products derived from | ||
* this software without specific prior written permission. | ||
* | ||
*/ | ||
/******************************************** | ||
@@ -750,3 +772,3 @@ * time-inject: | ||
} | ||
msg._srcid = node.id; | ||
msg._srcid = node._path || node.id; | ||
msg._ts = dNow.valueOf(); | ||
@@ -753,0 +775,0 @@ return msg; |
@@ -0,1 +1,23 @@ | ||
/* | ||
* This code is licensed under the Apache License Version 2.0. | ||
* | ||
* Copyright (c) 2022 Robert Gester | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions | ||
* are met: | ||
* | ||
* 1. Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* | ||
* 2. Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* | ||
* 3. Neither the name of the copyright holder nor the names of its | ||
* contributors may be used to endorse or promote products derived from | ||
* this software without specific prior written permission. | ||
* | ||
*/ | ||
/******************************************** | ||
@@ -85,5 +107,3 @@ * time-span: | ||
timeSpan = timeSpan * -1; | ||
const dTmp = d1; | ||
d1 = d2; | ||
d2 = dTmp; | ||
[d1, d2] = [d2, d1]; | ||
} | ||
@@ -269,3 +289,10 @@ | ||
this.positionConfig = RED.nodes.getNode(config.positionConfig); | ||
if (!this.positionConfig) { | ||
node.status({ | ||
fill: 'red', | ||
shape: 'dot', | ||
text: 'Node not properly configured!!' | ||
}); | ||
return; | ||
} | ||
this.operand1 = { | ||
@@ -272,0 +299,0 @@ type: config.operand1Type, |
@@ -0,1 +1,23 @@ | ||
/* | ||
* This code is licensed under the Apache License Version 2.0. | ||
* | ||
* Copyright (c) 2022 Robert Gester | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions | ||
* are met: | ||
* | ||
* 1. Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* | ||
* 2. Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* | ||
* 3. Neither the name of the copyright holder nor the names of its | ||
* contributors may be used to endorse or promote products derived from | ||
* this software without specific prior written permission. | ||
* | ||
*/ | ||
/******************************************** | ||
@@ -287,3 +309,10 @@ * within-time-switch: | ||
// this.debug('initialize withinTimeSwitchNode ' + util.inspect(config, { colors: true, compact: 10, breakLength: Infinity })); | ||
if (!this.positionConfig) { | ||
node.status({ | ||
fill: 'red', | ||
shape: 'dot', | ||
text: 'Node not properly configured!!' | ||
}); | ||
return null; | ||
} | ||
this.timeStart = { | ||
@@ -393,6 +422,6 @@ type: config.startTimeType, | ||
if (typeof config.timedatestart !== undefined && config.timedatestart !== '') { | ||
if (typeof config.timedatestart !== 'undefined' && config.timedatestart !== '') { | ||
this.timeStartDate = new Date(config.timedatestart); | ||
} | ||
if (typeof config.timedateend !== undefined && config.timedateend !== '') { | ||
if (typeof config.timedateend !== 'undefined' && config.timedateend !== '') { | ||
this.timeEndDate = new Date(config.timedateend); | ||
@@ -399,0 +428,0 @@ } |
{ | ||
"name": "node-red-contrib-sun-position", | ||
"version": "2.0.6", | ||
"version": "2.1.1", | ||
"description": "NodeRED nodes to get sun and moon position", | ||
@@ -56,3 +56,3 @@ "keywords": [ | ||
"scripts": { | ||
"test": "eslint \"./**/*.js\" \"./**/*.html\"", | ||
"test": "eslint \"./**/*.js\" \"./**/*.html\" && node-red-dev validate", | ||
"lintfix": "eslint --fix \"./**/*.js\" \"./**/*.html\"", | ||
@@ -115,7 +115,8 @@ "lint": "eslint \"./**/*.js\" \"./**/*.html\"", | ||
"devDependencies": { | ||
"eslint": "^8.3.0", | ||
"eslint-plugin-html": "^6.2.0", | ||
"eslint-plugin-jsdoc": "^37.0.3", | ||
"eslint-plugin-json": "^3.1.0", | ||
"eslint-plugin-node": "^11.1.0" | ||
"eslint": ">=8.9.0", | ||
"eslint-plugin-html": ">=6.2.0", | ||
"eslint-plugin-jsdoc": ">=37.9.1", | ||
"eslint-plugin-json": ">=3.1.0", | ||
"eslint-plugin-node": ">=11.1.0", | ||
"node-red-dev": "^0.1.5" | ||
}, | ||
@@ -122,0 +123,0 @@ "disabledSettings": { |
# node-red-contrib-sun-position for NodeRED | ||
[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/rdmtc/node-red-contrib-sun-position/graphs/commit-activity) | ||
[![HitCount](http://hits.dwyl.io/rdmtc/node-red-contrib-sun-position.svg)](http://hits.dwyl.io/rdmtc/node-red-contrib-sun-position) | ||
[![Dependencies Status](https://img.shields.io/david/rdmtc/node-red-contrib-sun-position.svg)](https://david-dm.org/rdmtc/node-red-contrib-sun-position) | ||
[![npm version](https://badge.fury.io/js/node-red-contrib-sun-position.svg)](https://badge.fury.io/js/node-red-contrib-sun-position) | ||
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) | ||
[![Issues](https://img.shields.io/github/issues/rdmtc/node-red-contrib-sun-position.svg?style=flat-square)](https://github.com/rdmtc/node-red-contrib-sun-position/issues) | ||
[![code style](https://img.shields.io/badge/Code%20Style-eslint-green.svg)](https://eslint.org/) | ||
[![NPM](https://nodei.co/npm/node-red-contrib-sun-position.png)](https://nodei.co/npm/node-red-contrib-sun-position/) | ||
@@ -10,0 +9,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
2029642
131
16675
0
6
117