node-red-contrib-sun-position
Advanced tools
Comparing version 0.1.13 to 0.1.14-beta.6
@@ -0,0 +0,0 @@ module.exports = { |
@@ -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", |
116
README.md
@@ -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
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
2699
440
699729
1
60
+ Addedutil@>=0.10.0
+ Addedavailable-typed-arrays@1.0.7(transitive)
+ Addedcall-bind@1.0.7(transitive)
+ Addeddefine-data-property@1.1.4(transitive)
+ Addedes-define-property@1.0.0(transitive)
+ Addedes-errors@1.3.0(transitive)
+ Addedfor-each@0.3.3(transitive)
+ Addedfunction-bind@1.1.2(transitive)
+ Addedget-intrinsic@1.2.4(transitive)
+ Addedgopd@1.0.1(transitive)
+ Addedhas-property-descriptors@1.0.2(transitive)
+ Addedhas-proto@1.0.3(transitive)
+ Addedhas-symbols@1.0.3(transitive)
+ Addedhas-tostringtag@1.0.2(transitive)
+ Addedhasown@2.0.2(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedis-arguments@1.1.1(transitive)
+ Addedis-callable@1.2.7(transitive)
+ Addedis-generator-function@1.0.10(transitive)
+ Addedis-typed-array@1.1.13(transitive)
+ Addedpossible-typed-array-names@1.0.0(transitive)
+ Addedset-function-length@1.2.2(transitive)
+ Addedutil@0.12.5(transitive)
+ Addedwhich-typed-array@1.1.15(transitive)