Skip to content

Commit

Permalink
Locale awareness and fix for config overwriting
Browse files Browse the repository at this point in the history
- Time calculation and conversion using moment is now locale aware
- Fix for configuration of coordinates and custom sun times being
  overwritten by node instances
  • Loading branch information
jensrossbach committed Feb 20, 2021
1 parent 63aa35c commit 6fb327d
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 84 deletions.
Binary file modified images/delay.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 4 additions & 29 deletions nodes/change.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ module.exports = function(RED)

node.chronos = require("./common/chronos.js");
node.config = RED.nodes.getNode(settings.config);
node.locale = require("os-locale").sync();

if (!node.config)
{
Expand All @@ -45,9 +46,7 @@ module.exports = function(RED)
else
{
node.debug("Starting node with configuration '" + node.config.name + "' (latitude " + node.config.latitude + ", longitude " + node.config.longitude + ")");

node.status({});
node.chronos.init(RED, node.config.latitude, node.config.longitude, node.config.sunPositions);

node.rules = settings.rules;

Expand Down Expand Up @@ -125,7 +124,7 @@ module.exports = function(RED)
}
case "date":
{
setTarget(msg, rule.target, node.chronos.getTime(node.chronos.getUserDate(rule.date), rule.time.type, rule.time.value).valueOf());
setTarget(msg, rule.target, node.chronos.getTime(RED, node, node.chronos.getUserDate(RED, node, rule.date), rule.time.type, rule.time.value).valueOf());
break;
}
}
Expand All @@ -137,7 +136,7 @@ module.exports = function(RED)

if (property && ((typeof property == "number") || (typeof property == "string")))
{
input = node.chronos.getTimeFrom(property);
input = node.chronos.getTimeFrom(node, property);
if (!input.isValid())
{
input = null;
Expand Down Expand Up @@ -176,21 +175,7 @@ module.exports = function(RED)
}
case "weekday":
{
// we use MO..SU == 1..7, but moment uses SU..SA == 0..6
if (rule.value < 7)
{
input.day(rule.value);
}
else
{
if (input.day() > 0)
{
input.add(1, "week"); // add one week to have the next Sunday
}

input.day(0);
}

input.weekday(rule.value - 1);
break;
}
case "day":
Expand Down Expand Up @@ -238,22 +223,12 @@ module.exports = function(RED)
case "startOf":
{
input.startOf(rule.arg);
if (rule.arg == "week") // start of week = MO <-> SU
{
input.add(1, "day");
}

output = input.valueOf();
break;
}
case "endOf":
{
input.endOf(rule.arg);
if (rule.arg == "week") // end of week = SU <-> SA
{
input.add(1, "day");
}

output = input.valueOf();
break;
}
Expand Down
70 changes: 38 additions & 32 deletions nodes/common/chronos.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,45 +37,40 @@ class TimeError extends Error
}
}

var RED;

var latitude = 0;
var longitude = 0;
const moment = require("moment");
const sunCalc = require("suncalc");

var moment;
var sunCalc;


function init(_RED, _latitude, _longitude, additionalTimes)
function initCustomTimes(times)
{
RED = _RED;

latitude = _latitude;
longitude = _longitude;

moment = require("moment");
sunCalc = require("suncalc");

if (additionalTimes)
if (times)
{
additionalTimes.forEach(time =>
times.forEach(time =>
{
console.log("Adding custom time " + time.riseName + "/" + time.setName + "@" + time.angle);
sunCalc.addTime(time.angle, "__cust_" + time.riseName, "__cust_" + time.setName);
});
}
}

function getCurrentTime()
function getCurrentTime(node)
{
return moment();
let ret = moment();
ret.locale(node.locale);

return ret;
}

function getTimeFrom(source)
function getTimeFrom(node, source)
{
return moment(source);
let ret = moment(source);
ret.locale(node.locale);

return ret;
}

function getUserTime(day, value)
function getUserTime(RED, day, value)
{
let ret = null;

Expand Down Expand Up @@ -123,13 +118,14 @@ function getUserTime(day, value)
return ret;
}

function getUserDate(value)
function getUserDate(RED, node, value)
{
let ret = null;

if (DATE_REGEX.test(value))
{
ret = moment(value, "YYYY-MM-DD");
ret.locale(node.locale);
}

if (!ret || !ret.isValid())
Expand All @@ -150,9 +146,10 @@ function isValidUserDate(value)
return DATE_REGEX.test(value);
}

function getSunTime(day, type)
function getSunTime(RED, node, day, type)
{
let sunTimes = sunCalc.getTimes(day.toDate(), latitude, longitude);
node.debug("Calculating sun time for " + type + " at location " + node.config.latitude + ", " + node.config.longitude);
let sunTimes = sunCalc.getTimes(day.toDate(), node.config.latitude, node.config.longitude);

if (!(type in sunTimes))
{
Expand All @@ -167,6 +164,10 @@ function getSunTime(day, type)
{
ret = null;
}
else
{
ret.locale(node.locale);
}
}

if (!ret)
Expand All @@ -177,9 +178,10 @@ function getSunTime(day, type)
return ret;
}

function getMoonTime(day, type)
function getMoonTime(RED, node, day, type)
{
let moonTimes = sunCalc.getMoonTimes(day.toDate(), latitude, longitude);
node.debug("Calculating moon time for " + type + " at location " + node.config.latitude + ", " + node.config.longitude);
let moonTimes = sunCalc.getMoonTimes(day.toDate(), node.config.latitude, node.config.longitude);

let ret = null;
if (moonTimes[type])
Expand All @@ -189,6 +191,10 @@ function getMoonTime(day, type)
{
ret = null;
}
else
{
ret.locale(node.locale);
}
}

if (!ret)
Expand All @@ -199,26 +205,26 @@ function getMoonTime(day, type)
return ret;
}

function getTime(day, type, value)
function getTime(RED, node, day, type, value)
{
if (type == "time")
{
return getUserTime(day, value);
return getUserTime(RED, day, value);
}
else if ((type == "sun") || (type == "custom"))
{
return getSunTime(day.set({"hour": 12, "minute": 0, "second": 0, "millisecond": 0}), (type == "custom") ? "__cust_" + value : value);
return getSunTime(RED, node, day.set({"hour": 12, "minute": 0, "second": 0, "millisecond": 0}), (type == "custom") ? "__cust_" + value : value);
}
else if (type == "moon")
{
return getMoonTime(day.set({"hour": 12, "minute": 0, "second": 0, "millisecond": 0}), value);
return getMoonTime(RED, node, day.set({"hour": 12, "minute": 0, "second": 0, "millisecond": 0}), value);
}
}


module.exports =
{
init: init,
initCustomTimes: initCustomTimes,
getCurrentTime: getCurrentTime,
getTimeFrom: getTimeFrom,
getUserTime: getUserTime,
Expand Down
10 changes: 5 additions & 5 deletions nodes/common/sfutils.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ function evaluateCondition(RED, node, baseTime, cond, id)
}
else if ((cond.operator == "before") || (cond.operator == "after"))
{
let targetTime = node.chronos.getTime(baseTime.clone(), cond.operands.type, cond.operands.value);
let targetTime = node.chronos.getTime(RED, node, baseTime.clone(), cond.operands.type, cond.operands.value);

if (cond.operands.offset != 0)
{
Expand All @@ -241,8 +241,8 @@ function evaluateCondition(RED, node, baseTime, cond, id)
}
else if ((cond.operator == "between") || (cond.operator == "outside"))
{
let time1 = node.chronos.getTime(baseTime.clone(), cond.operands[0].type, cond.operands[0].value);
let time2 = node.chronos.getTime(baseTime.clone(), cond.operands[1].type, cond.operands[1].value);
let time1 = node.chronos.getTime(RED, node, baseTime.clone(), cond.operands[0].type, cond.operands[0].value);
let time2 = node.chronos.getTime(RED, node, baseTime.clone(), cond.operands[1].type, cond.operands[1].value);

if (cond.operands[0].offset != 0)
{
Expand Down Expand Up @@ -309,7 +309,7 @@ function getBaseTime(RED, node, msg)

if (node.baseTimeType == "msgIngress")
{
ret = node.chronos.getCurrentTime();
ret = node.chronos.getCurrentTime(node);
}
else
{
Expand All @@ -332,7 +332,7 @@ function getBaseTime(RED, node, msg)

if (typeof value == "number")
{
ret = node.chronos.getTimeFrom(value);
ret = node.chronos.getTimeFrom(node, value);
}
}

Expand Down
6 changes: 4 additions & 2 deletions nodes/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ module.exports = function(RED)
{
function ChronosConfigNode(config)
{
const chronos = require("./common/chronos.js");

RED.nodes.createNode(this, config);

this.name = config.name;
this.sunPositions = config.sunPositions;

this.latitude = parseFloat(this.credentials.latitude);
this.longitude = parseFloat(this.credentials.longitude);

chronos.initCustomTimes(config.sunPositions);
}

RED.nodes.registerType("chronos-config", ChronosConfigNode,
Expand Down
30 changes: 24 additions & 6 deletions nodes/delay.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ module.exports = function(RED)
RED.nodes.createNode(node, settings);

node.config = RED.nodes.getNode(settings.config);
node.locale = require("os-locale").sync();

if (!node.config)
{
Expand All @@ -41,9 +42,7 @@ module.exports = function(RED)
else
{
node.debug("Starting node with configuration '" + node.config.name + "' (latitude " + node.config.latitude + ", longitude " + node.config.longitude + ")");

node.status({});
chronos.init(RED, node.config.latitude, node.config.longitude, node.config.sunPositions);

node.whenType = settings.whenType;
node.whenValue = settings.whenValue;
Expand Down Expand Up @@ -214,8 +213,8 @@ module.exports = function(RED)
{
node.debug("Set up timer for type '" + type + "', value '" + value + "'");

const now = chronos.getCurrentTime();
node.sendTime = chronos.getTime(now.clone(), type, value);
const now = chronos.getCurrentTime(node);
node.sendTime = chronos.getTime(RED, node, now.clone(), type, value);

if (offset != 0)
{
Expand All @@ -232,7 +231,7 @@ module.exports = function(RED)
}
else
{
node.sendTime = chronos.getTime(node.sendTime.add(1, "days"), type, value);
node.sendTime = chronos.getTime(RED, node, node.sendTime.add(1, "days"), type, value);
}
}

Expand Down Expand Up @@ -292,7 +291,26 @@ module.exports = function(RED)

function updateStatus()
{
node.status(((node.msgQueue.length > 0) && node.sendTime) ? {fill: "blue", shape: "dot", text: node.msgQueue.length + " " + RED._("delay.status.queued") + " " + node.sendTime.format("YYYY-MM-DD HH:mm:ss")} : {});
if ((node.msgQueue.length > 0) && node.sendTime)
{
let when = node.sendTime.calendar(
{
sameDay: function()
{
return "LT" + ((this.second() > 0) ? "S" : "");
},
nextDay: function()
{
return "l LT" + ((this.second() > 0) ? "S" : "");
}
});

node.status({fill: "blue", shape: "dot", text: node.msgQueue.length + " " + RED._("delay.status.queued") + " " + when});
}
else
{
node.status({});
}
}
}

Expand Down
3 changes: 1 addition & 2 deletions nodes/filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ module.exports = function(RED)

node.chronos = require("./common/chronos.js");
node.config = RED.nodes.getNode(settings.config);
node.locale = require("os-locale").sync();

if (!node.config)
{
Expand All @@ -47,9 +48,7 @@ module.exports = function(RED)
else
{
node.debug("Starting node with configuration '" + node.config.name + "' (latitude " + node.config.latitude + ", longitude " + node.config.longitude + ")");

node.status({});
node.chronos.init(RED, node.config.latitude, node.config.longitude, node.config.sunPositions);

node.baseTime = settings.baseTime;
node.baseTimeType = settings.baseTimeType;
Expand Down
Loading

0 comments on commit 6fb327d

Please sign in to comment.