node-red-contrib-schedex
Advanced tools
Comparing version 1.10.0 to 1.10.1
70
index.js
@@ -71,2 +71,3 @@ /** | ||
const node = this; | ||
const globalConfig = { debug: false }; | ||
const events = {}; | ||
@@ -76,2 +77,10 @@ // Assume the node is off initially | ||
function getGlobalConfig() { | ||
return _.assign(globalConfig, node.context().global.get('schedex')); | ||
} | ||
function debug(...args) { | ||
if (getGlobalConfig().debug) node.log.apply(node.log, args); | ||
} | ||
// Make sure these two props are proper booleans. | ||
@@ -151,4 +160,5 @@ config.onrandomoffset = !!config.onrandomoffset; | ||
} | ||
node.status({ fill, shape, text: message.join(' ') }); | ||
const text = message.join(' '); | ||
debug(`status: fill [${fill}] shape [${shape}] text [${text}]`); | ||
node.status({ fill, shape, text }); | ||
} | ||
@@ -158,2 +168,3 @@ | ||
lastEvent = event; | ||
debug(`send: topic [${event.topic}] payload [${event.payload}]`); | ||
node.send({ topic: event.topic, payload: event.payload }); | ||
@@ -181,37 +192,51 @@ setStatus(Status.FIRED, { event, manual }); | ||
const weekdayConfig = getWeekdayConfig(); | ||
event.moment = node.now(); | ||
let day = 0; | ||
event.moment = node.now().millisecond(0); | ||
if (firedNow) { | ||
// We've already fired today so start by examining tomorrow | ||
event.moment.add(1, 'day'); | ||
day = 1; | ||
} | ||
debug(`schedule: event fired now [${firedNow}] date [${event.moment.toString()}]`); | ||
let valid = false; | ||
let day = 0; | ||
const clockTime = new RegExp('(\\d+):(\\d+)', 'u').exec(event.time); | ||
// Today is day 0 and we try seven days into the future | ||
while (!valid && day <= 7) { | ||
const matches = new RegExp('(\\d+):(\\d+)', 'u').exec(event.time); | ||
if (matches && matches.length) { | ||
event.moment = event.moment.hour(+matches[1]).minute(+matches[2]); | ||
if (clockTime && clockTime.length) { | ||
event.moment = event.moment | ||
.hour(+clockTime[1]) | ||
.minute(+clockTime[2]) | ||
.second(0); | ||
} else { | ||
const sunCalcTimes = SunCalc.getTimes( | ||
event.moment.toDate(), | ||
config.lat, | ||
config.lon | ||
); | ||
const date = sunCalcTimes[event.time]; | ||
if (!date) { | ||
// #57 Suncalc appears to give the best results if you | ||
// calculate at midday. | ||
const sunDate = event.moment | ||
.hour(12) | ||
.minute(0) | ||
.second(0) | ||
.toDate(); | ||
const sunTimes = SunCalc.getTimes(sunDate, config.lat, config.lon); | ||
const sunTime = sunTimes[event.time]; | ||
if (!sunTime) { | ||
setStatus(Status.ERROR, { error: `Invalid time [${event.time}]` }); | ||
return false; | ||
} | ||
event.moment = moment(date); | ||
// #57 Nadir appears to work differently to other sun times | ||
// in that it will calculate tomorrow's nadir if the time is | ||
// too close to today's nadir. So we just take the time and | ||
// apply that to the event's moment. That's doesn't yield a | ||
// perfect suntime but it's close enough. | ||
event.moment | ||
.hour(sunTime.getHours()) | ||
.minute(sunTime.getMinutes()) | ||
.second(sunTime.getSeconds()); | ||
} | ||
event.moment.seconds(0).millisecond(0); | ||
if (event.offset) { | ||
let adjustment = event.offset; | ||
if (event.randomoffset) { | ||
adjustment = event.offset * Math.random(); | ||
} | ||
event.moment.add(adjustment, 'minutes'); | ||
event.moment.add( | ||
event.randomoffset ? event.offset * Math.random() : event.offset, | ||
'minutes' | ||
); | ||
} | ||
@@ -221,2 +246,3 @@ | ||
weekdayConfig[event.moment.isoWeekday() - 1] && event.moment.isAfter(now); | ||
debug(`schedule: day [${day}] [${event.moment.toString()}] valid [${valid}]`); | ||
if (!valid) { | ||
@@ -223,0 +249,0 @@ event.moment.add(1, 'day'); |
{ | ||
"name": "node-red-contrib-schedex", | ||
"version": "1.10.0", | ||
"version": "1.10.1", | ||
"description": "", | ||
@@ -38,4 +38,4 @@ "main": "index.js", | ||
"eslint-config-prettier": "^6.10.0", | ||
"eslint-plugin-import": "^2.20.0", | ||
"husky": "^4.2.1", | ||
"eslint-plugin-import": "^2.20.1", | ||
"husky": "^4.2.2", | ||
"lint-staged": "^10.0.7", | ||
@@ -42,0 +42,0 @@ "markdown-to-html": "0.0.13", |
@@ -148,1 +148,7 @@ # Schedex | ||
| `passthroughunhandled false` | Disabled unhandled input messages automatically being sent to output | | ||
### Enabling extra debugging | ||
Install `node-red-contrib-config` and drag a config node into your workspace. Configure the node to set a global variable called `schedex` | ||
with a JSON value of `{"debug": true}`. Also make sure that the config tickbox for `active` is unchecked. Redeploy. Now click the button on the config node. | ||
This will trigger all instances of `schedex` to write extra logging to the os syslog next time they're invoked. |
@@ -30,5 +30,10 @@ /* eslint-disable max-lines,max-lines-per-function */ | ||
const mock = require('node-red-contrib-mock-node'); | ||
const SunCalc = require('suncalc2'); | ||
const nodeRedModule = require('../index.js'); | ||
function newNode(configOverrides) { | ||
const enableDebug = (nrModule, node1) => { | ||
node1.context().global.set('schedex', { debug: true }); | ||
}; | ||
function newNode(configOverrides, preConfigureNodeCallback) { | ||
const config = { | ||
@@ -62,3 +67,3 @@ name: 'test-node', | ||
} | ||
return mock(nodeRedModule, config); | ||
return mock(nodeRedModule, config, null, preConfigureNodeCallback); | ||
} | ||
@@ -260,2 +265,31 @@ | ||
describe('schedex', function() { | ||
it('issue#57 nadir issues', function(done) { | ||
this.timeout(60000 * 5); | ||
console.log(`\t[${this.test.title}] will take 10-ish seconds, please wait...`); | ||
const node = newNode({ | ||
ontime: 'nadir', | ||
offtime: '', | ||
offoffset: 0, | ||
offrandomoffset: '0' | ||
}); | ||
// Nadir is 00:16:06 so set now to be just before | ||
// so it will fire within a few seconds. | ||
const now = moment('2020-02-14T00:16:01'); | ||
node.now = function() { | ||
return now.clone(); | ||
}; | ||
// Trigger some events so the node recalculates the on time | ||
node.emit('input', { payload: { suspended: true } }); | ||
node.emit('input', { payload: { suspended: false } }); | ||
const events = node.schedexEvents(); | ||
assert.strictEqual(events.on.moment.toISOString(), '2020-02-14T00:16:06.000Z'); | ||
setTimeout(function() { | ||
assert.strictEqual(node.sent(0).payload, 'on payload'); | ||
assert.strictEqual(node.sent(0).topic, 'on topic'); | ||
assert.strictEqual(events.on.moment.toISOString(), '2020-02-15T00:16:05.000Z'); | ||
done(); | ||
}, 10000); | ||
}); | ||
it('issue#66 should schedule correctly with a singular on or off', function(done) { | ||
@@ -424,3 +458,3 @@ this.timeout(60000 * 5); | ||
// Start with passthroughunhandled disabled, we should get nothing sent | ||
const node = newNode({ passthroughunhandled: false }); | ||
const node = newNode({ passthroughunhandled: false }, enableDebug); | ||
node.emit('input', { payload: 'wibble' }); | ||
@@ -440,6 +474,18 @@ assert.strictEqual(node.sent().length, 0); | ||
const now = moment('2019-10-26 22:00:00.000'); | ||
const node = newNode({ | ||
ontime: 'sunset', | ||
offtime: '21:00' | ||
}); | ||
const sunCalcTimes = SunCalc.getTimes( | ||
now | ||
.clone() | ||
.add(1, 'day') | ||
.hour(0) | ||
.minute(0) | ||
.second(0) | ||
.toDate(), | ||
51.5050793, | ||
-0.1225863 | ||
); | ||
console.log(sunCalcTimes.sunset); | ||
const node = newNode({ ontime: 'sunset', offtime: '21:00' }, enableDebug); | ||
node.now = function() { | ||
@@ -451,4 +497,9 @@ return now.clone(); | ||
node.emit('input', { payload: { suspended: false } }); | ||
// Expecting Sun Oct 27 2019 16:45:40 GMT+0000 | ||
// Expecting 2019-10-25T16:47:35.000Z | ||
// console.log(node.schedexEvents().on.moment.toString()); | ||
// const expected | ||
// assert.strictEqual( | ||
// node.schedexEvents().on.moment.toISOString(), | ||
// '2019-10-27T16:49:33.000Z' | ||
// ); | ||
assert.ok( | ||
@@ -471,2 +522,15 @@ node.schedexEvents().on.moment.isSame(moment('2019-10-27 16:45:00.000'), 'minute'), | ||
}; | ||
const sunCalcTimes = SunCalc.getTimes( | ||
now | ||
.clone() | ||
.hour(0) | ||
.minute(0) | ||
.second(0) | ||
.toDate(), | ||
51.5050793, | ||
-0.1225863 | ||
); | ||
console.log(sunCalcTimes.sunset); | ||
// Trigger some events so the node recalculates the on time | ||
@@ -473,0 +537,0 @@ node.emit('input', { payload: { suspended: true } }); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
89440
1289
154