node-red-contrib-sun-position
Advanced tools
Comparing version 1.0.0-alpha-8 to 1.0.1
@@ -21,2 +21,4 @@ # clock-timer Controller | ||
- [Node Output](#node-output) | ||
- [Node Status](#node-status) | ||
- [rules](#rules) | ||
- [Other](#other) | ||
@@ -104,2 +106,65 @@ | ||
{"rule":{"active":false,"id":-1},"reason":{"code":1,"state":"default","description":"position is set to default position because no other rule matches","stateComplete":"1578080767456 - default"},"timeClock":{"payloadDefault":"","payloadDefaultType":"date","payloadDefaultTimeFormat":0,"payloadDefaultOffset":0,"payloadDefaultOffsetType":"none","payloadDefaultOffsetMultiplier":60000,"topic":"default","overwrite":{"active":false,"expireDuration":null,"priority":0}}} | ||
* `timeCtrl` a object will be added add as `msg.timeCtrl` property on single output mode or send as `msg.payload` on slit output mode with the following properties: | ||
* `timeCtrl.reason` - __object__ - for the reason of the current blind position | ||
* `timeCtrl.reason.code` - __number__ - representing the reason for the blind position. The possible codes are | ||
* **-1** - the rules was not evaluated, maybe override is active | ||
* **1** - defined default payload, because no other rule/condition/behavior | ||
* **2** - manual override | ||
* **3** - manual override - expiring | ||
* **4** - based blind position based by rule | ||
* `timeCtrl.reason.state` - __string__ - short text representing the reason for the blind position (same as node status text) | ||
* `timeCtrl.reason.description` - __string__ - describe the reason for the blind position | ||
* `timeCtrl.timeClock` - __object__ - containing all settings, only the most interesting ones are explained here | ||
* `timeCtrl.timeClock.payloadDefault` - __any__ - the defined default payload | ||
* `timeCtrl.timeClock.payloadDefaultType` - __string__ - the type of the default payload | ||
* `timeCtrl.timeClock.payloadDefault...` - other settings of the default payload | ||
* `timeCtrl.timeClock.topic` - __string__ - the defined default topic | ||
* `timeCtrl.timeCtrl.overwrite` - __object__ | ||
* `timeCtrl.timeCtrl.overwrite.active` - __boolean__ - is `true` when overwrite is active, otherwise `false` | ||
* `timeCtrl.timeCtrl.overwrite.priority` - __number__ - the priority of the override | ||
* `timeCtrl.timeCtrl.overwrite.expires` - __boolean__ - is `true` when overwrite expires [exists only if overwrite active] | ||
* `timeCtrl.timeCtrl.overwrite.expireTs` - __number__ - a timestamp (UNIX) when overwrite expiring [exists only if overwrite expires] | ||
* `timeCtrl.timeCtrl.overwrite.expireDate` - __string__ - a timestamp (String) when overwrite expiring [exists only if overwrite expires] | ||
* `timeCtrl.rule` - __object__ - exists only if no override is active | ||
* `timeCtrl.rule.active` - __boolean__ - `true` if a rule applies | ||
* `timeCtrl.rule.id` - __number__ - id of the rule who applies (is `-1` if no rule has applied) | ||
* `timeCtrl.rule.level` - __number__ - the blind level defined by the rule if level type is __absolute__, otherwise the defined default blind position [exists only if a rule applies] | ||
* `timeCtrl.rule.conditional` - __boolean__ - `true` if the rule has a condition [exists only if a rule applies] | ||
* `timeCtrl.rule.timeLimited` - __boolean__ - `true` if the rule has a time [exists only if a rule applies] | ||
* `timeCtrl.rule.conditon` - __object__ with additional data about the condition [exists only if `timeCtrl.rule.conditional` is true] - good for debugging purpose | ||
* `timeCtrl.rule.time` - __object__ with additional data about the time [exists only if `timeCtrl.rule.timeLimited` is true] - good for debugging purpose | ||
* `timeCtrl.rule.hasMinimum` - __boolean__ - is __true__ if to the level of the rule an additional __minimum__ rule will be active, otherwise __false__ | ||
* `timeCtrl.rule.levelMinimum` - __number__ - exists only if `timeCtrl.rule.hasMinimum` is __true__ and then contains then the blind level defined by the rule | ||
* `timeCtrl.rule.hasMaximum` - __boolean__ - is __true__ if to the level of the rule an additional __maximum__ rule will be active, otherwise __false__ | ||
* `timeCtrl.rule.levelMinimum` - __number__ - exists only if `timeCtrl.rule.hasMaximum` is __true__ and then contains then the blind level defined by the rule | ||
* `timeCtrl.autoTrigger` - __object__ - with additional data about the autoTrigger [exists only if auto trigger is enabled in the settings] | ||
* `timeCtrl.autoTrigger.deaultTime` - __number__ - in milliseconds the auto trigger time of the settings | ||
* `timeCtrl.autoTrigger.time` - __number__ - in milliseconds the next auto trigger time (could be less than the dined time in the settings) | ||
* `timeCtrl.autoTrigger.type` - __number__ - the type of the next auto trigger | ||
* **0** - equal to defined `timeCtrl.autoTrigger.deaultTime` | ||
* **1** - by current rule end or `timeCtrl.autoTrigger.deaultTime` | ||
* **2** - by next rule or `timeCtrl.autoTrigger.deaultTime` | ||
* **3** - sun not on horizon (maybe it is night?) | ||
* **4** - sun not visible | ||
* **5** - sun before in window (auto trigger time will be at maximum every 10 minutes) | ||
* **6** - sun in window and smooth time is set (auto trigger time will be maximum the defined smooth time) | ||
* **7** - sun in window and no smooth time defined (auto trigger time will be at maximum every 5 minutes) | ||
### Node Status | ||
The node status representing the value of the `timeCtrl.reason.state` of the output. | ||
The color of the output is as following: | ||
* red - any error | ||
* blue - override active | ||
* grey - payload by rule | ||
* green - default value | ||
* yellow - any other | ||
## rules | ||
------------------------------------------------------------ | ||
@@ -106,0 +171,0 @@ |
@@ -970,17 +970,23 @@ /******************************************** | ||
node.emit('input', { | ||
topic: 'autoTrigger/triggerOnly/start/1', | ||
topic: 'autoTrigger/triggerOnly/start', | ||
payload: 'triggerOnly', | ||
triggerOnly: true | ||
}); | ||
}, 30000); // 30s | ||
setTimeout(() => { | ||
node.emit('input', { | ||
topic: 'autoTrigger/triggerOnly/start/2', | ||
payload: 'triggerOnly', | ||
triggerOnly: true | ||
}); | ||
}, 360000); // 6min | ||
}, 30000 + Math.floor(Math.random() * 30000)); // 30s - 1min | ||
} | ||
} | ||
initialize(); | ||
setTimeout(() => { | ||
try { | ||
initialize(); | ||
} catch (err) { | ||
node.error(err.message); | ||
node.log(util.inspect(err, Object.getOwnPropertyNames(err))); | ||
node.status({ | ||
fill: 'red', | ||
shape: 'ring', | ||
text: RED._('node-red-contrib-sun-position/position-config:errors.error-title') | ||
}); | ||
} | ||
}, 200 + Math.floor(Math.random() * 600)); | ||
} | ||
@@ -987,0 +993,0 @@ |
@@ -32,3 +32,2 @@ /******************************************** | ||
// function tsSetAddProp(node, msg, type, name, valueType, value, format, offset, offsetType, multiplier, days, next) { | ||
/** | ||
@@ -59,5 +58,5 @@ * | ||
if (res === null || (typeof res === 'undefined')) { | ||
throw new Error('could not evaluate ' + data.type + '.' + data.value); | ||
this.error('Could not evaluate ' + data.type + '.' + data.value + '. - Maybe settings outdated (open and save again)!'); | ||
} else if (res.error) { | ||
this.error('error on getting additional payload 1: ' + res.error); | ||
this.error('Eerror on getting additional payload: "' + res.error + '"'); | ||
} else if (data.outType === 'msgPayload') { | ||
@@ -150,2 +149,20 @@ msg.payload = res; | ||
/** | ||
* Recalculate the timeout | ||
*/ | ||
function doTimeRecalc() { | ||
try { | ||
node.debug('needsRecalc'); | ||
doCreateTimeout(node); | ||
} catch (err) { | ||
node.error(err.message); | ||
node.log(util.inspect(err, Object.getOwnPropertyNames(err))); | ||
node.status({ | ||
fill: 'red', | ||
shape: 'ring', | ||
text: RED._('node-red-contrib-sun-position/position-config:errors.error-title') | ||
}); | ||
} | ||
} | ||
/** | ||
* creates the timeout | ||
@@ -226,3 +243,4 @@ * @param {*} node - the node representation | ||
} | ||
let fill = 'yellow'; | ||
let shape = 'dot'; | ||
if ((node.nextTime !== null) && (typeof node.nextTime !== undefined) && (errorStatus === '')) { | ||
@@ -235,4 +253,5 @@ if (!hlp.isValidDate(node.nextTime)) { | ||
let millisec = tsGetScheduleTime(node.nextTime, 10); | ||
const isAlt = (node.nextTimeAlt); | ||
const isAlt = node.nextTimeAlt; | ||
if (isAlt) { | ||
shape = 'ring'; | ||
const millisecAlt = tsGetScheduleTime(node.nextTimeAlt, 10); | ||
@@ -245,60 +264,64 @@ if (millisecAlt < millisec) { | ||
// node.debug('timeout ' + node.nextTime + ' is in ' + millisec + 'ms (isAlt=' + isAlt + ' isAltFirst=' + isAltFirst + ')'); | ||
node.timeOutObj = setTimeout((isAlt, isAltFirst) => { | ||
const msg = { | ||
type: 'start', | ||
timeData: {} | ||
}; | ||
node.timeOutObj = null; | ||
let useAlternateTime = false; | ||
if (isAlt) { | ||
let needsRecalc = false; | ||
try { | ||
useAlternateTime = node.positionConfig.comparePropValue(node, msg, node.propertyType, node.property, | ||
node.propertyOperator, node.propertyThresholdType, node.propertyThresholdValue); | ||
needsRecalc = (isAltFirst && !useAlternateTime) || (!isAltFirst && useAlternateTime); | ||
} catch (err) { | ||
needsRecalc = isAltFirst; | ||
hlp.handleError(node, RED._('time-inject.errors.invalid-property-type', { | ||
type: node.propertyType, | ||
value: node.property | ||
}), err); | ||
} | ||
if (millisec > 345600000) { | ||
// > 4 Days | ||
if (node.intervalObj) { | ||
clearInterval(node.intervalObj); | ||
node.intervalObj = null; | ||
} | ||
if (needsRecalc) { | ||
node.timeOutObj = setTimeout(() => { | ||
doTimeRecalc(); | ||
}, millisec - 129600000); // 1,5 days before | ||
fill = 'blue'; | ||
} else { | ||
// node.debug('timeout ' + node.nextTime + ' is in ' + millisec + 'ms (isAlt=' + isAlt + ' isAltFirst=' + isAltFirst + ')'); | ||
node.timeOutObj = setTimeout((isAlt, isAltFirst) => { | ||
const msg = { | ||
type: 'start', | ||
timeData: {} | ||
}; | ||
node.timeOutObj = null; | ||
let useAlternateTime = false; | ||
if (isAlt) { | ||
let needsRecalc = false; | ||
try { | ||
node.debug('needsRecalc'); | ||
doCreateTimeout(node); | ||
useAlternateTime = node.positionConfig.comparePropValue(node, msg, node.propertyType, node.property, | ||
node.propertyOperator, node.propertyThresholdType, node.propertyThresholdValue); | ||
needsRecalc = (isAltFirst && !useAlternateTime) || (!isAltFirst && useAlternateTime); | ||
} catch (err) { | ||
node.error(err.message); | ||
node.log(util.inspect(err, Object.getOwnPropertyNames(err))); | ||
node.status({ | ||
fill: 'red', | ||
shape: 'ring', | ||
text: RED._('node-red-contrib-sun-position/position-config:errors.error-title') | ||
}); | ||
needsRecalc = isAltFirst; | ||
hlp.handleError(node, RED._('time-inject.errors.invalid-property-type', { | ||
type: node.propertyType, | ||
value: node.property | ||
}), err); | ||
} | ||
return { state:'recalc', done: true }; | ||
if (needsRecalc) { | ||
doTimeRecalc(); | ||
return { state:'recalc', done: true }; | ||
} | ||
} | ||
} | ||
if (useAlternateTime && node.nextTimeAltData) { | ||
msg.timeData = node.nextTimeAltData; | ||
} else if (node.nextTimeData) { | ||
msg.timeData = node.nextTimeData; | ||
if (useAlternateTime && node.nextTimeAltData) { | ||
msg.timeData = node.nextTimeAltData; | ||
} else if (node.nextTimeData) { | ||
msg.timeData = node.nextTimeData; | ||
} | ||
node.emit('input', msg); | ||
return { state: 'emit', done: true }; | ||
}, millisec, isAlt, isAltFirst); | ||
fill = 'green'; | ||
if (!isFixedTime && !node.intervalObj && (_onInit !== true)) { | ||
node.intervalObj = setInterval(() => { | ||
node.debug('retriggered'); | ||
doCreateTimeout(node); | ||
}, node.recalcTime); | ||
} else if (isFixedTime && node.intervalObj) { | ||
clearInterval(node.intervalObj); | ||
node.intervalObj = null; | ||
} | ||
node.emit('input', msg); | ||
return { state: 'emit', done: true }; | ||
}, millisec, isAlt, isAltFirst); | ||
} | ||
} | ||
if (!isFixedTime && !node.intervalObj && (_onInit !== true)) { | ||
node.intervalObj = setInterval(() => { | ||
node.debug('retriggered'); | ||
doCreateTimeout(node); | ||
}, node.recalcTime); | ||
} else if (isFixedTime && node.intervalObj) { | ||
clearInterval(node.intervalObj); | ||
node.intervalObj = null; | ||
} | ||
if ((errorStatus !== '')) { | ||
@@ -315,4 +338,4 @@ node.status({ | ||
node.status({ | ||
fill: 'green', | ||
shape: 'ring', | ||
fill, | ||
shape, | ||
text: node.positionConfig.toDateTimeString(node.nextTimeAlt) + ' / ' + node.positionConfig.toTimeString(node.nextTime) | ||
@@ -322,4 +345,4 @@ }); | ||
node.status({ | ||
fill: 'green', | ||
shape: 'dot', | ||
fill, | ||
shape, | ||
text: node.positionConfig.toDateTimeString(node.nextTime) + ' / ' + node.positionConfig.toTimeString(node.nextTimeAlt) | ||
@@ -330,4 +353,4 @@ }); | ||
node.status({ | ||
fill: 'green', | ||
shape: 'dot', | ||
fill, | ||
shape, | ||
text: node.positionConfig.toDateTimeString(node.nextTime) | ||
@@ -384,38 +407,41 @@ }); | ||
tsSetAddProp(this, msg, { | ||
outType: config.addPayload1Type, | ||
outValue: config.addPayload1, | ||
type: config.addPayload1ValueType, | ||
value: config.addPayload1Value, | ||
format: config.addPayload1Format, | ||
offsetType: config.addPayload1OffsetType, | ||
offset: config.addPayload1Offset, | ||
multiplier: config.addPayload1OffsetMultiplier, | ||
next: config.addPayload1Next, | ||
days: config.addPayload1Days | ||
}); | ||
tsSetAddProp(this, msg, { | ||
outType: config.addPayload2Type, | ||
outValue: config.addPayload2, | ||
type: config.addPayload2ValueType, | ||
value: config.addPayload2Value, | ||
format: config.addPayload2Format, | ||
offsetType: config.addPayload2OffsetType, | ||
offset: config.addPayload2Offset, | ||
multiplier: config.addPayload2OffsetMultiplier, | ||
next: config.addPayload2Next, | ||
days: config.addPayload2Days | ||
}); | ||
tsSetAddProp(this, msg, { | ||
outType: config.addPayload3Type, | ||
outValue: config.addPayload3, | ||
type: config.addPayload3ValueType, | ||
value: config.addPayload3Value, | ||
format: config.addPayload3Format, | ||
offsetType: config.addPayload3OffsetType, | ||
offset: config.addPayload3Offset, | ||
multiplier: config.addPayload3OffsetMultiplier, | ||
next: config.addPayload3Next, | ||
days: config.addPayload3Days | ||
}); | ||
if (typeof config.addPayload1Type !== 'undefined' && | ||
typeof config.addPayload1ValueType !== 'undefined') { | ||
tsSetAddProp(this, msg, { | ||
outType: config.addPayload1Type, | ||
outValue: config.addPayload1, | ||
type: config.addPayload1ValueType, | ||
value: config.addPayload1Value, | ||
format: config.addPayload1Format, | ||
offsetType: config.addPayload1OffsetType, | ||
offset: config.addPayload1Offset, | ||
multiplier: config.addPayload1OffsetMultiplier, | ||
next: config.addPayload1Next, | ||
days: config.addPayload1Days | ||
}); | ||
tsSetAddProp(this, msg, { | ||
outType: config.addPayload2Type, | ||
outValue: config.addPayload2, | ||
type: config.addPayload2ValueType, | ||
value: config.addPayload2Value, | ||
format: config.addPayload2Format, | ||
offsetType: config.addPayload2OffsetType, | ||
offset: config.addPayload2Offset, | ||
multiplier: config.addPayload2OffsetMultiplier, | ||
next: config.addPayload2Next, | ||
days: config.addPayload2Days | ||
}); | ||
tsSetAddProp(this, msg, { | ||
outType: config.addPayload3Type, | ||
outValue: config.addPayload3, | ||
type: config.addPayload3ValueType, | ||
value: config.addPayload3Value, | ||
format: config.addPayload3Format, | ||
offsetType: config.addPayload3OffsetType, | ||
offset: config.addPayload3Offset, | ||
multiplier: config.addPayload3OffsetMultiplier, | ||
next: config.addPayload3Next, | ||
days: config.addPayload3Days | ||
}); | ||
} | ||
send(msg); // node.send(msg); | ||
@@ -455,26 +481,38 @@ done(); | ||
const createTO = doCreateTimeout(node, true); | ||
if (createTO.done !== true) { | ||
if (createTO.errorMsg) { | ||
node.warn(RED._('node-red-contrib-sun-position/position-config:errors.warn-init', { message: createTO.errorMsg, time: 6})); | ||
} | ||
setTimeout(() => { | ||
try { | ||
doCreateTimeout(node); | ||
} catch (err) { | ||
node.error(err.message); | ||
node.log(util.inspect(err, Object.getOwnPropertyNames(err))); | ||
setTimeout(() => { | ||
try { | ||
const createTO = doCreateTimeout(node, true); | ||
if (createTO.done !== true) { | ||
if (createTO.errorMsg) { | ||
node.warn(RED._('node-red-contrib-sun-position/position-config:errors.warn-init', { message: createTO.errorMsg, time: 6})); | ||
} | ||
setTimeout(() => { | ||
try { | ||
doCreateTimeout(node); | ||
} catch (err) { | ||
node.error(err.message); | ||
node.log(util.inspect(err, Object.getOwnPropertyNames(err))); | ||
node.status({ | ||
fill: 'red', | ||
shape: 'ring', | ||
text: RED._('node-red-contrib-sun-position/position-config:errors.error-title') | ||
}); | ||
} | ||
}, 360000); // 6 Minuten | ||
node.status({ | ||
fill: 'red', | ||
shape: 'ring', | ||
text: RED._('node-red-contrib-sun-position/position-config:errors.error-title') | ||
text: RED._('node-red-contrib-sun-position/position-config:errors.error-init', { message: createTO.statusMsg, time: '6min'}) | ||
}); | ||
} | ||
}, 360000); // 6 Minuten | ||
node.status({ | ||
fill: 'red', | ||
shape: 'ring', | ||
text: RED._('node-red-contrib-sun-position/position-config:errors.error-init', { message: createTO.statusMsg, time: '6min'}) | ||
}); | ||
} | ||
} catch (err) { | ||
node.error(err.message); | ||
node.log(util.inspect(err, Object.getOwnPropertyNames(err))); | ||
node.status({ | ||
fill: 'red', | ||
shape: 'ring', | ||
text: RED._('node-red-contrib-sun-position/position-config:errors.error-title') | ||
}); | ||
} | ||
}, 200 + Math.floor(Math.random() * 600)); | ||
} catch (err) { | ||
@@ -481,0 +519,0 @@ node.error(err.message); |
{ | ||
"name": "node-red-contrib-sun-position", | ||
"version": "1.0.0-alpha-8", | ||
"version": "1.0.1", | ||
"description": "NodeRED nodes to get sun and moon position", | ||
@@ -96,3 +96,3 @@ "keywords": [ | ||
"camo-purge": "^1.0.2", | ||
"eslint": "^6.6.0", | ||
"eslint": "^6.8.0", | ||
"eslint-plugin-html": "^6.0.0" | ||
@@ -99,0 +99,0 @@ }, |
@@ -41,2 +41,3 @@ # node-red-contrib-sun-position for NodeRED | ||
* [time-inject - Node Output](#time-inject---node-output) | ||
* [time-inject - Node Status](#time-inject---node-status) | ||
* [within-time](#within-time) | ||
@@ -292,2 +293,16 @@ * [within-time - Node settings](#within-time---node-settings) | ||
#### time-inject - Node Status | ||
* red on error | ||
* green | ||
* the color opf the status is green, if the next trigger time is soon (< 36h). | ||
* type of the status | ||
* **dot** The next trigger time is normal time. (But that doesn't mean that an inject really takes place.) | ||
* **ring** The next trigger time is alternate time. (But that doesn't mean that an inject really takes place.) | ||
* blue | ||
* the next trigger (alternate or normal time) is far in the future (>36h). | ||
* type of the status | ||
* **dot** The next trigger time is normal time. (But that doesn't mean that an inject really takes place.) | ||
* **ring** The next trigger time is alternate time. (But that doesn't mean that an inject really takes place.) | ||
### within-time | ||
@@ -294,0 +309,0 @@ |
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 too big to display
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
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
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
1440449
10634
0
715