Socket
Socket
Sign inDemoInstall

node-red-contrib-schedex

Package Overview
Dependencies
3
Maintainers
1
Versions
41
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.2.1 to 1.3.0

151

index.js

@@ -1,2 +0,2 @@

/* eslint-disable no-invalid-this,consistent-this */
/* eslint-disable no-invalid-this,consistent-this,max-lines-per-function */
/**

@@ -32,12 +32,18 @@ * The MIT License (MIT)

const Status = Object.freeze({
SCHEDULED: Symbol('scheduled'),
SUSPENDED: Symbol('suspended'),
FIRED: Symbol('fired'),
ERROR: Symbol('error')
});
RED.nodes.registerType('schedex', function(config) {
RED.nodes.createNode(this, config);
const node = this,
events = {
on: setupEvent('on', 'dot'),
off: setupEvent('off', 'ring')
};
events.on.inverse = events.off;
events.off.inverse = events.on;
events = { on: setupEvent('on', 'dot'), off: setupEvent('off', 'ring') };
function inverse(event) {
return event === events.on ? events.off : events.on;
}
// migration code : if new values are undefined, set all to true

@@ -60,3 +66,3 @@ if (

const weekdays = [
const weekdays = Object.freeze([
config.mon,

@@ -69,3 +75,3 @@ config.tue,

config.sun
];
]);

@@ -96,3 +102,5 @@ node.on('input', function(msg) {

? 'suspended'
: events.off.moment.isAfter(events.on.moment) ? 'off' : 'on',
: events.off.moment.isAfter(events.on.moment)
? 'off'
: 'on',
ontopic: events.on.topic,

@@ -105,11 +113,4 @@ onpayload: events.on.payload,

} else {
if (msg.payload.indexOf('suspended') !== -1) {
handled = true;
const match = /.*suspended\s+(\S+)/.exec(msg.payload);
const previous = config.suspended;
config.suspended = toBoolean(match[1]);
requiresBootstrap = requiresBootstrap || previous !== config.suspended;
}
enumerateProgrammables(function(obj, prop, payloadName, typeConverter) {
const match = new RegExp(`.*${payloadName}\\s+(\\S+)`).exec(
const match = new RegExp(`.*${payloadName}\\s+(\\S+)`, 'u').exec(
msg.payload

@@ -126,8 +127,2 @@ );

} else {
if (msg.payload.hasOwnProperty('suspended')) {
handled = true;
const previous = config.suspended;
config.suspended = !!msg.payload.suspended;
requiresBootstrap = requiresBootstrap || previous !== config.suspended;
}
enumerateProgrammables(function(obj, prop, payloadName, typeConverter) {

@@ -143,7 +138,3 @@ if (msg.payload.hasOwnProperty(payloadName)) {

if (!handled) {
node.status({
fill: 'red',
shape: 'dot',
text: 'Unsupported input'
});
setStatus(Status.ERROR, { error: 'Unsupported input' });
} else if (requiresBootstrap) {

@@ -173,21 +164,12 @@ bootstrap();

function send(event, manual) {
node.send({
topic: event.topic,
payload: event.payload
});
node.status({
fill: manual ? 'blue' : 'green',
shape: event.shape,
text:
event.name +
(manual ? ' manual' : ' auto') +
(isSuspended()
? ' - scheduling suspended'
: ` until ${event.inverse.moment.format(fmt)}`)
});
node.send({ topic: event.topic, payload: event.payload });
setStatus(Status.FIRED, { event, manual });
}
function schedule(event, isInitial) {
if (!event.time) {
return true;
}
const now = node.now();
const matches = new RegExp(/(\d+):(\d+)/).exec(event.time);
const matches = new RegExp('(\\d+):(\\d+)', 'u').exec(event.time);
if (matches && matches.length) {

@@ -207,7 +189,3 @@ // Don't use existing 'now' moment here as hour and minute mutate the moment.

if (!event.moment) {
node.status({
fill: 'red',
shape: 'dot',
text: `Invalid time: ${event.time}`
});
setStatus(Status.ERROR, { error: `Invalid time [${event.time}]` });
return false;

@@ -247,9 +225,3 @@ }

events.off.moment = null;
node.status({
fill: 'grey',
shape: 'dot',
text: `Scheduling suspended ${
weekdays.indexOf(true) === -1 ? '(no weekdays selected) ' : ''
} - manual mode only`
});
setStatus(Status.SUSPENDED);
}

@@ -259,16 +231,54 @@

if (schedule(events.on, true) && schedule(events.off, true)) {
const firstEvent = events.on.moment.isBefore(events.off.moment)
? events.on
: events.off;
const message = `${firstEvent.name} ${firstEvent.moment.format(fmt)}, ${
firstEvent.inverse.name
} ${firstEvent.inverse.moment.format(fmt)}`;
node.status({
fill: 'yellow',
shape: 'dot',
text: message
});
setStatus(Status.SCHEDULED);
}
}
function setStatus(status, { event = null, manual = false, error = null } = {}) {
const message = [];
let shape = 'dot',
fill = 'red';
if (status === Status.SCHEDULED) {
fill = 'yellow';
if (events.on.moment && events.off.moment) {
const firstEvent = events.on.moment.isBefore(events.off.moment)
? events.on
: events.off;
message.push(firstEvent.name);
message.push(firstEvent.moment.format(fmt));
message.push(inverse(firstEvent).name);
message.push(inverse(firstEvent).moment.format(fmt));
} else if (events.on.moment) {
message.push(events.on.name);
message.push(events.on.moment.format(fmt));
} else if (events.off.moment) {
message.push(events.off.name);
message.push(events.off.moment.format(fmt));
}
} else if (status === Status.FIRED) {
// eslint-disable-next-line prefer-destructuring
shape = event.shape;
fill = manual ? 'blue' : 'green';
message.push(event.name);
message.push(manual ? 'manual' : 'auto');
if (isSuspended()) {
message.push('- scheduling suspended');
} else {
message.push(`until ${inverse(event).moment.format(fmt)}`);
}
} else if (status === Status.SUSPENDED) {
fill = 'grey';
message.push('Scheduling suspended');
if (weekdays.indexOf(true) === -1) {
message.push('(no weekdays selected)');
} else if (!events.on.time && !events.off.time) {
message.push('(no on or off time)');
}
message.push('- manual mode only');
} else if (status === Status.ERROR) {
message.push(error);
}
node.status({ fill, shape, text: message.join(' ') });
}
function bootstrap() {

@@ -283,3 +293,7 @@ if (isSuspended()) {

function isSuspended() {
return config.suspended || weekdays.indexOf(true) === -1;
return (
config.suspended ||
weekdays.indexOf(true) === -1 ||
(!events.on.time && !events.off.time)
);
}

@@ -307,2 +321,3 @@

callback(config, 'lat', 'lat', Number);
callback(config, 'suspended', 'suspended', toBoolean);
}

@@ -309,0 +324,0 @@

{
"name": "node-red-contrib-schedex",
"version": "1.2.1",
"version": "1.3.0",
"description": "",
"main": "index.js",
"keywords": ["node-red", "schedule", "scheduler", "timer", "sun events"],
"keywords": [
"node-red",
"schedule",
"scheduler",
"timer",
"sun events"
],
"scripts": {

@@ -21,17 +27,17 @@ "test": "nyc --reporter=html node_modules/.bin/mocha -R spec ./tests/test.js",

"dependencies": {
"lodash": "^4.17.10",
"moment": "^2.22.1",
"lodash": "^4.17.11",
"moment": "^2.22.2",
"suncalc": "^1.8.0"
},
"devDependencies": {
"chai": "^4.1.2",
"eslint": "^4.19.1",
"chai": "^4.2.0",
"eslint": "^5.7.0",
"eslint-config-biddster": "^0.6.0",
"eslint-config-prettier": "^2.9.0",
"eslint-config-prettier": "^3.1.0",
"markdown-to-html": "0.0.13",
"mocha": "^5.1.1",
"mocha": "^5.2.0",
"node-red-contrib-mock-node": "^0.4.0",
"nsp": "^3.2.1",
"nyc": "^11.8.0",
"prettier": "^1.12.1"
"nyc": "^13.1.0",
"prettier": "^1.14.3"
},

@@ -49,3 +55,6 @@ "node-red": {

},
"extends": ["eslint-config-biddster/es6-node", "prettier"]
"extends": [
"eslint-config-biddster/es6-node",
"prettier"
]
},

@@ -56,3 +65,6 @@ "prettier": {

"printWidth": 96
},
"nyc": {
"exclude": "tests/**"
}
}

@@ -15,3 +15,3 @@ # Schedex

This node requires node 4.x. It's tested against 4.6.1.
This node requires node 6.x+. It's tested against 6.14.2.

@@ -33,7 +33,10 @@ $ cd ~/.node-red

This setting is provided for the situation where you temporarily don't want time based activation and don't want to
rewire your Node-RED flow.
This setting is provided for the situation where you temporarily don't want time based activation and don't want to rewire your Node-RED flow.
> Note that scheduling is suspended if you do not enter an on or off time in the node configuration.
## Times
> Note that on and off times are independent. You only need to configure one or the other or both. You can leave the on or off time field blank in the node configuration and no output will be emitted.
The times can be a 24 hour time or a [suncalc](https://github.com/mourner/suncalc) event:

@@ -59,2 +62,3 @@

## Offsets

@@ -119,17 +123,17 @@

| Example msg.payload | Description |
| ---------------------------------------------- | ------------------------------------------------------------ |
| `suspended true` | true will suspend scheduling, false will resume scheduling |
| `ontime 12:00` | Time as specified in the table above for time configuration |
| `ontopic my_topic` | Sets the topic for the on event (no spaces) |
| `onpayload my_payload` | Sets the payload for the on event (no spaces) |
| `onoffset 30` | Sets the offset for the on event |
| `onrandomoffset true` | Sets the random offset for the on event |
| `offtime dusk` | Time as specified in the table above for time configuration |
| `offtopic my_topic` | Sets the topic for the off event (no spaces) |
| `offpayload my_payload` | Sets the payload for the off event (no spaces) |
| `offoffset -30` | Sets the offset for the off event |
| `offrandomoffset false` | Sets the random offset for the off event |
| `mon false` | Disables the schedule on a Monday |
| `tue true` | Enables the schedule on a Tuesday |
| `ontime 16:30 onoffset 60 onrandomoffset true` | Sets the time, offset and random offset for the on event |
| Example msg.payload | Description |
| ---------------------------------------------- | ----------------------------------------------------------- |
| `suspended true` | true will suspend scheduling, false will resume scheduling |
| `ontime 12:00` | Time as specified in the table above for time configuration |
| `ontopic my_topic` | Sets the topic for the on event (no spaces) |
| `onpayload my_payload` | Sets the payload for the on event (no spaces) |
| `onoffset 30` | Sets the offset for the on event |
| `onrandomoffset true` | Sets the random offset for the on event |
| `offtime dusk` | Time as specified in the table above for time configuration |
| `offtopic my_topic` | Sets the topic for the off event (no spaces) |
| `offpayload my_payload` | Sets the payload for the off event (no spaces) |
| `offoffset -30` | Sets the offset for the off event |
| `offrandomoffset false` | Sets the random offset for the off event |
| `mon false` | Disables the schedule on a Monday |
| `tue true` | Enables the schedule on a Tuesday |
| `ontime 16:30 onoffset 60 onrandomoffset true` | Sets the time, offset and random offset for the on event |

@@ -0,1 +1,2 @@

/* eslint-disable max-lines,max-lines-per-function */
/**

@@ -34,2 +35,37 @@ * The MIT License (MIT)

describe('schedex', function() {
it('should visually indicate manual on off', function() {
let node = newNode();
node.emit('input', { payload: 'on' });
console.log(node.status().text);
assert(node.status().text.indexOf('ON manual until') === 0);
node = newNode();
node.emit('input', { payload: 'off' });
assert(node.status().text.indexOf('OFF manual until') === 0);
});
it('issue#22: should schedule correctly with ontime no offtime', function() {
const node = newNode({
ontime: '23:59',
offtime: ''
});
assert.strictEqual(node.status().text, `ON ${moment().format('YYYY-MM-DD')} 23:59`);
});
it('issue#22: should schedule correctly with offtime no ontime', function() {
const node = newNode({
ontime: '',
offtime: '23:59',
offoffset: 0
});
assert.strictEqual(node.status().text, `OFF ${moment().format('YYYY-MM-DD')} 23:59`);
});
it('issue#22: should indicate scheduling suspended if no on or off time', function() {
const node = newNode({
ontime: '',
offtime: ''
});
assert.strictEqual(
node.status().text,
'Scheduling suspended (no on or off time) - manual mode only'
);
});
it('should schedule initially', function() {

@@ -120,3 +156,3 @@ const node = newNode();

});
assert.strictEqual(node.status().text, 'Invalid time: 5555');
assert.strictEqual(node.status().text, 'Invalid time [5555]');
});

@@ -123,0 +159,0 @@ it('should suspend initially', function() {

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc