Socket
Socket
Sign inDemoInstall

node-red-contrib-sun-position

Package Overview
Dependencies
1
Maintainers
1
Versions
136
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.3.0-beta-5 to 0.3.1

107

nodes/blind-control.js

@@ -16,4 +16,8 @@ /********************************************

*/
function validPosition_(node, level) {
function validPosition_(node, level, allowRound) {
// node.debug('validPosition_ level='+level);
if (level === '' || level === null || typeof level === 'undefined') {
node.warn(`Position is empty!`);
return false;
}
if (isNaN(level)) {

@@ -39,2 +43,5 @@ node.warn(`Position: "${level}" is NaN!`);

}
if (allowRound) {
return true;
}
return Number.isInteger(Number((level / node.blindData.increment).toFixed(hlp.countDecimals(node.blindData.increment) + 2)));

@@ -162,2 +169,3 @@ }

node.tempData[type + '.' + value] = data;
return data;
}

@@ -362,3 +370,3 @@

}
const newPos = hlp.getMsgNumberValue(msg, ['blindPosition', 'position', 'level', 'blindLevel'], ['manual', 'levelOverwrite']);
let newPos = hlp.getMsgNumberValue(msg, ['blindPosition', 'position', 'level', 'blindLevel'], ['manual', 'levelOverwrite']);
const expire = hlp.getMsgNumberValue(msg, 'expire', 'expire');

@@ -384,6 +392,10 @@ if (node.blindData.overwrite.active && isNaN(newPos)) {

} else if (!isNaN(newPos)) {
if (!validPosition_(node, newPos)) {
const allowRound = (msg.topic ? (msg.topic.includes('roundLevel') || msg.topic.includes('roundLevel')) : false);
if (!validPosition_(node, newPos, allowRound)) {
node.error(RED._('blind-control.errors.invalid-blind-level', { pos: newPos }));
return false;
}
if (allowRound) {
newPos = posRound_(node, newPos);
}
node.debug(`overwrite newPos=${newPos}`);

@@ -488,3 +500,3 @@ const noSameValue = hlp.getMsgBoolValue(msg, 'ignoreSameValue');

if ((node.smoothTime > 0) && (node.sunData.changeAgain > now.getTime())) {
// node.debug(`no change smooth - smoothTime= ${node.smoothTime} changeAgain= ${node.sunData.changeAgain}`);
node.debug(`no change smooth - smoothTime= ${node.smoothTime} changeAgain= ${node.sunData.changeAgain}`);
node.reason.code = 11;

@@ -504,3 +516,3 @@ node.reason.state = RED._('blind-control.states.smooth', { pos: node.blindData.level.toString()});

// min
// node.debug(`${node.blindData.level} is below ${node.blindData.levelMin} (min)`);
node.debug(`${node.blindData.level} is below ${node.blindData.levelMin} (min)`);
node.reason.code = 5;

@@ -513,3 +525,3 @@ node.reason.state = RED._('blind-control.states.sunCtrlMin', {org: node.reason.state});

// max
// node.debug(`${node.blindData.level} is above ${node.blindData.levelMax} (max)`);
node.debug(`${node.blindData.level} is above ${node.blindData.levelMax} (max)`);
node.reason.code = 6;

@@ -521,3 +533,3 @@ node.reason.state = RED._('blind-control.states.sunCtrlMax', {org: node.reason.state});

}
// node.debug(`calcBlindSunPosition end pos=${node.blindData.level} reason=${node.reason.code} description=${node.reason.description}`);
node.debug(`calcBlindSunPosition end pos=${node.blindData.level} reason=${node.reason.code} description=${node.reason.description}`);
return sunPosition;

@@ -541,2 +553,4 @@ }

if (rule.conditional) {
delete rule.conditonData.operandValue;
delete rule.conditonData.thresholdValue;
rule.conditonData.result = node.positionConfig.comparePropValue(node, msg,

@@ -549,4 +563,15 @@ rule.validOperandAType,

(type, value, data, _id) => { // opCallback
if (_id === 1) {
rule.conditonData.operandValue = value;
} else if (_id === 2) {
rule.conditonData.thresholdValue = value;
}
return evalTempData(node, type, value, data);
});
rule.conditonData.text = rule.conditonData.operandName + ' ' + rule.conditonData.operatorText;
rule.conditonData.textShort = (rule.conditonData.operandNameShort || rule.conditonData.operandName) + ' ' + rule.conditonData.operatorText;
if (typeof rule.conditonData.thresholdValue !== 'undefined') {
rule.conditonData.text += ' ' + rule.conditonData.thresholdValue;
rule.conditonData.textShort += ' ' + hlp.clipStrLength(rule.conditonData.thresholdValue, 10);
}
}

@@ -562,19 +587,2 @@ }

}
/*
rule.conditonData = {
operandAName: rule.validOperandAType + '.' + rule.validOperandAValue,
operator: rule.validOperator
};
if (!node.positionConfig.comparePropValue(node, msg, rule.validOperandAType, rule.validOperandAValue, rule.validOperator, rule.validOperandBType, rule.validOperandBValue, rule.temp, 'value', 'threshold', rule.conditonData)) {
return null;
}
rule.conditonData.operatorText = rule.validOperatorText;
rule.conditonData.operatorDescription = RED._('node-red-contrib-sun-position/position-config:common.comparatorDescription.' + rule.validOperator);
rule.conditonData.text = rule.conditonData.operandAName + ' ' + rule.conditonData.operatorText;
rule.conditonData.textShort = hlp.clipValueLength(rule.conditonData.operandAName,25) + ' ' + rule.conditonData.operatorText;
if (rule.conditonData.operandB) {
rule.conditonData.operandBName = rule.validOperandBType + '.' + rule.validOperandBValue;
rule.conditonData.text += ' ' + rule.conditonData.operandB;
rule.conditonData.textShort += ' ' + hlp.clipValueLength(rule.conditonData.operandBName, 20);
} */
} catch (err) {

@@ -664,2 +672,3 @@ node.warn(RED._('blind-control.errors.getPropertyData', err));

// node.debug('checkRules end: livingRuleData=' + util.inspect(livingRuleData,{colors:true, compact:10}));
node.debug(`checkRules end pos=${node.blindData.level} reason=${node.reason.code} description=${node.reason.description}`);
return livingRuleData;

@@ -675,2 +684,3 @@ }

// node.debug('checkRules end default: livingRuleData=' + util.inspect(livingRuleData, {colors:true, compact:10}));
node.debug(`checkRules end pos=${node.blindData.level} reason=${node.reason.code} description=${node.reason.description}`);
return livingRuleData;

@@ -920,2 +930,37 @@ }

node.rulesTemp = [];
const getName = (type, value) => {
if (type === 'num') {
return value;
} else if (type === 'str') {
return '"' + value + '"';
} else if (type === 'bool') {
return '"' + value + '"';
} else if (type === 'global' || type === 'flow') {
value = value.replace(/^#:(.+)::/, '');
}
return type + '.' + value;
};
const getNameShort = (type, value) => {
if (type === 'num') {
return value;
} else if (type === 'str') {
return '"' + hlp.clipStrLength(value,20) + '"';
} else if (type === 'bool') {
return '"' + value + '"';
} else if (type === 'global' || type === 'flow') {
value = value.replace(/^#:(.+)::/, '');
// special for Homematic Devices
if (/^.+\[('|").{18,}('|")\].*$/.test(value)) {
value = value.replace(/^.+\[('|")/, '').replace(/('|")\].*$/, '');
if (value.length > 25) {
return '...' + value.slice(-22);
}
return value;
}
}
if ((type + value).length > 25) {
return type + '...' + value.slice(-22);
}
return type + '.' + value;
};
for (let i = 0; i < node.rulesCount; ++i) {

@@ -930,3 +975,4 @@ const rule = node.rulesData[i];

result: false,
operandAName: rule.validOperandAType + '.' + rule.validOperandAValue,
operandName: getName(rule.validOperandAType,rule.validOperandAValue),
thresholdName: getName(rule.validOperandBType, rule.validOperandBValue),
operator: rule.validOperator,

@@ -936,9 +982,8 @@ operatorText: rule.validOperatorText,

};
rule.conditonData.text = rule.conditonData.operandAName + ' ' + rule.conditonData.operatorText;
rule.conditonData.textShort = hlp.clipValueLength(rule.conditonData.operandAName, 25) + ' ' + rule.conditonData.operatorText;
if (rule.conditonData.operandB) {
rule.conditonData.operandBName = rule.validOperandBType + '.' + rule.validOperandBValue;
rule.conditonData.text += ' ' + rule.conditonData.operandB;
rule.conditonData.textShort += ' ' + hlp.clipValueLength(rule.conditonData.operandBName, 20);
if (rule.conditonData.operandName.length > 25) {
rule.conditonData.operandNameShort = getNameShort(rule.validOperandAType, rule.validOperandAValue);
}
if (rule.conditonData.thresholdName.length > 25) {
rule.conditonData.thresholdNameShort = getNameShort(rule.validOperandBType, rule.validOperandBValue);
}
}

@@ -945,0 +990,0 @@ }

@@ -11,3 +11,5 @@ /********************************************

isFalse,
clipValueLength,
pad2,
customISOstring,
clipStrLength,
countDecimals,

@@ -102,2 +104,21 @@ handleError,

/*******************************************************************************************************/
/**
* Formats a Date object to a custom ISO String
* @param {*} date Date to Format
* @param {*} offset Offset for Format
*/
function customISOstring(date, offset) {
date = new Date(date); // copy instance
const h = Math.floor(Math.abs(offset)/60);
const m = Math.abs(offset) % 60;
date.setMinutes(date.getMinutes() - offset); // apply custom timezone
return date.getUTCFullYear() + '-' // return custom format
+ pad2(date.getUTCMonth() + 1) + '-'
+ pad2(date.getUTCDate()) + 'T'
+ pad2(date.getUTCHours()) + ':'
+ pad2(date.getUTCMinutes()) + ':'
+ pad2(date.getUTCSeconds())
+ (offset === 0 ? 'Z' : (offset<0 ? '+' : '-') + pad2(h) + ':' + pad2(m));
}
/*******************************************************************************************************/
/* Node-Red Helper functions */

@@ -157,5 +178,6 @@ /*******************************************************************************************************/

*/
function clipValueLength(v, l) {
function clipStrLength(v, l) {
l = l || 15;
if (v.length > l) {
return v.substring(0, (l - 3)) + '...';
return v.slice(0, (l - 3)) + '...';
}

@@ -1046,3 +1068,3 @@ return v;

for (let x = maxlength; x >= minlength; x--) {
const token = str.substring(i, i + x);
const token = str.substr(i, x);
if (token.length < minlength) {

@@ -1126,3 +1148,3 @@ return null;

const month_name = dateFormat.i18n.monthNames[i];
if (val.substring(i_val, i_val + month_name.length).toLowerCase() === month_name.toLowerCase()) {
if (val.substr(i_val, month_name.length).toLowerCase() === month_name.toLowerCase()) {
if (token === 'MMM' || ((token === 'NNN' || token === 'MMMM') && i > 11)) {

@@ -1146,3 +1168,3 @@ month = i + 1;

const day_name = dateFormat.i18n.dayNames[i];
if (val.substring(i_val, i_val + day_name.length).toLowerCase() === day_name.toLowerCase()) {
if (val.substr(i_val, day_name.length).toLowerCase() === day_name.toLowerCase()) {
i_val += day_name.length;

@@ -1214,12 +1236,12 @@ break;

} else if ((token.toLowerCase() === 'tt') || (token.toLowerCase() === 't')) {
if (val.substring(i_val, i_val + 2).toLowerCase() === 'am') {
if (val.substr(i_val, 2).toLowerCase() === 'am') {
ampm = 'AM';
i_val += 2;
} else if (val.substring(i_val, i_val + 2).toLowerCase() === 'pm') {
} else if (val.substr(i_val, 2).toLowerCase() === 'pm') {
ampm = 'PM';
i_val += 2;
} else if (val.substring(i_val, i_val + 1).toLowerCase() === 'a') {
} else if (val.substr(i_val, 1).toLowerCase() === 'a') {
ampm = 'AM';
i_val += 1;
} else if (val.substring(i_val, i_val + 1).toLowerCase() === 'p') {
} else if (val.substr(i_val, 1).toLowerCase() === 'p') {
ampm = 'PM';

@@ -1231,3 +1253,3 @@ i_val += 1;

} else {
if (val.substring(i_val, i_val + token.length) !== token) {
if (val.substr(i_val, token.length) !== token) {
return null;

@@ -1234,0 +1256,0 @@ }

@@ -199,3 +199,3 @@ /********************************************

/*******************************************************************************************************/
getFloatProp(_srcNode, msg, type, value, def) {
getFloatProp(_srcNode, msg, type, value, def, opCallback) {
// _srcNode.debug('getFloatProp type='+type+' value='+value);

@@ -212,8 +212,4 @@ let data; // 'msg', 'flow', 'global', 'num', 'bin', 'env', 'jsonata'

return def || NaN;
} else if (type === 'msgPayload') {
data = msg.payload;
} else if (type === 'msgValue') {
data = msg.value;
} else {
data = RED.util.evaluateNodeProperty(value, type, _srcNode, msg);
data = this.getPropValue(_srcNode, msg, type, value, opCallback);
}

@@ -246,14 +242,2 @@ if (data === null || typeof data === 'undefined') {

return hlp.getFormattedDateOut(result, format);
} else if (vType === 'msgPayload') {
return msg.payload;
} else if (vType === 'msgTs') {
return msg.ts;
} else if (vType === 'msgLc') {
return msg.lc;
} else if (vType === 'msgValue') {
return msg.value;
} else if (vType === 'pdsCalcData') {
return this.getSunCalc(msg.ts);
} else if (vType === 'pdmCalcData') {
return this.getMoonCalc(msg.ts);
} else if ((vType === 'pdsTime') || (vType === 'pdmTime')) {

@@ -286,3 +270,3 @@ if (vType === 'pdsTime') { // sun

}
return RED.util.evaluateNodeProperty(value, vType, _srcNode, msg);
return this.getPropValue(_srcNode, msg, vType, value);
}

@@ -325,13 +309,5 @@ /*******************************************************************************************************/

return hlp.addOffset(result, offsetX, multiplier);
} else if (vType === 'msgPayload') {
result = msg.payload;
} else if (vType === 'msgTs') {
result = msg.ts;
} else if (vType === 'msgLc') {
return msg.lc;
} else if (vType === 'msgValue') {
result = msg.value;
} else {
// msg, flow, global, str, num, env
result = RED.util.evaluateNodeProperty(value, vType, _srcNode, msg);
result = this.getPropValue(_srcNode, msg, vType, value);
}

@@ -391,3 +367,4 @@ if (result !== null && typeof result !== 'undefined') {

result.fix = (vType === 'json'); // is not a fixed time if can be changed
const res = RED.util.evaluateNodeProperty(value, vType, _srcNode, msg);
const res = this.getPropValue(_srcNode, msg, vType, value);
if (res) {

@@ -426,2 +403,8 @@ result.value = hlp.getDateOfText(res);

result = Number(value);
} else if (type === 'str') {
result = ''+value;
} else if (type === 'bool') {
result = /^true$/i.test(value);
} else if (type === 'date') {
result = Date.now();
} else if (type === 'msgPayload') {

@@ -428,0 +411,0 @@ result = msg.payload;

{
"name": "node-red-contrib-sun-position",
"version": "0.3.0-beta-5",
"version": "0.3.1",
"description": "NodeRED nodes to get sun and moon position",

@@ -43,3 +43,5 @@ "keywords": [

"calculate",
"redmatic"
"redmatic",
"blind",
"blind-control"
],

@@ -46,0 +48,0 @@ "main": "none",

@@ -19,4 +19,6 @@ # node-red-contrib-sun-position for NodeRED

Additional you can get sun and moon position or to control a flow by sun or moon position. It is ideal for usage of control smart home, but also for all other time based flow control.
In addition, there is now a blind controller, which can set blind position time and sun controlled. ( see [blind-control](blind_control.md) )
![nodes](images/appearance1.png?raw=true)
![nodes](images/appearance2.png?raw=true)

@@ -28,44 +30,43 @@ > This is still in development!

* [node-red-contrib-sun-position for NodeRED](#node-red-contrib-sun-position-for-nodered)
* [Table of contents](#table-of-contents)
* [Installation](#installation)
* [Quick Start](#quick-start)
* [General](#general)
* [Saving resources](#saving-resources)
* [second based accuracy](#second-based-accuracy)
* [Implemented Nodes](#implemented-nodes)
* [sun-position](#sun-position)
* [sun-position - Node settings](#sun-position---node-settings)
* [Node Input](#node-input)
* [sun-position - Node Output](#sun-position---node-output)
* [moon-position](#moon-position)
* [moon-position - Node settings](#moon-position---node-settings)
* [moon-position - Node Output](#moon-position---node-output)
* [time-inject](#time-inject)
* [time-inject - Node settings](#time-inject---node-settings)
* [time-inject - Node Input](#time-inject---node-input)
* [time-inject - Node Output](#time-inject---node-output)
* [within-time](#within-time)
* [within-time - Node settings](#within-time---node-settings)
* [time-comp](#time-comp)
* [time-comp - Node settings](#time-comp---node-settings)
* [time-span](#time-span)
* [time-span - Node settings](#time-span---node-settings)
* [blind-control](#blind-control)
* [Times definitions](#times-definitions)
* [sun times](#sun-times)
* [remarks](#remarks)
* [blue hour](#blue-hour)
* [amateurDawn /amateurDusk](#amateurdawn-amateurdusk)
* [alternate properties](#alternate-properties)
* [moon times](#moon-times)
* [message, flow or global property or JSONATA expression](#message-flow-or-global-property-or-jsonata-expression)
* [input parse formats](#input-parse-formats)
* [output timestamp formats](#output-timestamp-formats)
* [output timespan formats](#output-timespan-formats)
* [Conditions](#conditions)
* [TODO](#todo)
* [Bugs and Feedback](#bugs-and-feedback)
* [LICENSE](#license)
* [Other](#other)
- [node-red-contrib-sun-position for NodeRED](#node-red-contrib-sun-position-for-nodered)
- [Table of contents](#table-of-contents)
- [Installation](#installation)
- [General](#general)
- [Saving resources](#saving-resources)
- [second based accuracy](#second-based-accuracy)
- [Implemented Nodes](#implemented-nodes)
- [sun-position](#sun-position)
- [sun-position - Node settings](#sun-position---node-settings)
- [Node Input](#node-input)
- [sun-position - Node Output](#sun-position---node-output)
- [moon-position](#moon-position)
- [moon-position - Node settings](#moon-position---node-settings)
- [moon-position - Node Output](#moon-position---node-output)
- [time-inject](#time-inject)
- [time-inject - Node settings](#time-inject---node-settings)
- [time-inject - Node Input](#time-inject---node-input)
- [time-inject - Node Output](#time-inject---node-output)
- [within-time](#within-time)
- [within-time - Node settings](#within-time---node-settings)
- [time-comp](#time-comp)
- [time-comp - Node settings](#time-comp---node-settings)
- [time-span](#time-span)
- [time-span - Node settings](#time-span---node-settings)
- [blind-control](#blind-control)
- [Times definitions](#times-definitions)
- [sun times](#sun-times)
- [remarks](#remarks)
- [blue hour](#blue-hour)
- [amateurDawn /amateurDusk](#amateurdawn-amateurdusk)
- [alternate properties](#alternate-properties)
- [moon times](#moon-times)
- [message, flow or global property or JSONATA expression](#message-flow-or-global-property-or-jsonata-expression)
- [input parse formats](#input-parse-formats)
- [output timestamp formats](#output-timestamp-formats)
- [output timespan formats](#output-timespan-formats)
- [Conditions](#conditions)
- [TODO](#todo)
- [Bugs and Feedback](#bugs-and-feedback)
- [LICENSE](#license)
- [Other](#other)

@@ -76,6 +77,3 @@ ## Installation

## Quick Start
tbd
## General

@@ -366,10 +364,19 @@

* **none** - no status will be displayed - **only errors** - if an error occurs it will be displayed
![within-time-status-error](https://user-images.githubusercontent.com/12692680/57134527-b62e5800-6da6-11e9-946a-677044d25655.png)
* **time limits** - the time limits will be displayed. An `⎇` sign after a time will show that an alternate time is used.
![within-time-status-time](https://user-images.githubusercontent.com/12692680/57134513-b4649480-6da6-11e9-9bb2-3acda84b8ef8.png)
* **last message** - the time limits will be shown and if the last message was blocked. An `⎇` sign after a time will show that an alternate time is used.
![within-time-status-message-block](https://user-images.githubusercontent.com/12692680/57134528-b6c6ee80-6da6-11e9-90be-e3b15c2b2bff.png)
if the message was pass through the timestamp of this message will be shown.
![within-time-status-message-send](https://user-images.githubusercontent.com/12692680/57134529-b6c6ee80-6da6-11e9-8c71-7245dda4b6ee.png)
* **time limits or last message** - on deploy/start until a message arrives the same behavior as `time limits` options, otherwise the `last message` status display.
* **resend start** If this checkbox is checked and a message arrived outside of time, this message will be additional send again some milliseconds after next start time point. This option is only for fixed time definitions available.

@@ -376,0 +383,0 @@ * **resend end** If this checkbox is checked and a message arrived within time, this message will be additional send again some milliseconds after next end time point. This option is only for fixed time definitions available.

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc