Socket
Socket
Sign inDemoInstall

node-red-contrib-sun-position

Package Overview
Dependencies
Maintainers
1
Versions
136
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-red-contrib-sun-position - npm Package Compare versions

Comparing version 0.1.13 to 0.1.14-beta.6

images/sun-times.svg.png

0

.eslintrc.js

@@ -0,0 +0,0 @@ module.exports = {

131

nodes/lib/suncalc.js

@@ -6,2 +6,4 @@ /*

*/
'use strict';
const util = require('util');

@@ -24,3 +26,2 @@ (function () {

// date/time constants and conversions

@@ -44,3 +45,2 @@

// general calculations for position

@@ -87,3 +87,3 @@

var C = rad * (1.9148 * sin(M) + 0.02 * sin(2 * M) + 0.0003 * sin(3 * M)), // equation of center
let C = rad * (1.9148 * sin(M) + 0.02 * sin(2 * M) + 0.0003 * sin(3 * M)), // equation of center
P = rad * 102.9372; // perihelion of the Earth

@@ -96,3 +96,3 @@

var M = solarMeanAnomaly(d),
let M = solarMeanAnomaly(d),
L = eclipticLongitude(M);

@@ -106,6 +106,4 @@

var SunCalc = {};
// calculates sun position for a given date and latitude/longitude

@@ -115,3 +113,3 @@

var lw = rad * -lng,
let lw = rad * -lng,
phi = rad * lat,

@@ -129,23 +127,33 @@ d = toDays(date),

// sun times configuration (angle, morning name, evening name)
var sunTimes = SunCalc.times = [
[6, 'goldenHourEnd', 'goldenHourStart', 9, 11], // GOLDEN_HOUR_AM
[-0.3, 'sunriseEnd', 'sunsetStart', 8, 12], // SUNRISE_END
[-0.833, 'sunrise', 'sunset', 7, 13], // SUNRISE
[-4, 'blueHourDawnEnd', 'blueHourDuskStart', 6, 14], // BLUE_HOUR
[-6, 'civilDawn', 'civilDusk', 5, 15], // DAWN
[-8, 'blueHourDawnStart', 'blueHourDuskEnd', 4, 16], // BLUE_HOUR
[-12, 'nauticalDawn', 'nauticalDusk', 3, 17], // NAUTIC_DAWN
[-15, 'amateurDawn', 'amateurDusk', 2, 18],
[-18, 'astronomicalDawn', 'astronomicalDusk', 1, 19] // ASTRO_DAWN
];
var sunTimesDefault = SunCalc.timesDefault = {
solarNoon: 10,
nadir: 0
};
var sunTimesAlternate = SunCalc.timesAlternate = [
// for backward compatibilit
['dawn', 'civilDawn'],
['dusk', 'civilDusk'],
['nightEnd', 'astronomicalDawn'],
['night', 'astronomicalDusk'],
['nightStart', 'astronomicalDusk'],
['goldenHour', 'goldenHourStart']
];
var times = SunCalc.times = [
[-0.833, 'sunrise', 'sunset'], // SUNRISE
[-0.3, 'sunriseEnd', 'sunsetStart'], // SUNRISE_END
[-4, 'blueHourDawnEnd', 'blueHourDuskStart'], // BLUE_HOUR
[-6, 'civilDawn', 'civilDusk'], // DAWN
[-8, 'blueHourDawnStart', 'blueHourDuskEnd'], // BLUE_HOUR
[-12, 'nauticalDawn', 'nauticalDusk'], // NAUTIC_DAWN
[-15, 'amateurDawn', 'amateurDusk'],
[-18, 'astronomicalDawn', 'astronomicalDusk'], // ASTRO_DAWN
[6, 'goldenHourEnd', 'goldenHour'] // GOLDEN_HOUR_AM
];
// adds a custom time to the times config
SunCalc.addTime = function (angle, riseName, setName) {
times.push([angle, riseName, setName]);
SunCalc.addTime = function (angle, riseName, setName, risePos, setPos) {
sunTimes.push([angle, riseName, setName, risePos, setPos]);
};
// calculations for sun times

@@ -174,3 +182,3 @@

var w = hourAngle(h, phi, dec),
let w = hourAngle(h, phi, dec),
a = approxTransit(w, lw, n);

@@ -180,3 +188,2 @@ return solarTransitJ(a, M, L);

// calculates sun times for a given date and latitude/longitude

@@ -186,3 +193,3 @@

var lw = rad * -lng,
let lw = rad * -lng,
phi = rad * lat,

@@ -198,33 +205,47 @@

Jnoon = solarTransitJ(ds, M, L),
Jnoon = solarTransitJ(ds, M, L);
i, len, time, Jset, Jrise;
var result = {
solarNoon: fromJulian(Jnoon),
nadir: fromJulian(Jnoon + 0.5)
let result = {
solarNoon: {
value: fromJulian(Jnoon),
pos: sunTimesDefault.solarNoon,
name: 'solarNoon',
angle: 90
},
nadir: {
value: fromJulian(Jnoon + 0.5),
pos: sunTimesDefault.nadir,
name: 'solarNoon',
angle: 270
}
};
for (let i = 0, len = sunTimes.length; i < len; i += 1) {
let time = sunTimes[i];
for (i = 0, len = times.length; i < len; i += 1) {
time = times[i];
let Jset = getSetJ(time[0] * rad, lw, phi, dec, n, M, L);
let Jrise = Jnoon - (Jset - Jnoon);
Jset = getSetJ(time[0] * rad, lw, phi, dec, n, M, L);
Jrise = Jnoon - (Jset - Jnoon);
result[time[1]] = fromJulian(Jrise);
result[time[2]] = fromJulian(Jset);
result[time[2]] = {
value: fromJulian(Jset),
pos: time[4],
name: time[2],
angle: time[0]
};
result[time[1]] = {
value: fromJulian(Jrise),
pos: time[3],
name: time[1],
angle: (180 + (time[0] * -1))
};
}
// for backward compatibilit
result['dawn'] = result['civilDawn'];
result['dusk'] = result['civilDusk'];
result['nightEnd'] = result['astronomicalDawn'];
result['night'] = result['astronomicalDusk'];
result['nightStart'] = result['astronomicalDusk'];
result['dawn'] = result['civilDawn'];
result['goldenHourStart'] = result['goldenHour'];
for (let i = 0, len = sunTimesAlternate.length; i < len; i += 1) {
let time = sunTimesAlternate[i];
result[time[0]] = result[time[1]];
}
//console.log(util.inspect(result));
return result;
};
// moon calculations, based on http://aa.quae.nl/en/reken/hemelpositie.html formulas

@@ -234,3 +255,3 @@

var L = rad * (218.316 + 13.176396 * d), // ecliptic longitude
let L = rad * (218.316 + 13.176396 * d), // ecliptic longitude
M = rad * (134.963 + 13.064993 * d), // mean anomaly

@@ -252,3 +273,3 @@ F = rad * (93.272 + 13.229350 * d), // mean distance

var lw = rad * -lng,
let lw = rad * -lng,
phi = rad * lat,

@@ -280,3 +301,3 @@ d = toDays(date),

var d = toDays(date || new Date()),
let d = toDays(date || new Date()),
s = sunCoords(d),

@@ -307,7 +328,7 @@ m = moonCoords(d),

SunCalc.getMoonTimes = function (date, lat, lng, inUTC) {
var t = new Date(date);
let t = new Date(date);
if (inUTC) t.setUTCHours(0, 0, 0, 0);
else t.setHours(0, 0, 0, 0);
var hc = 0.133 * rad,
let hc = 0.133 * rad,
h0 = SunCalc.getMoonPosition(t, lat, lng).altitude - hc,

@@ -317,3 +338,3 @@ h1, h2, rise, set, a, b, xe, ye, d, roots, x1, x2, dx;

// go in 2-hour chunks, each time seeing if a 3-point quadratic curve crosses zero (which means rise or set)
for (var i = 1; i <= 24; i += 2) {
for (let i = 1; i <= 24; i += 2) {
h1 = SunCalc.getMoonPosition(hoursLater(t, i), lat, lng).altitude - hc;

@@ -352,3 +373,3 @@ h2 = SunCalc.getMoonPosition(hoursLater(t, i + 1), lat, lng).altitude - hc;

var result = {};
let result = {};

@@ -355,0 +376,0 @@ if (rise) result.rise = hoursLater(t, rise);

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

"use strict";
const util = require('util');

@@ -10,8 +11,10 @@ module.exports = {

compareAzimuth,
addOffset,
calcDayOffset,
calcTimeValue,
calcTimeValueUTC,
getTimeOfText,
getTimeOfTextUTC,
getDateOfText,
getDateOfTextUTC,
//getTimeOfTextUTC,
//getDateOfTextUTC,
getTimeNumber,

@@ -32,3 +35,3 @@ getNodeId

function getNodeId(node) {
//node.debug(node.debug(JSON.stringify(srcNode, Object.getOwnPropertyNames(srcNode))));
//node.debug(node.debug(util.inspect(srcNode, Object.getOwnPropertyNames(srcNode))));
return '[' + node.type + ((node.name) ? '/' + node.name + ':' : ':') + node.id + ']';

@@ -50,3 +53,3 @@ }

node.error(messageText);
node.debug(JSON.stringify(err, Object.getOwnPropertyNames(err)));
node.log(util.inspect(err, Object.getOwnPropertyNames(err)));
node.status({

@@ -59,3 +62,3 @@ fill: "red",

console.error(messageText);
console.error(JSON.stringify(err, Object.getOwnPropertyNames(err)));
console.error(util.inspect(err, Object.getOwnPropertyNames(err)));
}

@@ -66,3 +69,3 @@ return false;

function getTimeNumber(date) {
return date.getUTCSeconds() + date.getUTCMinutes() * 60 + date.getUTCHours() * 3600;
return date.getUTCMilliseconds() + date.getUTCSeconds() + date.getUTCMinutes() * 60 + date.getUTCHours() * 3600;
}

@@ -104,8 +107,32 @@ /*******************************************************************************************************/

};
/*******************************************************************************************************/
function addOffset(d, offset) {
if (offset && !isNaN(offset) && offset !== 0) {
return new Date(d.getTime() + offset * 1000); //- does not work
}
return d;
}
/*******************************************************************************************************/
function calcDayOffset(days, daystart) {
let dayx = 0;
let daypos = daystart;
while (days.indexOf(daypos) === -1) {
dayx += 1;
if ((daystart + dayx) > 6) {
daystart = (dayx * -1);
}
daypos = daystart + dayx;
if (dayx > 7) {
dayx = -1;
break;
}
}
return dayx;
}
/*******************************************************************************************************/
function calcTimeValue(d, offset, next, days) {
//console.debug('calcTimeValue d=' + d + ' offset=' + offset + ' next=' + next + ' days=' + days);
if (offset && !isNaN(offset) && offset !== 0) {
d = new Date(d.getTime() + offset * 1000); //- does not work
}
d = addOffset(d, offset);
if (next && !isNaN(next)) {

@@ -122,17 +149,3 @@ let now = new Date();

if (days && (days !== '*') && (days !== '')) {
let daystart = d.getDay();
let dayx = 0;
let daypos = daystart;
while (days.indexOf(daypos) === -1) {
dayx += 1;
if ((daystart + dayx) > 6) {
daystart = (dayx * -1);
}
daypos = daystart + dayx;
if (dayx > 7) {
dayx = -1;
break;
}
}
let dayx = calcDayOffset(days,d.getDay());
if (dayx > 0) {

@@ -148,5 +161,3 @@ d.setDate(d.getDate() + dayx);

//console.debug('calcTimeValueUTC d=' + d + ' offset=' + offset + ' next=' + next + ' days=' + days);
if (offset && !isNaN(offset) && offset !== 0) {
d = new Date(d.getTime() + offset * 1000); //- does not work
}
d = addOffset(d, offset);
if (next && !isNaN(next)) {

@@ -163,17 +174,3 @@ let now = new Date();

if (days && (days !== '*') && (days !== '')) {
let daystart = d.getUTCDay();
let dayx = 0;
let daypos = daystart;
while (days.indexOf(daypos) === -1) {
dayx += 1;
if ((daystart + dayx) > 6) {
daystart = (dayx * -1);
}
daypos = daystart + dayx;
if (dayx > 7) {
dayx = -1;
break;
}
}
let dayx = calcDayOffset(days,d.getUTCDay());
if (dayx > 0) {

@@ -206,2 +203,27 @@ d.setUTCDate(d.getUTCDate() + dayx);

function getDateOfText(date, offset, next, days) {
if (date == null) {
throw new Error('Could not evaluate as a valid Date or time. Value is null!');
}
if ( typeof date === 'object') {
if ( x.hasOwnProperty('now') ) {
date = date.now;
} else if ( x.hasOwnProperty('date') ) {
date = date.date;
} else if ( x.hasOwnProperty('time') ) {
date = date.time;
} else if ( x.hasOwnProperty('ts') ) {
date = date.ts;
} else if ( x.hasOwnProperty('lc') ) {
date = date.lc;
} else if ( x.hasOwnProperty('value') ) {
date = date.lc;
}
}
var re = /^(0[0-9]|[0-9]|1[0-9]|2[0-3])(?::([0-5][0-9]|[0-9]))?(?::([0-5][0-9]|[0-9]))?\s*(pm?)?$/;
if (re.test(String(date))) {
let result = getTimeOfText(String(date), offset, next, days);
if (result != null) {
return result;
}
}
if (!isNaN(date)) {

@@ -213,7 +235,2 @@ date = Number(date);

return calcTimeValue(dto, offset, next, days);
} else {
let result = getTimeOfText(String(date), offset, next, days);
if (result != null) {
return result;
}
}

@@ -223,2 +240,3 @@ throw new Error("could not evaluate " + String(date) + ' as a valid Date or time.');

/*******************************************************************************************************/
/*
function getTimeOfTextUTC(t, tzOffset, offset, next, days, date) {

@@ -242,2 +260,3 @@ //console.debug('getTimeOfTextUTC t=' + t + ' tzOffset=' + tzOffset + ' offset=' + offset + ' next=' + next + ' days=' + days);

/*******************************************************************************************************/
/*
function getDateOfTextUTC(date, tzOffset, offset, next, days) {

@@ -257,2 +276,2 @@ if (!isNaN(date)) {

throw new Error("could not evaluate " + String(date) + ' as a valid Date or time.');
};
};/** **/

@@ -24,2 +24,6 @@ {

"statusTimeOrSend": "time limits or last message",
"lastMsgOnStartOut": "resend start",
"lastMsgOnStartOutTxt": "next start additionally emit the last message arrived out of time",
"lastMsgOnEndOut": "resend end",
"lastMsgOnEndOutTxt": "next end additionally emit the last message arrived in time",
"seconds": "seconds",

@@ -26,0 +30,0 @@ "minutes": "minutes",

@@ -24,2 +24,6 @@ {

"statusTimeOrSend": "time limits or last message",
"lastMsgOnStartOut": "resend start",
"lastMsgOnStartOutTxt": "next start additionally emit the last message arrived out of time",
"lastMsgOnEndOut": "resend end",
"lastMsgOnEndOutTxt": "next end additionally emit the last message arrived in time",
"seconds": "seconds",

@@ -26,0 +30,0 @@ "minutes": "minutes",

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

const hlp = require(path.join(__dirname, '/lib/sunPosHelper.js'));
const util = require('util');
//const hlp = '/lib/sunPosHelper.js';
module.exports = function(RED) {
module.exports = function (RED) {
"use strict";

@@ -21,3 +22,3 @@

this.on('input', function(msg) {
this.on('input', function (msg) {
try {

@@ -83,3 +84,3 @@ var ports = new Array(this.rules.length);

node.error("could not evaluate " + vType + '.' + value + ': ' + err.message);
node.debug(JSON.stringify(err, Object.getOwnPropertyNames(err)));
node.debug(util.inspect(err, Object.getOwnPropertyNames(err)));
}

@@ -86,0 +87,0 @@ }

@@ -8,2 +8,3 @@ /********************************************

const hlp = require(path.join(__dirname, '/lib/sunPosHelper.js'));
const util = require('util');
const sunCalc = require(path.join(__dirname, '/lib/suncalc.js'));

@@ -68,20 +69,2 @@

function nextday(days, daystart) {
let dayx = 0;
let daypos = daystart;
while (days.indexOf(daypos) === -1) {
dayx += 1;
if ((daystart + dayx) > 6) {
daypos = dayx - (7 - daystart);
} else {
daypos = daystart + dayx;
}
if (dayx > 6) {
dayx = -1;
break;
}
}
return dayx;
}
module.exports = function (RED) {

@@ -99,3 +82,3 @@ "use strict";

this.tzOffset = (n.timezoneOffset * -60) || 0;
this.debug('load position-config ' + this.name + ' long:' + this.longitude + ' lat:' + this.latitude + ' angelt:' + this.angleType + ' TZ:' + this.tzOffset);
//this.debug('load position-config ' + this.name + ' long:' + this.longitude + ' lat:' + this.latitude + ' angelt:' + this.angleType + ' TZ:' + this.tzOffset);

@@ -111,3 +94,3 @@ this.lastSunCalc = {

this.getSunTimes = () => {
/*this.getSunTimes = () => {
//node.debug('getSunTimes');

@@ -118,28 +101,31 @@ let res = sunTimesCheck(node);

return res;
}
this.getSunTime = (now, value, next, days) => {
//node.debug('getSunTime ' + value + ' - ' + next + ' - ' + days);
}*/
this.getSunTime = (now, value, offset, next, days) => {
//node.debug('getSunTime value=' + value + ' offset=' + offset + ' next=' + next + ' days=' + days);
let result = sunTimesCheck(node, now);
result.value = new Date(node.sunTimesToday[value]);
result = Object.assign(result, node.sunTimesToday[value]);
result.value = hlp.addOffset(new Date(result.value), offset);
if (next && !isNaN(next) && result.value.getTime() <= now.getTime()) {
if (next === 1) {
result.value = new Date(node.sunTimesTomorow[value]);
result = Object.assign(result, node.sunTimesTomorow[value]);
} else if (next > 1) {
let date = (new Date()).addDays(next);
let times = sunCalc.getTimes(date, node.latitude, node.longitude);
result.value = times[value];
result = Object.assign(result, sunCalc.getTimes(date, node.latitude, node.longitude)[value]);
}
result.value = hlp.addOffset(new Date(result.value), offset);
}
if (days && (days !== '*') && (days !== '')) {
let dayx = nextday(days, result.value.getUTCDay());
let dayx = hlp.calcDayOffset(days, result.value.getDay());
//node.debug('move day ' + dayx);
if (dayx > 0) {
let date = result.value.addDays(dayx);
let times = sunCalc.getTimes(date, node.latitude, node.longitude);
result.value = new Date(times[value]);
//let times = sunCalc.getTimes(date, node.latitude, node.longitude);
result = Object.assign(result, sunCalc.getTimes(date, node.latitude, node.longitude)[value]);
result.value = hlp.addOffset(new Date(result.value), offset);
} else if (dayx < 0) {
node.debug('getSunTime value=' + value + ' - next=' + next + ' - days=' + days + ' result=' + result.value);
//node.debug('getSunTime - no valid day of week found value=' + value + ' - next=' + next + ' - days=' + days + ' result=' + util.inspect(result));
result.error = 'No valid day of week found!';
}
}
//node.debug('getSunTime result=' + util.inspect(result));
return result;

@@ -154,36 +140,36 @@ }

}
this.getMoonTime = (now, value, next, days) => {
//node.debug('getMoonTime ' + value + ' - ' + next + ' - ' + days);
this.getMoonTime = (now, value, offset, next, days) => {
//node.debug('getMoonTime value=' + value + ' offset=' + offset + ' next=' + next + ' days=' + days);
let result = moonTimesCheck(node, now);
result.value = new Date(node.moonTimesToday[value]);
//node.debug('Moon Times today =' + util.inspect(node.moonTimesToday));
result.value = hlp.addOffset(new Date(node.moonTimesToday[value]), offset);
if (next && !isNaN(next) && result.value.getTime() <= now.getTime()) {
if (next === 1) {
result.value = new Date(node.moonTimesTomorow[value]);
result.value = hlp.addOffset(new Date(node.moonTimesTomorow[value]), offset);
//node.debug('Moon Times tomorrow =' + util.inspect(node.moonTimesTomorow));
} else if (next > 1) {
let date = (new Date()).addDays(next);
let times = sunCalc.getMoonTimes(date, node.latitude, node.longitude, true);
result.value = times[value];
result.value = hlp.addOffset(new Date(new Date(times[value])), offset);
//node.debug('Moon Times for ' + date + ' =' + util.inspect(times));
}
}
if (days && (days !== '*') && (days !== '')) {
let dayx = nextday(days, result.value.getUTCDay());
if (dayx === 1) {
result.value = new Date(node.moonTimesTomorow[value]);
} else if (dayx > 1) {
let dayx = hlp.calcDayOffset(days, result.value.getDay());
if (dayx > 0) {
let date = (new Date()).addDays(dayx);
let times = sunCalc.getMoonTimes(date, node.latitude, node.longitude, true);
result.value = new Date(times[value]);
result.value = hlp.addOffset(new Date(new Date(times[value])), offset);
//node.debug('Moon Times for ' + date + ' =' + util.inspect(times));
} else if (dayx < 0) {
result.error = 'no valid week day found!';
node.debug('getMoonTime value=' + value + ' - next=' + next + ' - days=' + days + ' result=' + result.value);
result.error = 'No valid day of week found!';
//node.debug('getMoonTime - no valid week day found value=' + value + ' - next=' + next + ' - days=' + days + ' result=' + result.value);
}
}
//node.debug('getMoonTime result' + util.inspect(result));
return result;
}
//15 Nov 12:06:32 - [error] [time-inject:7e325169.87e6e] Exception occured on time-inject:node.positionConfig.getTimeProp is not a function
//15 Nov 12:06:32 - [debug] [time-inject:7e325169.87e6e] {"stack":"TypeError: node.positionConfig.getTimeProp is not a function\n at doCreateTimeout (U:\\Development\\github\\node-red-contrib-sun-position\\nodes\\time-inject.js:66:53)\n at new timeInjectNode (U:\\Development\\github\\node-red-contrib-sun-position\\nodes\\time-inject.js:227:17)\n at createNode (C:\\Users\\rgester\\AppData\\Roaming\\npm\\node_modules\\node-red\\red\\runtime\\nodes\\flows\\Flow.js:305:18)\n at Flow.start (C:\\Users\\rgester\\AppData\\Roaming\\npm\\node_modules\\node-red\\red\\runtime\\nodes\\flows\\Flow.js:89:35)\n at start (C:\\Users\\rgester\\AppData\\Roaming\\npm\\node_modules\\node-red\\red\\runtime\\nodes\\flows\\index.js:328:29)\n at tryCatchReject (C:\\Users\\rgester\\AppData\\Roaming\\npm\\node_modules\\node-red\\node_modules\\when\\lib\\makePromise.js:845:30)\n at runContinuation1 (C:\\Users\\rgester\\AppData\\Roaming\\npm\\node_modules\\node-red\\node_modules\\when\\lib\\makePromise.js:804:4)\n at Fulfilled.when (C:\\Users\\rgester\\AppData\\Roaming\\npm\\node_modules\\node-red\\node_modules\\when\\lib\\makePromise.js:592:4)\n at Pending.run (C:\\Users\\rgester\\AppData\\Roaming\\npm\\node_modules\\node-red\\node_modules\\when\\lib\\makePromise.js:483:13)\n at Scheduler._drain (C:\\Users\\rgester\\AppData\\Roaming\\npm\\node_modules\\node-red\\node_modules\\when\\lib\\Scheduler.js:62:19)","message":"node.positionConfig.getTimeProp is not a function"}
this.getTimeProp = (srcNode, msg, vType, value, offset, next, days) => {
//node.debug(node.debug(JSON.stringify(srcNode, Object.getOwnPropertyNames(srcNode))));
node.debug('getTimeProp ' + hlp.getNodeId(srcNode) + ' vType=' + vType + ' value=' + value + ' offset=' + offset + ' next=' + next + ' days=' + days);
//node.debug('getTimeProp ' + hlp.getNodeId(srcNode) + ' vType=' + vType + ' value=' + value + ' offset=' + offset + ' next=' + next + ' days=' + days);
let now = new Date();

@@ -203,25 +189,19 @@ let result = {

result.value = hlp.getTimeOfText(String(value), offset, next, days, now);
node.debug(String(value) + ' -- ' + result.value);
//node.debug(String(value) + ' -- ' + result.value);
result.fix = true;
} else if (vType === 'pdsTime') {
//sun
result = node.getSunTime(now, value, next, days);
result = node.getSunTime(now, value, offset, next, days);
result.fix = true;
} else if (vType === 'pdmTime') {
//moon
result = node.getMoonTime(now, value, next, days);
result = node.getMoonTime(now, value, offset, next, days);
result.fix = true;
} else if (vType === 'json') {
let val = JSON.parse(value);
let date = (val.now) ? val.now : ((val.date) ? val.date : ((val.time) ? val.time : ((val.ts) ? val.ts : "")));
result.value = hlp.hlp.getDateOfText(date, offset, next, days);
node.debug(date + ' -- ' + result.value);
result.fix = true;
} else {
//evaluateNodeProperty(value, type, node, msg, callback)
//can handle context, json, jsonata, env, ...
result.fix = (vType === 'json'); // is not a fixed time if can be changed
let res = RED.util.evaluateNodeProperty(value, vType, srcNode, msg);
if (res) {
result.value = hlp.getDateOfText(String(res), offset, next, days);
result.fix = false; // not a fixed time, because can be changed
node.debug(String(res) + ' -- ' + result.value);
result.value = hlp.getDateOfText(res, offset, next, days);
//node.debug(String(res) + ' -- ' + result.value);
} else {

@@ -233,3 +213,3 @@ result.error = "could not evaluate " + vType + '.' + value;

result.error = "could not evaluate " + vType + '=' + value + ': ' + err.message;
node.debug(JSON.stringify(err, Object.getOwnPropertyNames(err)));
node.debug(util.inspect(err, Object.getOwnPropertyNames(err)));
}

@@ -243,2 +223,3 @@

}
//node.debug('getTimeProp result' + util.inspect(result));
return result;

@@ -253,6 +234,5 @@ };

if (typeof date === 'string') {
node.debug('date ' + date);
//node.debug('getSunCalc for date ' + date);
let dto = new Date(date);
if (dto !== "Invalid Date" && !isNaN(dto)) {
node.debug('date ' + dto);
date = dto;

@@ -262,5 +242,6 @@ }

if ((typeof date === 'undefined') || !(date instanceof Date)) {
node.debug('no date' + date);
//node.debug('getSunCalc, no valid date ' + date + ' given');
date = new Date();
if (Math.abs(date.getTime() - this.lastSunCalc.ts) < 4000) {
//node.debug('getSunCalc, time difference since last output to low, do no calculation');
return this.lastSunCalc;

@@ -379,3 +360,3 @@ }

function sunTimesRefresh(node, today, tomorrow, dayId) {
node.debug('sunTimesRefresh - calculate sun times');
//node.debug('sunTimesRefresh - calculate sun times');
node.sunTimesToday = sunCalc.getTimes(today, node.latitude, node.longitude);

@@ -401,3 +382,3 @@ node.sunTimesTomorow = sunCalc.getTimes(tomorrow, node.latitude, node.longitude);

function moonTimesRefresh(node, today, tomorrow, dayId) {
node.debug('moonTimesRefresh - calculate moon times');
//node.debug('moonTimesRefresh - calculate moon times');
node.moonTimesToday = sunCalc.getMoonTimes(today, node.latitude, node.longitude, true);

@@ -439,3 +420,3 @@ if (!node.moonTimesToday.alwaysUp) {

function initTimes(node) {
node.debug('initTimes');
//node.debug('initTimes');
let today = new Date();

@@ -442,0 +423,0 @@ let dayId = getUTCDayId(today);

@@ -6,2 +6,3 @@ /********************************************

const hlp = require(path.join(__dirname, '/lib/sunPosHelper.js'));
const util = require('util');

@@ -39,3 +40,3 @@ module.exports = function (RED) {

let chk = hlp.compareAzimuth(ports[0].payload.azimuth, low, high);
let chg = (node.azimuthPos[i] !== chk);
let chg = (node.azimuthPos[i] !== chk);
ports[0].payload.pos.push(chk);

@@ -82,3 +83,3 @@ ports[0].payload.posChanged = ports[0].payload.posChanged && chg;

node.error("could not evaluate " + vType + '.' + value + ': ' + err.message);
node.debug(JSON.stringify(err, Object.getOwnPropertyNames(err)));
node.debug(util.inspect(err, Object.getOwnPropertyNames(err)));
}

@@ -85,0 +86,0 @@ }

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

"use strict";
const util = require('util');

@@ -11,3 +12,3 @@ const path = require('path');

module.exports = function(RED) {
module.exports = function (RED) {
"use strict";

@@ -19,3 +20,3 @@

this.positionConfig = RED.nodes.getNode(config.positionConfig);
//this.debug('initialize timeInjectNode ' + JSON.stringify(config));
//this.debug('initialize timeInjectNode ' + util.inspect(config));

@@ -44,4 +45,2 @@ this.payload = config.payload || '';

this.lastSendType = 'none';
this.lastInputType = 'none';
this.timeOutObj = null;

@@ -51,2 +50,4 @@ this.intervalObj = null;

this.nextTimeAlt = null;
this.nextTimeData = null;
this.nextTimeAltData = null;
var node = this;

@@ -65,4 +66,4 @@

let errorStatus = '';
let fixTimeStamp = false;
let isAltFirst = false;
let isFixedTime = true;
node.nextTime = null;

@@ -79,13 +80,16 @@ node.nextTimeAlt = null;

//node.nextTime = hlp.getTimeProp(node, node.timeType, node.time, node.offset * node.offsetMultiplier, 1);
node.nextTime = node.positionConfig.getTimeProp(node, undefined, node.timeType, node.time, node.offset * node.offsetMultiplier, 1, node.timeDays);
if (node.nextTime.error) {
node.nextTimeData = node.positionConfig.getTimeProp(node, undefined, node.timeType, node.time, node.offset * node.offsetMultiplier, 1, node.timeDays);
if (node.nextTimeData.error) {
errorStatus = "could not evaluate time";
node.error(node.nextTime.error);
node.error(node.nextTimeData.error);
node.debug(util.inspect(node.nextTimeData));
//console.log('1');
node.nextTime = null;
fixTimeStamp = true;
isFixedTime = false;
} else {
fixTimeStamp = node.nextTime.fix;
node.nextTime = node.nextTime.value;
node.nextTime = node.nextTimeData.value;
isFixedTime = node.nextTimeData.fix;
}
}
//console.log(util.inspect(node.nextTimeData));

@@ -95,10 +99,12 @@ if (node.propertyType !== 'none' &&

node.positionConfig) {
node.nextTimeAlt = node.positionConfig.getTimeProp(node, undefined, node.timeAltType, node.timeAlt, node.timeAltOffset * node.timeAltOffsetMultiplier, 1, node.timeDays);
if (node.nextTimeAlt.error) {
node.nextTimeAltData = node.positionConfig.getTimeProp(node, undefined, node.timeAltType, node.timeAlt, node.timeAltOffset * node.timeAltOffsetMultiplier, 1, node.timeDays);
if (node.nextTimeAltData.error) {
errorStatus = "could not evaluate alternate time";
node.error(node.nextTimeAlt.error);
node.error(node.nextTimeAltData.error);
//console.log('2');
node.nextTimeAlt = null;
isFixedTime = false;
} else {
fixTimeStamp = fixTimeStamp && node.nextTimeAlt.fix;
node.nextTimeAlt = node.nextTimeAlt.value;
node.nextTimeAlt = node.nextTimeAltData.value;
isFixedTime = isFixedTime && node.nextTimeAltData.fix;
}

@@ -108,3 +114,3 @@ }

if (!(node.nextTime instanceof Date) || node.nextTime === 'Invalid Date' || isNaN(node.nextTime)) {
node.debug(node.nextTime);
//node.debug(node.nextTime);
hlp.errorHandler(this, new Error('Invalid Date'), 'Invalid time format', 'internal error!');

@@ -115,3 +121,3 @@ return;

if (millis > 500) {
node.debug('timeout ' + node.nextTime + ' is in ' + millis + 'ms');
//node.debug('timeout ' + node.nextTime + ' is in ' + millis + 'ms');
let isAlt = (node.nextTimeAlt);

@@ -126,3 +132,8 @@ if (isAlt) {

node.timeOutObj = setTimeout((isAlt, isAltFirst) => {
let msg = {
type: 'start',
timeData: {}
};
node.timeOutObj = null;
let useAlternateTime = false;
if (isAlt) {

@@ -132,3 +143,3 @@ let needsRecalc = false;

let res = RED.util.evaluateNodeProperty(node.property, node.propertyType, node, msg);
let useAlternateTime = ((res == true) || (res == 'true'));
useAlternateTime = ((res == true) || (res == 'true'));
needsRecalc = (isAltFirst && !useAlternateTime) || (!isAltFirst && useAlternateTime);

@@ -141,3 +152,3 @@ } catch (err) {

}));
node.debug(JSON.stringify(err));
node.log(util.inspect(err));
}

@@ -153,6 +164,9 @@ if (needsRecalc) {

}
node.debug('redo doCreateTimeout');
node.emit("input", {
type: 'start'
});
if (useAlternateTime && node.nextTimeAltData) {
msg.timeData = node.nextTimeAltData;
} else if (node.nextTimeData) {
msg.timeData = node.nextTimeData;
}
//node.debug('redo doCreateTimeout');
node.emit("input", msg);
}, millis, isAlt, isAltFirst);

@@ -162,7 +176,15 @@ } else {

node.nextTime = null;
fixTimeStamp = false;
}
} else {
fixTimeStamp = false;
}
if (!isFixedTime && !node.intervalObj) {
node.intervalObj = setInterval(() => {
//node.debug('retrigger timecalc');
doCreateTimeout(node, msg);
}, node.recalcTime);
} else if (isFixedTime && node.intervalObj) {
clearInterval(node.intervalObj);
node.intervalObj = null;
}
if (errorStatus) {

@@ -172,3 +194,3 @@ node.status({

shape: "dot",
text: errorStatus
text: errorStatus + ((node.intervalObj) ? ' 🖩' : '')
});

@@ -198,15 +220,5 @@ } else if (node.nextTimeAlt && node.timeOutObj) {

}
if (!fixTimeStamp && !node.intervalObj) {
node.intervalObj = setInterval(() => {
node.debug('retrigger timecalc');
doCreateTimeout(node, msg);
}, node.recalcTime);
} else if (fixTimeStamp && node.intervalObj) {
clearInterval(node.intervalObj);
node.intervalObj = null;
}
}
this.on('close', function() {
this.on('close', function () {
if (node.timeOutObj) {

@@ -224,4 +236,3 @@ clearTimeout(node.timeOutObj);

doCreateTimeout(node, msg);
//node.debug('input ' + JSON.stringify(msg));
this.lastInputType = msg.type;
//node.debug('input ' + util.inspect(msg));
let plType = 'date';

@@ -235,3 +246,2 @@ let plValue = '';

msg.topic = this.topic;
this.lastSendType = 'start';

@@ -250,3 +260,3 @@ if (plType == null || plType === "date" || plType === "none" || plType === "") {

} else {
RED.util.evaluateNodeProperty(plValue, plType, this, msg, function(err, res) {
RED.util.evaluateNodeProperty(plValue, plType, this, msg, function (err, res) {
if (err) {

@@ -268,3 +278,3 @@ hlp.errorHandler(node, err, RED._("time-inject.errors.error-text"), RED._("time-inject.errors.error-title"));

if (this.once) {
this.onceTimeout = setTimeout(function() {
this.onceTimeout = setTimeout(function () {
node.emit("input", {

@@ -271,0 +281,0 @@ type: 'once'

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

"use strict";
const util = require('util');

@@ -47,4 +48,4 @@ const path = require('path');

endSuffix: '',
altStartTime : (node.propertyStartType !== 'none') && (msg || (node.propertyStartType !== 'msg')),
altEndTime : (node.propertyEndType !== 'none') && (msg || (node.propertyEndType !== 'msg'))
altStartTime: (node.propertyStartType !== 'none') && (msg || (node.propertyStartType !== 'msg')),
altEndTime: (node.propertyEndType !== 'none') && (msg || (node.propertyEndType !== 'msg'))
}

@@ -64,3 +65,3 @@

}));
node.debug(JSON.stringify(err));
node.debug(util.inspect(err));
}

@@ -81,3 +82,3 @@ }

}));
node.debug(JSON.stringify(err));
node.debug(util.inspect(err));
}

@@ -103,7 +104,36 @@ }

}
//node.debug(JSON.stringify(result, Object.getOwnPropertyNames(result)));
//node.debug(util.inspect(result, Object.getOwnPropertyNames(result)));
return result;
}
function getScheduleTime(time) {
var now = new Date();
var millis = time.getTime() - now.getTime();
while (millis < 10) {
millis += 86400000; //24h
}
return millis;
}
function checkReSendMsgDelayed(isActive, node, time, msg) {
if (node.timeOutObj) {
clearTimeout(node.timeOutObj);
node.timeOutObj = null;
}
if (!msg.reSendMsgDelayed && isActive && time) {
node.lastMsgObj = RED.util.cloneMessage(msg);
node.lastMsgObj.reSendMsgDelayed = false;
let millis = getScheduleTime(time) + 10;
node.debug('timeout for resend last message ' + time + ' is in ' + millis + 'ms');
node.timeOutObj = setTimeout(() => {
node.debug('setTimeout triggered, resend last message as configured');
node.timeOutObj = null;
if (node.lastMsgObj) {
node.lastMsgObj.reSendMsgDelayed = true;
node.emit("input", node.lastMsgObj);
}
}, millis);
}
}
function withinTimeSwitchNode(config) {

@@ -113,3 +143,3 @@ RED.nodes.createNode(this, config);

this.positionConfig = RED.nodes.getNode(config.positionConfig);
//this.debug('initialize withinTimeSwitchNode ' + JSON.stringify(config));
//this.debug('initialize withinTimeSwitchNode ' + util.inspect(config));

@@ -120,2 +150,4 @@ this.propertyStart = config.propertyStart || "";

this.propertyEndType = config.propertyEndType || "none";
this.timeOutObj = null;
this.lastMsgObj = null;
var node = this;

@@ -125,6 +157,5 @@

try {
//this.debug('starting ' + JSON.stringify(msg, Object.getOwnPropertyNames(msg)));
//this.debug('self ' + JSON.stringify(this, Object.getOwnPropertyNames(this)));
//this.debug('config ' + JSON.stringify(config, Object.getOwnPropertyNames(config)));
//this.debug('starting ' + util.inspect(msg, Object.getOwnPropertyNames(msg)));
//this.debug('self ' + util.inspect(this, Object.getOwnPropertyNames(this)));
//this.debug('config ' + util.inspect(config, Object.getOwnPropertyNames(config)));
let result = calcWithinTimes(this, msg, config, true);

@@ -144,10 +175,9 @@ let now = new Date();

//this.debug(result.start.value + ' - ' + now + ' - ' + result.end.value);
let startNr = hlp.getTimeNumber(result.start.value);
let endNr = hlp.getTimeNumber(result.end.value);
let cmpNow = hlp.getTimeNumber(now);
//this.debug(startNr + ' - ' + cmpNow + ' - ' + endNr);
let status = (config.statusOut || 3);
if (startNr < endNr) {
if (cmpNow >= startNr && cmpNow <= endNr) {
if (cmpNow >= startNr && cmpNow < endNr) {
//this.debug('compare in time 1 ' + startNr + ' - ' + cmpNow + ' - ' + endNr);
this.send([msg, null]);

@@ -157,8 +187,10 @@ setstate(this, result, status, {

shape: "ring",
text: '🖅 ' + result.startSuffix + now.toLocaleString() + result.endSuffix //🖅
text: '🖅 ' + result.startSuffix + now.toLocaleString() + result.endSuffix
});
checkReSendMsgDelayed(config.lastMsgOnEndOut, this, result.end.value, msg);
return null;
}
} else {
if (!(cmpNow > endNr && cmpNow < startNr)) {
if (!(cmpNow >= endNr && cmpNow < startNr)) {
//this.debug('compare in time 2 ' + startNr + ' - ' + cmpNow + ' - ' + endNr);
this.send([msg, null]);

@@ -168,13 +200,16 @@ setstate(this, result, status, {

shape: "dot",
text: '🖅 ' + result.startSuffix + now.toLocaleString() + result.endSuffix //🖅
text: '🖅 ' + result.startSuffix + now.toLocaleString() + result.endSuffix
});
checkReSendMsgDelayed(config.lastMsgOnEndOut, this, result.end.value, msg);
return null;
}
}
//this.debug('compare out of time ' + startNr + ' - ' + cmpNow + ' - ' + endNr);
this.send([null, msg]);
setstate(this, result, status, {
fill: "yellow",
shape: "dot",
text: '⛔ ⏵' + result.start.value.toLocaleTimeString() + result.startSuffix + ' - ⏴' + result.end.value.toLocaleTimeString() + result.endSuffix
text: '⛔' + result.startSuffix + now.toLocaleString() + result.endSuffix
});
this.send([null, msg]);
checkReSendMsgDelayed(config.lastMsgOnStartOut, this, result.start.value, msg);
} catch (err) {

@@ -181,0 +216,0 @@ hlp.errorHandler(this, err, RED._("within-time-switch.errors.error-text"), RED._("within-time-switch.errors.error-title"));

{
"name": "node-red-contrib-sun-position",
"version": "0.1.13",
"version": "0.1.14-beta.6",
"description": "NodeRED nodes to get sun and moon position",

@@ -22,2 +22,4 @@ "main": "none",

"node-red",
"nodes",
"flow",
"sun-position",

@@ -38,3 +40,12 @@ "moon-position",

"inject",
"time"
"timer",
"time",
"timeswitch",
"timerswitch",
"time-range",
"time-range-switch",
"timecheck",
"compare",
"clock",
"schedule"
],

@@ -59,2 +70,5 @@ "homepage": "https://github.com/HM-RedMatic/node-red-contrib-sun-position",

},
"dependencies": {
"util": ">=0.10.0"
},
"extensions": [

@@ -61,0 +75,0 @@ "js",

@@ -17,3 +17,4 @@ # node-red-contrib-sun-position for NodeRED

This node are for getting sun and moon position or to control a flow by sun or moon position. This can be used for smart home.
This is a ultimate Node-Red Timer based flow control with dusk, dawn (and variations) and much more.
Addidional 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.

@@ -54,2 +55,12 @@ ![nodes](images/appearance1.png?raw=true)

## General
### Saving resources
The nodes are designed to do not calculate time events with every arriving message or with an interval every x time. This is to be able to handle a huge amount of messages also on even on computers with low resources.
### second based accuracy
The nodes are designed to be accurate to seconds. This means it was designed to turn on/off at exact given second. Other timers often work using intervals where they check your schedule only once a minute or even less. This means when you want something to come on at 08:00am, it may actually not come on until 30 seconds later. This nodes does not have this problem, it will come on at exactly 08:00:00am.
## Implemented Nodes

@@ -101,3 +112,3 @@

- `msg.payload.times.solarNoon` solar noon (sun is in the highest position)
- `msg.payload.times.goldenHour` evening golden hour starts
- `msg.payload.times.goldenHourStart` evening golden hour starts
- `msg.payload.times.sunsetStart` sunset starts (bottom edge of the sun touches the horizon)

@@ -142,3 +153,3 @@ - `msg.payload.times.sunset` sunset (sun disappears below the horizon, evening civil twilight starts)

"goldenHourEnd":"2018-12-10T07:58:28.541Z",
"goldenHour":"2018-12-10T14:00:01.086Z",
"goldenHourStart":"2018-12-10T14:00:01.086Z",
"dawn":"2018-12-10T06:19:31.249Z",

@@ -149,3 +160,3 @@ "dusk":"2018-12-10T15:38:58.379Z",

"nightStart":"2018-12-10T17:01:39.696Z",
"goldenHourStart":"2018-12-10T14:00:01.086Z"
"goldenHour":"2018-12-10T14:00:01.086Z"
},

@@ -289,7 +300,12 @@ "pos": [],

- **Start time** defines the start time of the time range with with different [configuration possibilities](#times-definitions)
- **Start Offset** allows to define a positive or negative offset in *seconds*, *minutes* or *hours* to the given **Start Time**. This will be useful for sun based times.
- **End time** defines the end time of the time range with with different [configuration possibilities](#times-definitions)
- **End Offset** allows to define a positive or negative offset in *seconds*, *minutes* or *hours* to the given **End Time**. This will be useful for sun based times.
- **Property** _optional_ here can be defined a boolean property. If it is true alternate start or and times will be used.
- **Alternate start time** _optional_ defines an alternate start time of the time range which will be used if the property is true. This can be used for different times for example of holidays.
- **Start time** alternate start time
- **Start Offset** offset for the alternate start time
- **Alternate end time** _optional_ defines an alternate end time of the time range which will be used if the property is true. This can be used for different times for example of holidays.
- **End time** alternate end time
- **End Offset** offset for the alternate end time
- **Status** here can be adjusted which status should be displayed under the node.

@@ -306,3 +322,6 @@ - this has the following posibilities:

- **time limits or last message** - on deploy/start until a message arrives the same behaviour 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.
- **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.
### Times definitions

@@ -319,37 +338,74 @@

- `00:00pm ... 12:59pm` 12h Format
- `00:00:00pm ... 12:59:00pm` 12h Format
- `00:00:00pm ... 12:59:00pm` 12h Format with seconds
#### sun times
following Sun times can be choosen:
| Time | Description |
| ------------------- | ------------------------------------------------------------------------ |
| `astronomicalDawn` | night ends (morning astronomical twilight starts) |
| `amateurDawn` | amateur astronomical dawn (sun at 12° before sunrise) |
| `nauticalDawn` | nautical dawn (morning nautical twilight starts) |
| `blueHourDawnStart` | blue Hour start (time for special photography photos starts) |
| `civilDawn` | dawn (morning nautical twilight ends, morning civil twilight starts) |
| `blueHourDawnEnd` | blue Hour end (time for special photography photos end) |
| `sunrise` | sunrise (top edge of the sun appears on the horizon) |
| `sunriseEnd` | sunrise ends (bottom edge of the sun touches the horizon) |
| `goldenHourEnd` | morning golden hour (soft light, best time for photography) ends |
| `solarNoon` | solar noon (sun is in the highest position) |
| `goldenHour` | evening golden hour starts |
| `sunsetStart` | sunset starts (bottom edge of the sun touches the horizon) |
| `sunset` | sunset (sun disappears below the horizon, evening civil twilight starts) |
| `blueHourDuskStart` | blue Hour start (time for special photography photos starts) |
| `civilDusk` | dusk (evening nautical twilight starts) |
| `blueHourDuskEnd` | blue Hour end (time for special photography photos end) |
| `nauticalDusk` | nautical dusk end (evening astronomical twilight starts) |
| `amateurDusk` | amateur astronomical dusk (sun at 12° after sunrise) |
| `astronomicalDusk` | night starts (dark enough for astronomical observations) |
| `nadir` | nadir (darkest moment of the night, sun is in the lowest position) |
| Time | Description | SunBH |
| ------------------- | ------------------------------------------------------------------------ | ----- |
| `astronomicalDawn` | night ends (morning astronomical twilight starts) | 18 |
| `amateurDawn` | amateur astronomical dawn (sun at 12° before sunrise) | 15 |
| `nauticalDawn` | nautical dawn (morning nautical twilight starts) | 12 |
| `blueHourDawnStart` | blue Hour start (time for special photography photos starts) | 8 |
| `civilDawn` | dawn (morning nautical twilight ends, morning civil twilight starts) | 6 |
| `blueHourDawnEnd` | blue Hour end (time for special photography photos end) | 4 |
| `sunrise` | sunrise (top edge of the sun appears on the horizon) | 0.833 |
| `sunriseEnd` | sunrise ends (bottom edge of the sun touches the horizon) | 0.3 |
| `goldenHourEnd` | morning golden hour (soft light, best time for photography) ends | -6 |
| `solarNoon` | solar noon (sun is in the highest position) | |
| `goldenHourStart` | evening golden hour starts | -6 |
| `sunsetStart` | sunset starts (bottom edge of the sun touches the horizon) | 0.3 |
| `sunset` | sunset (sun disappears below the horizon, evening civil twilight starts) | 0.833 |
| `blueHourDuskStart` | blue Hour start (time for special photography photos starts) | 4 |
| `civilDusk` | dusk (evening nautical twilight starts) | 6 |
| `blueHourDuskEnd` | blue Hour end (time for special photography photos end) | 8 |
| `nauticalDusk` | nautical dusk end (evening astronomical twilight starts) | 12 |
| `amateurDusk` | amateur astronomical dusk (sun at 12° after sunrise) | 15 |
| `astronomicalDusk` | night starts (dark enough for astronomical observations) | 18 |
| `nadir` | nadir (darkest moment of the night, sun is in the lowest position) | |
SunBH is the angle of the sun below the horizon
![sun times](images/sun-times.svg.png?raw=true)
##### remarks
###### blue hour
Although the blue hour does not have an official definition, the blue color spectrum is most prominent when the Sun is between 4° and 8° below the horizon.
###### amateurDawn /amateurDusk
This is not an official definition, this is happend when the Sun is 15° below the horizon
###### alternate properties
The following time parameters are exists in the output for backwart compatibility. These are equal to parameters in the table above:
| time parameter | is equal to |
| -------------- | ------------------ |
| `dawn` | `civilDawn` |
| `dusk` | `civilDusk` |
| `nightEnd` | `astronomicalDawn` |
| `night` | `astronomicalDusk` |
| `nightStart` | `astronomicalDusk` |
| `goldenHour` | `goldenHourStart` |
#### moon times
moon rise and moon set can be used
any message, flow or global property. It must contain a timestamp as one of the following formats:
#### message, flow or global property or JSONATA expression
any message, flow or global property which contain any of the following types:
- Integer which is a [Unix Time Stamp](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_16) representing the number of milliseconds since January 1, 1970, 00:00:00 UTC, with leap seconds ignored.
- String value representing a valid JavaScript date-string.
String as one of the following formats:
- `00:00 ... 23:59` 24h Format
- `00:00:00 ... 23:59:00` 24h Format with seconds
- `00:00pm ... 12:59pm` 12h Format
- `00:00:00pm ... 12:59:00pm` 12h Format
- `00:00:00pm ... 12:59:00pm` 12h Format with seconds

@@ -356,0 +412,0 @@ **Offsets:**

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
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc