From 29694dd2cba5f0e8b3d5c6b6dba177890ef39105 Mon Sep 17 00:00:00 2001
From: JJ Cantillon
Date: Mon, 8 Jan 2018 01:26:57 +1000
Subject: [PATCH 001/456] make exif node add exif data even if gps missing
(#393)
---
utility/exif/94-exif.js | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/utility/exif/94-exif.js b/utility/exif/94-exif.js
index e4cbb887..316e04f9 100644
--- a/utility/exif/94-exif.js
+++ b/utility/exif/94-exif.js
@@ -73,13 +73,17 @@ module.exports = function(RED) {
node.log(error.toString());
}
else {
- //msg.payload remains the same buffer
- if ((exifData) && (exifData.hasOwnProperty("gps")) && (Object.keys(exifData.gps).length !== 0)) {
+ if (exifData) {
msg.exif = exifData;
- addMsgLocationDataFromExifGPSData(msg);
+ if((exifData.hasOwnProperty("gps")) && (Object.keys(exifData.gps).length !== 0)) {
+ addMsgLocationDataFromExifGPSData(msg);
+ }
+ else {
+ node.log("The incoming image did not contain Exif GPS data.");
+ }
}
else {
- node.warn("The incoming image did not contain Exif GPS data, nothing to do. ");
+ node.warn("The incoming image did not contain any Exif data, nothing to do. ");
}
}
node.send(msg);
From dbea8a484acbadde88359b104176c1c5a320a373 Mon Sep 17 00:00:00 2001
From: borpin
Date: Sun, 7 Jan 2018 15:37:28 +0000
Subject: [PATCH 002/456] Updates to match API changes (#392)
* Updates to match API changes
Update to the node to match the server API changes. An attempt has been made to leave a legacy path for existing installations that may have not updated the server side.
* Updated following comments.
Update following comments.
Output removed and node.warn or error used.
oneeditprepare added.
Name moved to last item.
In addition, a check added to ensure nodegroup has valid value.
Question: I have added a 'return' as I do not want data posted if there is not a valid nodegroup. Is this the best way to exit the function? Always taught that multiple exits was a bad idea. I wondered about raising an error / exception and then catching it but not sure how to do that.
* Update documentation for revised node
---
io/emoncms/88-emoncms.html | 40 ++++++++++++-----
io/emoncms/88-emoncms.js | 91 +++++++++++++++++++++++++++++++-------
io/emoncms/README.md | 36 +++++++++------
3 files changed, 126 insertions(+), 41 deletions(-)
diff --git a/io/emoncms/88-emoncms.html b/io/emoncms/88-emoncms.html
index 21fe4a9a..65789671 100644
--- a/io/emoncms/88-emoncms.html
+++ b/io/emoncms/88-emoncms.html
@@ -6,22 +6,36 @@
-
+
+
+
+
+
+
-
-
-
-
\ No newline at end of file
+
diff --git a/io/snmp/snmp.js b/io/snmp/snmp.js
index 008d5995..9207217d 100644
--- a/io/snmp/snmp.js
+++ b/io/snmp/snmp.js
@@ -5,10 +5,10 @@ module.exports = function (RED) {
var sessions = {};
- function getSession(host, community, version) {
+ function getSession(host, community, version, timeout) {
var sessionKey = host + ":" + community + ":" + version;
if (!(sessionKey in sessions)) {
- sessions[sessionKey] = snmp.createSession(host, community, { version: version });
+ sessions[sessionKey] = snmp.createSession(host, community, { version:version, timeout:(timeout || 5000) });
}
return sessions[sessionKey];
}
@@ -19,6 +19,7 @@ module.exports = function (RED) {
this.host = n.host;
this.version = (n.version === "2c") ? snmp.Version2c : snmp.Version1;
this.oids = n.oids.replace(/\s/g, "");
+ this.timeout = Number(n.timeout || 5) * 1000;
var node = this;
this.on("input", function (msg) {
@@ -26,7 +27,7 @@ module.exports = function (RED) {
var community = node.community || msg.community;
var oids = node.oids || msg.oid;
if (oids) {
- getSession(host, community, node.version).get(oids.split(","), function (error, varbinds) {
+ getSession(host, community, node.version, node.timeout).get(oids.split(","), function (error, varbinds) {
if (error) {
node.error(error.toString(), msg);
}
@@ -54,13 +55,13 @@ module.exports = function (RED) {
}
RED.nodes.registerType("snmp", SnmpNode);
-
function SnmpSNode(n) {
RED.nodes.createNode(this, n);
this.community = n.community;
this.host = n.host;
this.version = (n.version === "2c") ? snmp.Version2c : snmp.Version1;
this.varbinds = n.varbinds;
+ this.timeout = Number(n.timeout || 5) * 1000;
var node = this;
this.on("input", function (msg) {
var host = node.host || msg.host;
@@ -70,7 +71,7 @@ module.exports = function (RED) {
for (var i = 0; i < varbinds.length; i++) {
varbinds[i].type = snmp.ObjectType[varbinds[i].type];
}
- getSession(host, community, node.version).set(varbinds, function (error, varbinds) {
+ getSession(host, community, node.version, node.timeout).set(varbinds, function (error, varbinds) {
if (error) {
node.error(error.toString(), msg);
}
@@ -93,14 +94,13 @@ module.exports = function (RED) {
RED.nodes.registerType("snmp set", SnmpSNode);
-
-
function SnmpTNode(n) {
RED.nodes.createNode(this, n);
this.community = n.community;
this.host = n.host;
this.version = (n.version === "2c") ? snmp.Version2c : snmp.Version1;
this.oids = n.oids.replace(/\s/g, "");
+ this.timeout = Number(n.timeout || 5) * 1000;
var node = this;
var maxRepetitions = 20;
@@ -116,7 +116,7 @@ module.exports = function (RED) {
var oids = node.oids || msg.oid;
if (oids) {
msg.oid = oids;
- getSession(host, community, node.version).table(oids, maxRepetitions, function (error, table) {
+ getSession(host, community, node.version, node.timeout).table(oids, maxRepetitions, function (error, table) {
if (error) {
node.error(error.toString(), msg);
}
@@ -153,12 +153,14 @@ module.exports = function (RED) {
}
RED.nodes.registerType("snmp table", SnmpTNode);
+
function SnmpSubtreeNode(n) {
RED.nodes.createNode(this, n);
this.community = n.community;
this.host = n.host;
this.version = (n.version === "2c") ? snmp.Version2c : snmp.Version1;
this.oids = n.oids.replace(/\s/g, "");
+ this.timeout = Number(n.timeout || 5) * 1000;
var node = this;
var maxRepetitions = 20;
var response = [];
@@ -181,7 +183,7 @@ module.exports = function (RED) {
var oids = node.oids || msg.oid;
if (oids) {
msg.oid = oids;
- getSession(host, community, node.version).subtree(msg.oid, maxRepetitions, feedCb, function (error) {
+ getSession(host, community, node.version, node.timeout).subtree(msg.oid, maxRepetitions, feedCb, function (error) {
if (error) {
node.error(error.toString(), msg);
}
@@ -200,12 +202,14 @@ module.exports = function (RED) {
}
RED.nodes.registerType("snmp subtree", SnmpSubtreeNode);
+
function SnmpWalkerNode(n) {
RED.nodes.createNode(this, n);
this.community = n.community;
this.host = n.host;
this.version = (n.version === "2c") ? snmp.Version2c : snmp.Version1;
this.oids = n.oids.replace(/\s/g, "");
+ this.timeout = Number(n.timeout || 5) * 1000;
var node = this;
var maxRepetitions = 20;
var response = [];
@@ -229,7 +233,7 @@ module.exports = function (RED) {
var community = node.community || msg.community;
if (oids) {
msg.oid = oids;
- getSession(host, community, node.version).walk(msg.oid, maxRepetitions, feedCb, function (error) {
+ getSession(host, community, node.version, node.timeout).walk(msg.oid, maxRepetitions, feedCb, function (error) {
if (error) {
node.error(error.toString(), msg);
}
From 4ed7ab590d048881e3642384e0aefa2a85c84f92 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Mon, 29 Jan 2018 09:16:35 +0000
Subject: [PATCH 010/456] reinstate feed parser useragent
---
social/feedparser/32-feedparse.js | 6 +++---
social/feedparser/package.json | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/social/feedparser/32-feedparse.js b/social/feedparser/32-feedparse.js
index bf898ef8..7a6bf88c 100644
--- a/social/feedparser/32-feedparse.js
+++ b/social/feedparser/32-feedparse.js
@@ -18,10 +18,10 @@ module.exports = function(RED) {
}
else {
var getFeed = function() {
- var req = request(node.url, {timeout: 10000, pool: false});
+ var req = request(node.url, {timeout:10000, pool:false});
//req.setMaxListeners(50);
- //req.setHeader('user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36');
- //req.setHeader('accept', 'text/html,application/xhtml+xml');
+ req.setHeader('user-agent', 'Mozilla/5.0 (Node-RED)');
+ req.setHeader('accept', 'text/html,application/xhtml+xml');
var feedparser = new FeedParser();
diff --git a/social/feedparser/package.json b/social/feedparser/package.json
index a5c0328f..e3be396f 100644
--- a/social/feedparser/package.json
+++ b/social/feedparser/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-feedparser",
- "version": "0.1.8",
+ "version": "0.1.9",
"description": "A Node-RED node to get RSS Atom feeds.",
"dependencies": {
"feedparser": "1.1.3",
From be79b6a1c603fb331f28a806c51d99bdcd33cd40 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Tue, 30 Jan 2018 21:42:14 +0000
Subject: [PATCH 011/456] add msg.property option to rbe, randon, smooth and
base64 nodes
---
function/random/package.json | 2 +-
function/random/random.html | 23 +-
function/random/random.js | 7 +-
function/rbe/package.json | 2 +-
function/rbe/rbe.html | 19 +-
function/rbe/rbe.js | 16 +-
function/smooth/17-smooth.html | 11 +-
function/smooth/17-smooth.js | 25 +-
function/smooth/package.json | 2 +-
package-lock.json | 817 +++++++++----------------
parsers/base64/70-base64.html | 15 +-
parsers/base64/70-base64.js | 22 +-
parsers/base64/package.json | 2 +-
test/function/random/random_spec.js | 19 +
test/function/rbe/rbe_spec.js | 35 ++
test/function/smooth/17-smooth_spec.js | 46 ++
test/parsers/base64/70-base64_spec.js | 29 +
17 files changed, 527 insertions(+), 565 deletions(-)
diff --git a/function/random/package.json b/function/random/package.json
index f6e48cac..4898c021 100644
--- a/function/random/package.json
+++ b/function/random/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-random",
- "version" : "0.0.8",
+ "version" : "0.1.0",
"description" : "A Node-RED node that when triggered generates a random number between two values.",
"dependencies" : {
},
diff --git a/function/random/random.html b/function/random/random.html
index 1a9cb7c7..0f2c3824 100644
--- a/function/random/random.html
+++ b/function/random/random.html
@@ -1,27 +1,31 @@
-
+70%
diff --git a/function/random/random.js b/function/random/random.js
index 69da1d65..a6fb1a47 100644
--- a/function/random/random.js
+++ b/function/random/random.js
@@ -6,14 +6,17 @@ module.exports = function(RED) {
this.low = Number(n.low || 1);
this.high = Number(n.high || 10);
this.inte = n.inte || false;
+ this.property = n.property||"payload";
var node = this;
this.on("input", function(msg) {
+ var value;
if (node.inte == "true" || node.inte === true) {
- msg.payload = Math.round(Number(Math.random()) * (node.high - node.low + 1) + node.low - 0.5);
+ value = Math.round(Number(Math.random()) * (node.high - node.low + 1) + node.low - 0.5);
}
else {
- msg.payload = Number(Math.random()) * (node.high - node.low) + node.low;
+ value = Number(Math.random()) * (node.high - node.low) + node.low;
}
+ RED.util.setMessageProperty(msg,node.property,value);
node.send(msg);
});
}
diff --git a/function/rbe/package.json b/function/rbe/package.json
index 6b1af48d..a48b84fc 100644
--- a/function/rbe/package.json
+++ b/function/rbe/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-rbe",
- "version" : "0.1.14",
+ "version" : "0.2.0",
"description" : "A Node-RED node that provides report-by-exception (RBE) and deadband capability.",
"dependencies" : {
},
diff --git a/function/rbe/rbe.html b/function/rbe/rbe.html
index ecf951c2..759c7c06 100644
--- a/function/rbe/rbe.html
+++ b/function/rbe/rbe.html
@@ -2,7 +2,7 @@
@@ -43,7 +47,7 @@
if specified the function will work on a per topic basis.
resetany
if set clears the stored value for the specified msg.topic, or
- all topics if msg.topic is not specified.
+ all topics if msg.topic is not specified.
Outputs
@@ -76,7 +80,8 @@
func: {value:"rbe"},
gap: {value:"",validate:RED.validators.regex(/^(\d*[.]*\d*|)(%|)$/)},
start: {value:""},
- inout: {value:"out"}
+ inout: {value:"out"},
+ property: {value:"payload",required:true}
},
inputs:1,
outputs:1,
@@ -89,6 +94,10 @@
return this.name?"node_label_italic":"";
},
oneditprepare: function() {
+ if (this.property === undefined) {
+ $("#node-input-property").val("payload");
+ }
+ $("#node-input-property").typedInput({default:'msg',types:['msg']});
//$( "#node-input-gap" ).spinner({min:0});
if ($("#node-input-inout").val() === null) {
$("#node-input-inout").val("out");
diff --git a/function/rbe/rbe.js b/function/rbe/rbe.js
index 50bfa1e8..49e2a208 100644
--- a/function/rbe/rbe.js
+++ b/function/rbe/rbe.js
@@ -13,6 +13,7 @@ module.exports = function(RED) {
this.gap = parseFloat(this.gap);
}
this.g = this.gap;
+ this.property = n.property||"payload";
var node = this;
@@ -24,26 +25,27 @@ module.exports = function(RED) {
}
else { node.previous = {}; }
}
- if (msg.hasOwnProperty("payload")) {
+ var value = RED.util.getMessageProperty(msg,node.property);
+ if (value !== undefined) {
var t = msg.topic || "_no_topic";
if ((this.func === "rbe") || (this.func === "rbei")) {
var doSend = (this.func !== "rbei") || (node.previous.hasOwnProperty(t)) || false;
- if (typeof(msg.payload) === "object") {
+ if (typeof(value) === "object") {
if (typeof(node.previous[t]) !== "object") { node.previous[t] = {}; }
- if (!RED.util.compareObjects(msg.payload, node.previous[t])) {
- node.previous[t] = RED.util.cloneMessage(msg.payload);
+ if (!RED.util.compareObjects(value, node.previous[t])) {
+ node.previous[t] = RED.util.cloneMessage(value);
if (doSend) { node.send(msg); }
}
}
else {
- if (msg.payload !== node.previous[t]) {
- node.previous[t] = RED.util.cloneMessage(msg.payload);
+ if (value !== node.previous[t]) {
+ node.previous[t] = RED.util.cloneMessage(value);
if (doSend) { node.send(msg); }
}
}
}
else {
- var n = parseFloat(msg.payload);
+ var n = parseFloat(value);
if (!isNaN(n)) {
if ((typeof node.previous[t] === 'undefined') && (this.func === "narrowband")) {
if (node.start === '') { node.previous[t] = n; }
diff --git a/function/smooth/17-smooth.html b/function/smooth/17-smooth.html
index 5de5af16..d7340849 100644
--- a/function/smooth/17-smooth.html
+++ b/function/smooth/17-smooth.html
@@ -1,7 +1,11 @@
@@ -17,7 +21,8 @@
category: 'function',
color:"#DEBD5C",
defaults: {
- name: {value:""}
+ name: {value:""},
+ property: {value:"payload",required:true}
},
inputs:1,
outputs:1,
@@ -27,6 +32,12 @@
},
labelStyle: function() {
return this.name?"node_label_italic":"";
+ },
+ oneditprepare: function() {
+ if (this.property === undefined) {
+ $("#node-input-property").val("payload");
+ }
+ $("#node-input-property").typedInput({default:'msg',types:['msg']});
}
});
diff --git a/parsers/base64/70-base64.js b/parsers/base64/70-base64.js
index 741fa5dc..764895df 100644
--- a/parsers/base64/70-base64.js
+++ b/parsers/base64/70-base64.js
@@ -1,28 +1,32 @@
module.exports = function(RED) {
"use strict";
-
function Base64Node(n) {
RED.nodes.createNode(this,n);
+ this.property = n.property||"payload";
var node = this;
this.on("input", function(msg) {
- if (msg.hasOwnProperty("payload")) {
- if (Buffer.isBuffer(msg.payload)) {
+ var value = RED.util.getMessageProperty(msg,node.property);
+ if (value !== undefined) {
+ if (Buffer.isBuffer(value)) {
// Take binary buffer and make into a base64 string
- msg.payload = msg.payload.toString('base64');
+ value = value.toString('base64');
+ RED.util.setMessageProperty(msg,node.property,value);
node.send(msg);
}
- else if (typeof msg.payload === "string") {
+ else if (typeof value === "string") {
// Take base64 string and make into binary buffer
- var load = msg.payload.replace(/\s+/g,''); // remove any whitespace
+ var load = value.replace(/\s+/g,''); // remove any whitespace
var regexp = new RegExp('^[A-Za-z0-9+\/=]*$'); // check it only contains valid characters
if ( regexp.test(load) && (load.length % 4 === 0) ) {
- msg.payload = new Buffer(load,'base64');
+ value = new Buffer(load,'base64');
+ RED.util.setMessageProperty(msg,node.property,value);
node.send(msg);
}
else {
//node.log("Not a Base64 string - maybe we should encode it...");
- msg.payload = (new Buffer(msg.payload,"binary")).toString('base64');
+ value = (new Buffer(value,"binary")).toString('base64');
+ RED.util.setMessageProperty(msg,node.property,value);
node.send(msg);
}
}
@@ -30,7 +34,7 @@ module.exports = function(RED) {
node.warn("This node only handles strings or buffers.");
}
}
- else { node.warn("No payload found to process"); }
+ else { node.warn("No property found to process"); }
});
}
RED.nodes.registerType("base64",Base64Node);
diff --git a/parsers/base64/package.json b/parsers/base64/package.json
index 99197caf..1805f7ef 100644
--- a/parsers/base64/package.json
+++ b/parsers/base64/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-base64",
- "version" : "0.0.8",
+ "version" : "0.1.0",
"description" : "A Node-RED node to pack and unpack objects to base64 format",
"dependencies" : {
},
diff --git a/test/function/random/random_spec.js b/test/function/random/random_spec.js
index e1a7d963..e1b9939f 100644
--- a/test/function/random/random_spec.js
+++ b/test/function/random/random_spec.js
@@ -66,4 +66,23 @@ describe('random node', function() {
});
});
+ it('should output an integer between -3 and 3 on chosen property - foo', function(done) {
+ var flow = [{"id":"n1", "type":"random", property:"foo", low:-3, high:3, inte:true, wires:[["n2"]] },
+ {id:"n2", type:"helper"} ];
+ helper.load(testNode, flow, function() {
+ var n1 = helper.getNode("n1");
+ var n2 = helper.getNode("n2");
+ var c = 0;
+ n2.on("input", function(msg) {
+ if (c === 0) {
+ msg.should.have.a.property("foo");
+ msg.foo.should.be.approximately(0,3);
+ msg.foo.toString().indexOf(".").should.equal(-1);
+ done();
+ }
+ });
+ n1.emit("input", {payload:"a"});
+ });
+ });
+
});
diff --git a/test/function/rbe/rbe_spec.js b/test/function/rbe/rbe_spec.js
index e19249ab..f41517d7 100644
--- a/test/function/rbe/rbe_spec.js
+++ b/test/function/rbe/rbe_spec.js
@@ -62,6 +62,41 @@ describe('rbe node', function() {
});
});
+ it('should only send output if another chosen property changes - foo (rbe)', function(done) {
+ var flow = [{"id":"n1", "type":"rbe", func:"rbe", gap:"0", property:"foo", wires:[["n2"]] },
+ {id:"n2", type:"helper"} ];
+ helper.load(testNode, flow, function() {
+ var n1 = helper.getNode("n1");
+ var n2 = helper.getNode("n2");
+ var c = 0;
+ n2.on("input", function(msg) {
+ if (c === 0) {
+ msg.should.have.a.property("foo", "a");
+ c+=1;
+ }
+ else if (c === 1) {
+ msg.should.have.a.property("foo", "b");
+ c+=1;
+ }
+ else {
+ msg.should.have.a.property("foo");
+ msg.foo.should.have.a.property("b",1);
+ msg.foo.should.have.a.property("c",2);
+ done();
+ }
+ });
+ n1.emit("input", {foo:"a"});
+ n1.emit("input", {payload:"a"});
+ n1.emit("input", {foo:"a"});
+ n1.emit("input", {payload:"a"});
+ n1.emit("input", {foo:"a"});
+ n1.emit("input", {foo:"b"});
+ n1.emit("input", {foo:{b:1,c:2}});
+ n1.emit("input", {foo:{c:2,b:1}});
+ n1.emit("input", {payload:{c:2,b:1}});
+ });
+ });
+
it('should only send output if payload changes - ignoring first value (rbei)', function(done) {
var flow = [{"id":"n1", "type":"rbe", func:"rbei", gap:"0", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
diff --git a/test/function/smooth/17-smooth_spec.js b/test/function/smooth/17-smooth_spec.js
index 6145a94e..4a9d2b83 100644
--- a/test/function/smooth/17-smooth_spec.js
+++ b/test/function/smooth/17-smooth_spec.js
@@ -48,6 +48,29 @@ describe('smooth node', function() {
});
});
+ it('should average over a number of inputs - another property - foo', function(done) {
+ var flow = [{"id":"n1", "type":"smooth", action:"mean", count:"5", round:"true", property:"foo", wires:[["n2"]] },
+ {id:"n2", type:"helper"} ];
+ helper.load(testNode, flow, function() {
+ var n1 = helper.getNode("n1");
+ var n2 = helper.getNode("n2");
+ var c = 0;
+ n2.on("input", function(msg) {
+ c += 1;
+ if (c === 4) { msg.should.have.a.property("foo", 1.8); }
+ if (c === 6) { msg.should.have.a.property("foo", 3); done(); }
+ });
+ n1.emit("input", {foo:1});
+ n1.emit("input", {foo:1});
+ n1.emit("input", {foo:2});
+ n1.emit("input", {payload:2});
+ n1.emit("input", {payload:2});
+ n1.emit("input", {foo:3});
+ n1.emit("input", {foo:4});
+ n1.emit("input", {foo:4.786});
+ });
+ });
+
it('should be able to be reset', function(done) {
var flow = [{"id":"n1", "type":"smooth", action:"mean", count:"5", round:"true", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
@@ -69,6 +92,29 @@ describe('smooth node', function() {
});
});
+ it('should be able to be reset - while using another property - foo', function(done) {
+ var flow = [{"id":"n1", "type":"smooth", action:"mean", count:"5", round:"true", property:"foo", wires:[["n2"]] },
+ {id:"n2", type:"helper"} ];
+ helper.load(testNode, flow, function() {
+ var n1 = helper.getNode("n1");
+ var n2 = helper.getNode("n2");
+ var c = 0;
+ n2.on("input", function(msg) {
+ c += 1;
+ if (c === 3) { msg.should.have.a.property("foo", 2); }
+ if (c === 6) { msg.should.have.a.property("foo", 5); done(); }
+ });
+ n1.emit("input", {foo:1});
+ n1.emit("input", {foo:2});
+ n1.emit("input", {payload:2});
+ n1.emit("input", {foo:3});
+ n1.emit("input", {reset:true, foo:4});
+ n1.emit("input", {foo:5});
+ n1.emit("input", {payload:2});
+ n1.emit("input", {foo:6});
+ });
+ });
+
it('should output max over a number of inputs', function(done) {
var flow = [{"id":"n1", "type":"smooth", action:"max", count:"5", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
diff --git a/test/parsers/base64/70-base64_spec.js b/test/parsers/base64/70-base64_spec.js
index 1fe5ddda..b7324248 100644
--- a/test/parsers/base64/70-base64_spec.js
+++ b/test/parsers/base64/70-base64_spec.js
@@ -39,6 +39,20 @@ describe('base64 node', function() {
});
});
+ it('should convert a Buffer to base64 using another property - foo', function(done) {
+ var flow = [{id:"n1", type:"base64", property:"foo", wires:[["n2"]] },
+ {id:"n2", type:"helper"} ];
+ helper.load(testNode, flow, function() {
+ var n1 = helper.getNode("n1");
+ var n2 = helper.getNode("n2");
+ n2.on("input", function(msg) {
+ msg.should.have.a.property("foo","QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo=");
+ done();
+ });
+ n1.emit("input", {foo: Buffer.from("ABCDEFGHIJKLMNOPQRSTUVWXYZ")});
+ });
+ });
+
it('should convert base64 to a Buffer', function(done) {
var flow = [{"id":"n1", "type":"base64", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
@@ -54,6 +68,21 @@ describe('base64 node', function() {
});
});
+ it('should convert base64 to a Buffer using another property - foo', function(done) {
+ var flow = [{id:"n1", type:"base64", property:"foo", wires:[["n2"]] },
+ {id:"n2", type:"helper"} ];
+ helper.load(testNode, flow, function() {
+ var n1 = helper.getNode("n1");
+ var n2 = helper.getNode("n2");
+ n2.on("input", function(msg) {
+ msg.should.have.a.property("foo");
+ msg.foo.toString().should.equal("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ done();
+ });
+ n1.emit("input", {foo:"QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo="});
+ });
+ });
+
it('should try to encode a non base64 string', function(done) {
var flow = [{"id":"n1", "type":"base64", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
From 6da469e49bf943f094ddd932b4f67d8ccc14eb1d Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Tue, 30 Jan 2018 21:57:44 +0000
Subject: [PATCH 012/456] fix missing timeout variable from SNMP node
---
io/snmp/package.json | 2 +-
io/snmp/snmp.html | 16 +++++-----------
2 files changed, 6 insertions(+), 12 deletions(-)
diff --git a/io/snmp/package.json b/io/snmp/package.json
index d561c581..05994444 100644
--- a/io/snmp/package.json
+++ b/io/snmp/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-snmp",
- "version" : "0.0.16",
+ "version" : "0.0.17",
"description" : "A Node-RED node that looks for SNMP oids.",
"dependencies" : {
"net-snmp" : "^1.1.19"
diff --git a/io/snmp/snmp.html b/io/snmp/snmp.html
index 2ada8dd4..f16cf1e5 100644
--- a/io/snmp/snmp.html
+++ b/io/snmp/snmp.html
@@ -57,7 +57,6 @@
return this.name ? "node_label_italic" : "";
}
});
-
-
From f664fa0e317742b45c7e72060c9ead99edf5c3ef Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Wed, 31 Jan 2018 10:33:27 +0000
Subject: [PATCH 013/456] pin back net-snap version
---
io/snmp/package.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/io/snmp/package.json b/io/snmp/package.json
index 05994444..6021262f 100644
--- a/io/snmp/package.json
+++ b/io/snmp/package.json
@@ -1,9 +1,9 @@
{
"name" : "node-red-node-snmp",
- "version" : "0.0.17",
+ "version" : "0.0.18",
"description" : "A Node-RED node that looks for SNMP oids.",
"dependencies" : {
- "net-snmp" : "^1.1.19"
+ "net-snmp" : "1.1.19"
},
"repository" : {
"type":"git",
From b2de9288606450ca3e3cb141b1645fd0e1341a0c Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Wed, 31 Jan 2018 11:18:30 +0000
Subject: [PATCH 014/456] update rest of parsers to allow property to be
selected
---
parsers/geohash/70-geohash.html | 8 +-
parsers/geohash/70-geohash.js | 126 +++++++++++-------------
parsers/geohash/package.json | 2 +-
parsers/msgpack/70-msgpack.html | 7 +-
parsers/msgpack/70-msgpack.js | 20 ++--
parsers/msgpack/package.json | 2 +-
parsers/what3words/package.json | 2 +-
parsers/what3words/what3words.html | 9 +-
parsers/what3words/what3words.js | 98 +++++++++---------
test/parsers/geohash/70-geohash_spec.js | 23 ++++-
10 files changed, 158 insertions(+), 139 deletions(-)
diff --git a/parsers/geohash/70-geohash.html b/parsers/geohash/70-geohash.html
index 1f2ac238..e4cbd579 100644
--- a/parsers/geohash/70-geohash.html
+++ b/parsers/geohash/70-geohash.html
@@ -1,5 +1,9 @@
diff --git a/parsers/geohash/package.json b/parsers/geohash/package.json
index 08e0d7c8..68339339 100644
--- a/parsers/geohash/package.json
+++ b/parsers/geohash/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-geohash",
- "version" : "0.1.7",
+ "version" : "0.1.8",
"description" : "A Node-RED node to encode and decode lat,lon pairs to a geohash.",
"dependencies" : {
"ngeohash" : "0.6.0"
diff --git a/parsers/msgpack/70-msgpack.html b/parsers/msgpack/70-msgpack.html
index ceed92d5..12552ff0 100644
--- a/parsers/msgpack/70-msgpack.html
+++ b/parsers/msgpack/70-msgpack.html
@@ -35,6 +35,9 @@
},
labelStyle: function() {
return this.name?"node_label_italic":"";
+ },
+ oneditprepare: function() {
+ $("#node-input-property").typedInput({default:'msg',types:['msg']});
}
});
diff --git a/parsers/msgpack/package.json b/parsers/msgpack/package.json
index d5c163e9..ec71f920 100644
--- a/parsers/msgpack/package.json
+++ b/parsers/msgpack/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-msgpack",
- "version" : "1.1.1",
+ "version" : "1.1.2",
"description" : "A Node-RED node to pack and unpack objects to msgpack format",
"dependencies" : {
"msgpack-lite" : "^0.1.26"
diff --git a/parsers/what3words/package.json b/parsers/what3words/package.json
index 5d011dbb..4f8ccd9a 100644
--- a/parsers/what3words/package.json
+++ b/parsers/what3words/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-what3words",
- "version" : "0.1.7",
+ "version" : "0.1.8",
"description" : "A Node-RED node to convert locations to/from what3words",
"dependencies" : {
"geo.what3words" : "^2.0.0"
diff --git a/parsers/what3words/what3words.html b/parsers/what3words/what3words.html
index 6e8d5a23..a90212e4 100644
--- a/parsers/what3words/what3words.html
+++ b/parsers/what3words/what3words.html
@@ -62,6 +62,9 @@
},
labelStyle: function() {
return this.name?"node_label_italic":"";
+ },
+ oneditprepare: function() {
+ $("#node-input-property").typedInput({default:'msg',types:['msg']});
}
});
From f9ac210a41b6bbdfce4779409f1d6f366d9ea14b Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Sat, 3 Feb 2018 15:08:05 +0000
Subject: [PATCH 016/456] Add fixed conversion modes to base64 node
to close #401
---
parsers/base64/70-base64.html | 12 ++++++-
parsers/base64/70-base64.js | 60 ++++++++++++++++++++++-------------
parsers/base64/package.json | 2 +-
3 files changed, 50 insertions(+), 24 deletions(-)
diff --git a/parsers/base64/70-base64.html b/parsers/base64/70-base64.html
index 5ab31404..2edae4cc 100644
--- a/parsers/base64/70-base64.html
+++ b/parsers/base64/70-base64.html
@@ -1,5 +1,13 @@
diff --git a/parsers/msgpack/icons/parser-msgpack.png b/parsers/msgpack/icons/parser-msgpack.png
new file mode 100644
index 0000000000000000000000000000000000000000..02b5ddc0827853bf3ab620a1f75530fdeb164a43
GIT binary patch
literal 274
zcmeAS@N?(olHy`uVBq!ia0vp^B0wz1!3HFCgzU0`6kC$Fy9>jA5L~c#`DCC7XMsm#
zF#`j)FbFd;%$g$s6l5>)^mS!_#KbJX#O@!t;~P+DzNd?0h{y4#lh1NB8wj+dd+{B0
ze);%Ei(P~M)87@@j>oziJ7Rlxc_|j3(&(hXT31tjqj=@
z%fGFh{N)qNI%j^S+!ve=n0^&-Y-77{%=tzQo62Orlqq{{WzTKl>{%Cf=ca?-sb7L_
zYpYKys`tn~jCnpGOu{|*+EU{)zQ3kP{KG*bNPSd+y^`=_8P&;onpeP7|t$O
Q0(2^ar>mdKI;Vst0Qie#$N&HU
literal 0
HcmV?d00001
diff --git a/parsers/msgpack/package.json b/parsers/msgpack/package.json
index ec71f920..9a8b2070 100644
--- a/parsers/msgpack/package.json
+++ b/parsers/msgpack/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-msgpack",
- "version" : "1.1.2",
+ "version" : "1.1.3",
"description" : "A Node-RED node to pack and unpack objects to msgpack format",
"dependencies" : {
"msgpack-lite" : "^0.1.26"
diff --git a/parsers/what3words/icons/what3words.png b/parsers/what3words/icons/what3words.png
new file mode 100644
index 0000000000000000000000000000000000000000..9fe1b593abc0c476088fa42c93f340c288e19a13
GIT binary patch
literal 332
zcmeAS@N?(olHy`uVBq!ia0vp^l0YoS!3HF6zS(*kNU2IendogF8_
z+4+krS)%0MB9q9SQzXLw$M3z@bLEOh*o8mo2?=cAdnX^
zk^J{uwDAA_^7|rs<*(PVpRDAY|6P;!*TZ0kO#-X9+ZOmsNX}fD^K$=1wObEZ8E#q>
U++scFy%`iJp00i_>zopr09W#cO8@`>
literal 0
HcmV?d00001
diff --git a/parsers/what3words/package.json b/parsers/what3words/package.json
index 4f8ccd9a..173f6cc2 100644
--- a/parsers/what3words/package.json
+++ b/parsers/what3words/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-what3words",
- "version" : "0.1.8",
+ "version" : "0.1.9",
"description" : "A Node-RED node to convert locations to/from what3words",
"dependencies" : {
"geo.what3words" : "^2.0.0"
diff --git a/parsers/what3words/what3words.html b/parsers/what3words/what3words.html
index a90212e4..871159a7 100644
--- a/parsers/what3words/what3words.html
+++ b/parsers/what3words/what3words.html
@@ -56,7 +56,7 @@
color:"#DEBD5C",
inputs:1,
outputs:1,
- icon: "arrow-in.png",
+ icon: "what3words.png",
label: function() {
return this.name||"what3words";
},
From bb3d302bcbea690c0c92d8db0c4a96e050c2f351 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Fri, 9 Feb 2018 12:51:42 +0000
Subject: [PATCH 020/456] Add try/catch to daemon
---
utility/daemon/daemon.js | 93 ++++++++++++++++++++-----------------
utility/daemon/package.json | 2 +-
2 files changed, 52 insertions(+), 43 deletions(-)
diff --git a/utility/daemon/daemon.js b/utility/daemon/daemon.js
index ee2d045a..59dd6f6f 100644
--- a/utility/daemon/daemon.js
+++ b/utility/daemon/daemon.js
@@ -36,58 +36,67 @@ module.exports = function(RED) {
}
function runit() {
+ var line = "";
if (!node.cmd || (typeof node.cmd !== "string") || (node.cmd.length < 1)) {
node.status({fill:"grey",shape:"ring",text:"no command"});
return;
}
- node.child = spawn(node.cmd, node.args);
- if (RED.settings.verbose) { node.log(node.cmd+" "+JSON.stringify(node.args)); }
- node.status({fill:"green",shape:"dot",text:"running"});
- node.running = true;
- var line = "";
+ try {
+ node.child = spawn(node.cmd, node.args);
+ if (RED.settings.verbose) { node.log(node.cmd+" "+JSON.stringify(node.args)); }
+ node.status({fill:"green",shape:"dot",text:"running"});
+ node.running = true;
- node.child.stdout.on('data', function (data) {
- if (node.op === "string") { data = data.toString(); }
- if (node.op === "number") { data = Number(data); }
- if (RED.settings.verbose) { node.log("out: "+data); }
- if (node.op === "lines") {
- line += data.toString();
- var bits = line.split("\n");
- while (bits.length > 1) {
- node.send([{payload:bits.shift()},null,null]);
+ node.child.stdout.on('data', function (data) {
+ if (node.op === "string") { data = data.toString(); }
+ if (node.op === "number") { data = Number(data); }
+ if (RED.settings.verbose) { node.log("out: "+data); }
+ if (node.op === "lines") {
+ line += data.toString();
+ var bits = line.split("\n");
+ while (bits.length > 1) {
+ node.send([{payload:bits.shift()},null,null]);
+ }
+ line = bits[0];
}
- line = bits[0];
- }
- else {
- if (data && (data.length !== 0)) {
- node.send([{payload:data},null,null]);
+ else {
+ if (data && (data.length !== 0)) {
+ node.send([{payload:data},null,null]);
+ }
}
- }
- });
+ });
- node.child.stderr.on('data', function (data) {
- if (node.op === "string") { data = data.toString(); }
- if (node.op === "number") { data = Number(data); }
- if (RED.settings.verbose) { node.log("err: "+data); }
- node.send([null,{payload:data},null]);
- });
+ node.child.stderr.on('data', function (data) {
+ if (node.op === "string") { data = data.toString(); }
+ if (node.op === "number") { data = Number(data); }
+ if (RED.settings.verbose) { node.log("err: "+data); }
+ node.send([null,{payload:data},null]);
+ });
- node.child.on('close', function (code,signal) {
- if (RED.settings.verbose) { node.log("ret: "+code+":"+signal); }
+ node.child.on('close', function (code,signal) {
+ if (RED.settings.verbose) { node.log("ret: "+code+":"+signal); }
+ node.running = false;
+ node.child = null;
+ var rc = code;
+ if (code === null) { rc = signal; }
+ node.send([null,null,{payload:rc}]);
+ node.status({fill:"red",shape:"ring",text:"stopped"});
+ });
+
+ node.child.on('error', function (err) {
+ if (err.errno === "ENOENT") { node.warn('Command not found'); }
+ else if (err.errno === "EACCES") { node.warn('Command not executable'); }
+ else { node.log('error: ' + err); }
+ node.status({fill:"red",shape:"ring",text:"error"});
+ });
+ }
+ catch(e) {
+ if (e.errno === "ENOENT") { node.warn('Command not found'); }
+ else if (e.errno === "EACCES") { node.warn('Command not executable'); }
+ else { node.error(e); }
+ node.status({fill:"red",shape:"ring",text:"error"});
node.running = false;
- node.child = null;
- var rc = code;
- if (code === null) { rc = signal; }
- node.send([null,null,{payload:rc}]);
- node.status({fill:"red",shape:"ring",text:"stopped"});
- });
-
- node.child.on('error', function (err) {
- if (err.errno === "ENOENT") { node.warn('Command not found'); }
- else if (err.errno === "EACCES") { node.warn('Command not executable'); }
- else { node.log('error: ' + err); }
- node.status({fill:"grey",shape:"dot",text:"error"});
- });
+ }
}
if (node.redo === true) {
diff --git a/utility/daemon/package.json b/utility/daemon/package.json
index 018f0db9..089a8c26 100644
--- a/utility/daemon/package.json
+++ b/utility/daemon/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-daemon",
- "version" : "0.0.17",
+ "version" : "0.0.18",
"description" : "A Node-RED node that runs and monitors a long running system command.",
"dependencies" : {
},
From 17614843da48d3db96e0a7d5050f207ec4c2f06b Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Thu, 15 Feb 2018 14:04:03 +0000
Subject: [PATCH 021/456] add note re docker to pigpiod node
---
hardware/pigpiod/package.json | 2 +-
hardware/pigpiod/pi-gpiod.html | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/hardware/pigpiod/package.json b/hardware/pigpiod/package.json
index c188c5c4..e54c5e4d 100644
--- a/hardware/pigpiod/package.json
+++ b/hardware/pigpiod/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-pi-gpiod",
- "version": "0.0.7",
+ "version": "0.0.8",
"description": "A node-red node for PiGPIOd",
"dependencies" : {
"js-pigpio": "*"
diff --git a/hardware/pigpiod/pi-gpiod.html b/hardware/pigpiod/pi-gpiod.html
index 507e63f6..82998623 100644
--- a/hardware/pigpiod/pi-gpiod.html
+++ b/hardware/pigpiod/pi-gpiod.html
@@ -180,6 +180,7 @@
Details
You may also enable the input pullup resistor ↑ or the pulldown resistor ↓.
+
If using with Docker on Pi then the default Host IP should be `172.17.0.1`. You will also need to run `sudo pigpiod` on the host.
Note: the pin numbers refer the physical pin numbers on connector P1 as they are easier to locate.
@@ -426,6 +427,7 @@
and will set the selected physical pin high or low depending on the value passed in.
The initial value of the pin at deploy time can also be set to 0 or 1.
When using PWM and Servo modes, the input value should be a number 0 - 100, and can be floating point.
+
If using with Docker on Pi then the default Host IP should be `172.17.0.1`. You will also need to run `sudo pigpiod` on the host.
Note: the pin numbers refer the physical pin numbers on connector P1 as they are easier to locate.
From c1d835c1cadef6c89c7ca4e2e098ed6ac6adb486 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Thu, 15 Feb 2018 14:43:29 +0000
Subject: [PATCH 022/456] Tidy up gpiod node tips
---
hardware/pigpiod/locales/en-US/pi-gpiod.json | 8 ++++----
hardware/pigpiod/package.json | 2 +-
hardware/pigpiod/pi-gpiod.html | 12 ++++++------
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/hardware/pigpiod/locales/en-US/pi-gpiod.json b/hardware/pigpiod/locales/en-US/pi-gpiod.json
index 69199beb..5eaa33e6 100644
--- a/hardware/pigpiod/locales/en-US/pi-gpiod.json
+++ b/hardware/pigpiod/locales/en-US/pi-gpiod.json
@@ -30,10 +30,10 @@
"pinname": "Pin",
"tip": {
"pin": "Pins in Use: ",
- "in": "Tip: Only Digital Input is supported - input must be 0 or 1.",
- "dig": "Tip: For digital output - input must be 0 or 1.",
- "pwm": "Tip: For PWM output - input must be between 0 to 100.",
- "ser": "Tip: For Servo output - input must be between 0 to 100. 50 is centre. Min must be 500uS or more, Max must be 2500uS or less."
+ "in": "Only Digital Input is supported - input must be 0 or 1.",
+ "dig": "Digital output - input must be 0 or 1.",
+ "pwm": "PWM output - input must be between 0 to 100.",
+ "ser": "Servo output - input must be between 0 to 100. 50 is centre. Min must be 500uS or more, Max must be 2500uS or less."
},
"types": {
"digout": "digital output",
diff --git a/hardware/pigpiod/package.json b/hardware/pigpiod/package.json
index e54c5e4d..8ea76b8b 100644
--- a/hardware/pigpiod/package.json
+++ b/hardware/pigpiod/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-pi-gpiod",
- "version": "0.0.8",
+ "version": "0.0.9",
"description": "A node-red node for PiGPIOd",
"dependencies" : {
"js-pigpio": "*"
diff --git a/hardware/pigpiod/pi-gpiod.html b/hardware/pigpiod/pi-gpiod.html
index 82998623..d83641b2 100644
--- a/hardware/pigpiod/pi-gpiod.html
+++ b/hardware/pigpiod/pi-gpiod.html
@@ -163,9 +163,9 @@
+
Pins marked in blue are dual use. Make sure they are not enabled for
their other use before using as GPIO.
-
@@ -408,11 +408,11 @@
-
Pins marked in blue are dual use. Make sure they are not enabled for
- their other use before using as GPIO.
+
Pins marked in blue are dual use. Make sure they are not enabled for
+ their other use before using as GPIO.
@@ -485,7 +485,7 @@
$("#pwm-tip").show();
$("#ser-tip").hide();
}
- if ($("#node-input-out").val() === "ser") {
+ else if ($("#node-input-out").val() === "ser") {
$('#node-set-tick').hide();
$('#node-set-state').hide();
$('#node-set-minimax').show();
From 127fb6ac0c69af8d9b22cedca9d99e1eea71e2d8 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Mon, 19 Feb 2018 19:21:52 +0000
Subject: [PATCH 023/456] clarify serial port timeout doc info
---
io/serialport/25-serial.html | 2 +-
io/serialport/README.md | 2 +-
io/serialport/package.json | 4 ++--
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/io/serialport/25-serial.html b/io/serialport/25-serial.html
index 287515bb..ea7d7842 100644
--- a/io/serialport/25-serial.html
+++ b/io/serialport/25-serial.html
@@ -13,7 +13,7 @@
diff --git a/io/serialport/25-serial.js b/io/serialport/25-serial.js
index 07b3fd8d..e6fcf10d 100644
--- a/io/serialport/25-serial.js
+++ b/io/serialport/25-serial.js
@@ -117,8 +117,8 @@ module.exports = function(RED) {
this.port.on('data', function(msg) {
// single char buffer
if ((node.serialConfig.newline === 0)||(node.serialConfig.newline === "")) {
- if (node.serialConfig.bin !== "bin") { node.send({"payload": String.fromCharCode(msg)}); }
- else { node.send({"payload": new Buffer([msg])}); }
+ if (node.serialConfig.bin !== "bin") { node.send({"payload": String.fromCharCode(msg), port:node.serialConfig.serialport}); }
+ else { node.send({"payload": new Buffer([msg]), port:node.serialConfig.serialport}); }
}
else {
// do the timer thing
@@ -133,7 +133,7 @@ module.exports = function(RED) {
var m = new Buffer(i+1);
buf.copy(m,0,0,i+1);
if (node.serialConfig.bin !== "bin") { m = m.toString(); }
- node.send({"payload": m});
+ node.send({"payload": m, port:node.serialConfig.serialport});
m = null;
}, node.serialConfig.newline);
i = 0;
@@ -148,7 +148,7 @@ module.exports = function(RED) {
var m = new Buffer(i);
buf.copy(m,0,0,i);
if (node.serialConfig.bin !== "bin") { m = m.toString(); }
- node.send({"payload":m});
+ node.send({"payload":m, port:node.serialConfig.serialport});
m = null;
i = 0;
}
@@ -161,7 +161,7 @@ module.exports = function(RED) {
var n = new Buffer(i);
buf.copy(n,0,0,i);
if (node.serialConfig.bin !== "bin") { n = n.toString(); }
- node.send({"payload":n});
+ node.send({"payload":n, port:node.serialConfig.serialport});
n = null;
i = 0;
}
diff --git a/io/serialport/package.json b/io/serialport/package.json
index ccf56099..ee68d2af 100644
--- a/io/serialport/package.json
+++ b/io/serialport/package.json
@@ -1,9 +1,9 @@
{
"name" : "node-red-node-serialport",
- "version" : "0.6.4",
+ "version" : "0.6.5",
"description" : "Node-RED nodes to talk to serial ports",
"dependencies" : {
- "serialport" : "^6.0.5"
+ "serialport" : "^6.1.1"
},
"repository" : {
"type":"git",
From f92f16fd08c40ff56e6e31f0878859f40757e0c5 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Sun, 11 Mar 2018 21:10:37 +0000
Subject: [PATCH 027/456] Add warning of too large interval for feedparser
To close #408
---
social/feedparser/32-feedparse.html | 7 ++++---
social/feedparser/32-feedparse.js | 1 +
social/feedparser/locales/en-US/32-feedparse.json | 5 +++--
social/feedparser/package.json | 6 +++---
4 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/social/feedparser/32-feedparse.html b/social/feedparser/32-feedparse.html
index 5d732881..3581c75e 100644
--- a/social/feedparser/32-feedparse.html
+++ b/social/feedparser/32-feedparse.html
@@ -6,7 +6,7 @@
-
+
@@ -19,6 +19,7 @@
The msg.topic contains the original article link. The msg.payload
contains the description, and msg.article contains the complete article object,
which has properties such as .title, .summary, .date and so on.
+
The Refresh interval cannot be greater than 35790 minutes (approx 24.8 days).
diff --git a/storage/sqlite/sqlite.js b/storage/sqlite/sqlite.js
index 41936fd5..e210bbcb 100644
--- a/storage/sqlite/sqlite.js
+++ b/storage/sqlite/sqlite.js
@@ -1,4 +1,3 @@
-
module.exports = function(RED) {
"use strict";
var reconnect = RED.settings.sqliteReconnectTime || 20000;
@@ -33,26 +32,75 @@ module.exports = function(RED) {
function SqliteNodeIn(n) {
RED.nodes.createNode(this,n);
this.mydb = n.mydb;
+ this.sqlquery = n.sqlquery||"msg.topic";
+ this.sql = n.sql;
this.mydbConfig = RED.nodes.getNode(this.mydb);
+ var node = this;
+ node.status({});
if (this.mydbConfig) {
this.mydbConfig.doConnect();
- var node = this;
+ var bind = [];
node.on("input", function(msg) {
- if (typeof msg.topic === 'string') {
- //console.log("query:",msg.topic);
- var bind = Array.isArray(msg.payload) ? msg.payload : [];
- node.mydbConfig.db.all(msg.topic, bind, function(err, row) {
- if (err) { node.error(err,msg); }
- else {
- msg.payload = row;
- node.send(msg);
+ if (this.sqlquery == "msg.topic"){
+ if (typeof msg.topic === 'string') {
+ bind = Array.isArray(msg.payload) ? msg.payload : [];
+ node.mydbConfig.db.all(msg.topic, bind, function(err, row) {
+ if (err) { node.error(err,msg); }
+ else {
+ msg.payload = row;
+ node.send(msg);
+ }
+ });
+ }
+ else {
+ if (typeof msg.topic !== 'string') {
+ node.error("msg.topic : the query is not defined as a string",msg);
+ node.status({fill:"red",shape:"dot",text:"msg.topic error"});
}
- });
+ }
}
- else {
- if (typeof msg.topic !== 'string') {
- node.error("msg.topic : the query is not defined as a string",msg);
+ if (this.sqlquery == "fixed"){
+ if (typeof this.sql === 'string'){
+ bind = Array.isArray(msg.payload) ? msg.payload : [];
+ node.mydbConfig.db.all(this.sql, bind, function(err, row) {
+ if (err) { node.error(err,msg); }
+ else {
+ msg.payload = row;
+ node.send(msg);
+ }
+ });
+ }
+ else{
+ if (this.sql === null || this.sql == ""){
+ node.error("SQL statement config not set up",msg);
+ node.status({fill:"red",shape:"dot",text:"SQL config not set up"});
+ }
+ }
+ }
+ if (this.sqlquery == "prepared"){
+ if (typeof this.sql === 'string' && typeof msg.params !== "undefined" && typeof msg.params === "object"){
+ node.mydbConfig.db.all(this.sql, msg.params, function(err, row) {
+ if (err) { node.error(err,msg); }
+ else {
+ msg.payload = row;
+ node.send(msg);
+ }
+ });
+ }
+ else{
+ if (this.sql === null || this.sql == ""){
+ node.error("Prepared statement config not set up",msg);
+ node.status({fill:"red",shape:"dot",text:"Prepared statement not set up"});
+ }
+ if (typeof msg.params == "undefined"){
+ node.error("msg.params not passed");
+ node.status({fill:"red",shape:"dot",text:"msg.params not passed",msg});
+ }
+ else if (typeof msg.params != "object"){
+ node.error("msg.params not an object");
+ node.status({fill:"red",shape:"dot",text:"msg.params not an object",msg});
+ }
}
}
});
From 34199142ddd5a8760fd72dd7417abdfdcfa67a57 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Tue, 20 Mar 2018 17:17:14 +0000
Subject: [PATCH 030/456] Fix piLCD line 3 and 4 addressing
ti address #416
---
hardware/PiLcd/nrlcd.py | 4 ++--
hardware/PiLcd/package.json | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/hardware/PiLcd/nrlcd.py b/hardware/PiLcd/nrlcd.py
index de4cc012..ec6dfc65 100755
--- a/hardware/PiLcd/nrlcd.py
+++ b/hardware/PiLcd/nrlcd.py
@@ -31,8 +31,8 @@ LCD_CMD = False
LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line
-LCD_LINE_3 = 0xA0 # LCD RAM address for the 3rd line
-LCD_LINE_4 = 0xE0 # LCD RAM address for the 4th line
+LCD_LINE_3 = 0x94 # LCD RAM address for the 3rd line
+LCD_LINE_4 = 0xD4 # LCD RAM address for the 4th line
# Timing constants
E_PULSE = 0.0005
diff --git a/hardware/PiLcd/package.json b/hardware/PiLcd/package.json
index 7d158fe7..22668892 100644
--- a/hardware/PiLcd/package.json
+++ b/hardware/PiLcd/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-pilcd",
- "version" : "0.0.7",
+ "version" : "0.0.8",
"description" : "A Node-RED node for Raspberry Pi to write to HD44780 style LCD panels.",
"dependencies" : {
},
From 74d51f5a79990240d3be44443c239d7c644d6393 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Tue, 20 Mar 2018 17:18:20 +0000
Subject: [PATCH 031/456] Tiny tidy of email node
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
really needs a proper re-write…
---
social/email/61-email.html | 4 ++--
social/email/61-email.js | 5 +++--
social/email/package.json | 4 ++--
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/social/email/61-email.html b/social/email/61-email.html
index c7ddcc8d..aff990e7 100644
--- a/social/email/61-email.html
+++ b/social/email/61-email.html
@@ -97,7 +97,7 @@
return this.dname||this.name||"email";
},
labelStyle: function() {
- return (this.dname||!this.topic)?"node_label_italic":"";
+ return (this.dname)?"node_label_italic":"";
},
oneditprepare: function() {
if (this.credentials.global) {
@@ -249,7 +249,7 @@
return this.name||"email";
},
labelStyle: function() {
- return (this.name||!this.topic)?"node_label_italic":"";
+ return (this.name)?"node_label_italic":"";
},
oneditprepare: function() {
if (this.credentials.global) {
diff --git a/social/email/61-email.js b/social/email/61-email.js
index d22ced3a..1ab79102 100644
--- a/social/email/61-email.js
+++ b/social/email/61-email.js
@@ -203,6 +203,7 @@ module.exports = function(RED) {
function checkPOP3(msg) {
var currentMessage;
var maxMessage;
+ //node.log("Checking POP3 for new messages");
// Form a new connection to our email server using POP3.
var pop3Client = new POP3Client(
@@ -237,7 +238,7 @@ module.exports = function(RED) {
});
pop3Client.on("error", function(err) {
- node.log("We caught an error: " + JSON.stringify(err));
+ node.log("error: " + JSON.stringify(err));
});
pop3Client.on("connect", function() {
@@ -297,7 +298,7 @@ module.exports = function(RED) {
//
// Check the email sever using the IMAP protocol for new messages.
function checkIMAP(msg) {
- node.log("Checking IMAP for new messages");
+ //node.log("Checking IMAP for new messages");
// We get back a 'ready' event once we have connected to imap
imap.once("ready", function() {
node.status({fill:"blue", shape:"dot", text:"email.status.fetching"});
diff --git a/social/email/package.json b/social/email/package.json
index 2f90f14f..de19cd58 100644
--- a/social/email/package.json
+++ b/social/email/package.json
@@ -1,11 +1,11 @@
{
"name": "node-red-node-email",
- "version": "0.1.24",
+ "version": "0.1.25",
"description": "Node-RED nodes to send and receive simple emails",
"dependencies": {
"nodemailer": "^1.11.0",
"poplib": "^0.1.7",
- "mailparser": "^0.6.1",
+ "mailparser": "^0.6.2",
"imap": "^0.8.19"
},
"repository": {
From 3decff0b1ae8b5bb33de20d09803d423ad96f84f Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Tue, 20 Mar 2018 19:08:38 +0000
Subject: [PATCH 032/456] Bump sqlite node (now allows prepared statements)
---
storage/sqlite/package.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/storage/sqlite/package.json b/storage/sqlite/package.json
index d63dfa62..b85d3eec 100644
--- a/storage/sqlite/package.json
+++ b/storage/sqlite/package.json
@@ -1,9 +1,9 @@
{
"name" : "node-red-node-sqlite",
- "version" : "0.1.2",
+ "version" : "0.2.0",
"description" : "A sqlite node for Node-RED",
"dependencies" : {
- "sqlite3" : "3.1.*"
+ "sqlite3" : "3.*"
},
"repository" : {
"type":"git",
From 8ea3969714b610fe9290d2af24f670b698e23c55 Mon Sep 17 00:00:00 2001
From: Hiroyasu Nishiyama
Date: Thu, 29 Mar 2018 16:49:30 +0900
Subject: [PATCH 033/456] Japanese translation of info text for
twitter/feedparse/email/rbe nodes (#421)
* add Japanese info text of twitter node
* add Japanese info text of feedparse node
* add Japanese info text of email node
* add Japanese info text of rbe node
* minor fix of Japanese info text of email node
* minor fix of Japanese info text of email node
---
function/rbe/locales/ja/rbe.html | 29 ++++++++++++
social/email/locales/ja/61-email.html | 46 +++++++++++++++++++
.../feedparser/locales/ja/32-feedparse.html | 8 ++++
social/twitter/locales/ja/27-twitter.html | 43 +++++++++++++++++
4 files changed, 126 insertions(+)
create mode 100644 function/rbe/locales/ja/rbe.html
create mode 100755 social/email/locales/ja/61-email.html
create mode 100644 social/feedparser/locales/ja/32-feedparse.html
create mode 100644 social/twitter/locales/ja/27-twitter.html
diff --git a/function/rbe/locales/ja/rbe.html b/function/rbe/locales/ja/rbe.html
new file mode 100644
index 00000000..a5225051
--- /dev/null
+++ b/function/rbe/locales/ja/rbe.html
@@ -0,0 +1,29 @@
+
diff --git a/social/email/locales/ja/61-email.html b/social/email/locales/ja/61-email.html
new file mode 100755
index 00000000..8bbb2110
--- /dev/null
+++ b/social/email/locales/ja/61-email.html
@@ -0,0 +1,46 @@
+
+
+
diff --git a/social/feedparser/locales/ja/32-feedparse.html b/social/feedparser/locales/ja/32-feedparse.html
new file mode 100644
index 00000000..a58b1482
--- /dev/null
+++ b/social/feedparser/locales/ja/32-feedparse.html
@@ -0,0 +1,8 @@
+
diff --git a/social/twitter/locales/ja/27-twitter.html b/social/twitter/locales/ja/27-twitter.html
new file mode 100644
index 00000000..2ccd8eb5
--- /dev/null
+++ b/social/twitter/locales/ja/27-twitter.html
@@ -0,0 +1,43 @@
+
+
+
+
From da96f9e869bf8cfb74beaf2f2669eb6f0c864b55 Mon Sep 17 00:00:00 2001
From: Kazuhito Yokoi
Date: Thu, 29 Mar 2018 16:49:42 +0900
Subject: [PATCH 034/456] Improve Japanese translation in rbe node (#422)
* Improve Japanese translation
* Empty commit to run travis again
---
function/rbe/locales/ja/rbe.json | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/function/rbe/locales/ja/rbe.json b/function/rbe/locales/ja/rbe.json
index fd913794..b4d76df0 100644
--- a/function/rbe/locales/ja/rbe.json
+++ b/function/rbe/locales/ja/rbe.json
@@ -13,12 +13,12 @@
"opts": {
"rbe": "値が変化した時のみメッセージを中継",
"rbei": "値が変化した時のみメッセージを中継(初期値を無視)",
- "deadband": "値が比較値を超える時のみメッセージを中継",
- "deadbandEq": "値が比較値以上の時のみメッセージを中継",
- "narrowband": "初期値、値が比較値を超える時のみメッセージを中継",
- "narrowbandEq": "初期値、値が比較値以上の時のみメッセージを中継",
- "in": "を最後の入力値と比較",
- "out": "を最後の出力値と比較"
+ "deadband": "値が指定した変化量を超える時のみメッセージを中継",
+ "deadbandEq": "値が指定した変化量以上の時のみメッセージを中継",
+ "narrowband": "値が指定した変化量を超えない時のみメッセージを中継",
+ "narrowbandEq": "値が指定した変化量以上でない時のみメッセージを中継",
+ "in": "最後の入力値と比較",
+ "out": "最後の出力値と比較"
},
"warn": {
"nonumber": "ペイロードに数値が含まれていません"
From 9ea27f94ef0bafec6c9a9646414633e4ef568b0c Mon Sep 17 00:00:00 2001
From: Marc Buils
Date: Thu, 29 Mar 2018 09:50:51 +0200
Subject: [PATCH 035/456] Upgrade to Twilio sdk v3 (#411)
---
social/twilio/56-twilio.js | 14 ++++----------
social/twilio/package.json | 2 +-
2 files changed, 5 insertions(+), 11 deletions(-)
diff --git a/social/twilio/56-twilio.js b/social/twilio/56-twilio.js
index 75d47823..48403ba5 100644
--- a/social/twilio/56-twilio.js
+++ b/social/twilio/56-twilio.js
@@ -58,20 +58,14 @@ module.exports = function(RED) {
if ( this.twilioType == "call" ) {
// Make a call
var twimlurl = node.url || msg.payload;
- node.twilioClient.makeCall( {to: tonum, from: node.fromNumber, url: twimlurl}, function(err, response) {
- if (err) {
- node.error(err.message,msg);
- }
- //console.log(response);
+ node.twilioClient.calls.create({to: tonum, from: node.fromNumber, url: twimlurl}).catch(function(err) {
+ node.error(err.message,msg);
});
}
else {
// Send SMS
- node.twilioClient.sendMessage( {to: tonum, from: node.fromNumber, body: msg.payload}, function(err, response) {
- if (err) {
- node.error(err.message,msg);
- }
- //console.log(response);
+ node.twilioClient.messages.create({to: tonum, from: node.fromNumber, body: msg.payload}).catch( function(err) {
+ node.error(err.message,msg);
});
}
}
diff --git a/social/twilio/package.json b/social/twilio/package.json
index 43b86383..4c0c4e12 100644
--- a/social/twilio/package.json
+++ b/social/twilio/package.json
@@ -3,7 +3,7 @@
"version" : "0.0.15",
"description" : "A Node-RED node to send SMS messages via the Twilio service.",
"dependencies" : {
- "twilio" : "^2.11.1"
+ "twilio" : "^3.11.3"
},
"repository" : {
"type":"git",
From cf48039427bc8aaca99d6f35c42e8c552bf99e8e Mon Sep 17 00:00:00 2001
From: borpin
Date: Thu, 29 Mar 2018 08:53:12 +0100
Subject: [PATCH 036/456] Improve HTTP response handling and error reporting
(#419)
Improve HTTP response handling and error reporting of emoncms node
---
io/emoncms/88-emoncms.js | 57 ++++++++++++++++++++++++++--------------
io/emoncms/package.json | 8 ++++--
2 files changed, 44 insertions(+), 21 deletions(-)
diff --git a/io/emoncms/88-emoncms.js b/io/emoncms/88-emoncms.js
index 40e532ce..481ce1cd 100644
--- a/io/emoncms/88-emoncms.js
+++ b/io/emoncms/88-emoncms.js
@@ -58,6 +58,7 @@ module.exports = function(RED) {
}
else {
node.error("ERROR : No valid data type set - " + this.datatype);
+ node.status({fill:"red",shape:"ring",text:"No valid data type set"});
return;
}
@@ -76,7 +77,7 @@ module.exports = function(RED) {
// check for a time object and setup URI if valid
if (typeof msg.time === "undefined") {
- node.warn("WARN: Time object undefined, no time set");
+ // node.warn("WARN: Time object undefined, no time set");
}
else {
if (!isNaN(msg.time)) {
@@ -84,7 +85,7 @@ module.exports = function(RED) {
}
else {
if (isNaN(Date.parse(msg.time))) {
- // error condition
+ // error condition as msg.tme has some value that is not understood
node.warn("WARN: Time object not valid, no time set - " + msg.time);
} else {
this.url += '&time=' + Date.parse(msg.time)/1000; //seconds
@@ -94,34 +95,52 @@ module.exports = function(RED) {
}
var URIsent = this.url;
- http.get(this.url, function(res) {
+ msg.payload = "";
+ msg.urlsent = decodeURIComponent(URIsent);
+
+ var request = http.get(this.url, function(res) {
msg.topic = "http response";
msg.rc = res.statusCode;
- msg.payload = "";
res.setEncoding('utf8');
+ var body = "";
+
res.on('data', function(chunk) {
- msg.payload += chunk;
+ body += chunk;
});
- res.on('end', function() { //A 200 StatusCode does not mean data input sucess
+
+ res.on('end', function() {
+ // need to test for JSON as some responses are not valid JSON
try {
- msg.payload = JSON.parse(msg.payload);
- if (msg.payload.success) {
- node.status({fill:"green",shape:"dot",text:"Success"});
- } else {
- msg.warning = "ERROR: API Call Failed";
- msg.payload.urlsent = decodeURIComponent(URIsent);
- node.error(msg);
- node.status({fill:"red",shape:"ring",text:"Failed"});
- }
+ msg.payload = JSON.parse(body);
}
- catch(err) {
- msg.warning = "ERROR: Http response"
- node.warn(msg);
- node.status({fill:"red",shape:"ring",text:"http issue"});
+ catch (e) {
+ msg.payload = body;
+ }
+
+ if (msg.payload.success) {
+ node.status({fill:"green",shape:"dot",text:"Success RC="+ msg.rc});
+ }
+ else if (msg.payload === 'ok') {
+ node.status({fill:"green",shape:"dot",text:"ok RC="+ msg.rc});
+ }
+ else if (msg.payload === 'Invalid API key') {
+ node.error(msg);
+ node.status({fill:"red",shape:"ring",text:"Invalid API key RC="+ msg.rc});
+ } else {
+ msg.warning = "ERROR: API Call Failed";
+ node.error(msg);
+ node.status({fill:"red",shape:"ring",text:"API Failed RC="+ msg.rc});
}
});
}).on('error', function(e) {
+ msg.warning = e
+ node.error(msg);
node.error(e,msg);
+ node.status({fill:"red",shape:"dot",text:"HTTP Error"});
+ });
+ request.setTimeout(1000, function() {
+ node.error("timeout: " + msg);
+ node.status({fill:"red",shape:"ring",text:"HTTP Timeout"});
});
});
}
diff --git a/io/emoncms/package.json b/io/emoncms/package.json
index b16bf8b8..926908fe 100644
--- a/io/emoncms/package.json
+++ b/io/emoncms/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-emoncms",
- "version" : "0.1.0",
+ "version" : "0.2.0",
"description" : "A Node-RED node to fetch/post data to/from emoncms",
"dependencies" : {
},
@@ -32,6 +32,10 @@
{
"name": "Glyn Hudson",
"email": "glyn.hudson@openenergymonitor.org"
- }
+ },
+ {
+ "name": "borpin",
+ "email": "brian.orpin@gmail.com"
+ }
]
}
From 4a8f071c917c485fb6596573e597d32ea2440427 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Thu, 29 Mar 2018 09:34:31 +0100
Subject: [PATCH 037/456] bump email, feed parser, twilio, sqlite, rbe packages
---
function/rbe/package.json | 2 +-
social/email/package.json | 2 +-
social/feedparser/package.json | 2 +-
social/twilio/package.json | 2 +-
storage/sqlite/package.json | 25 ++++++++++++++-----------
5 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/function/rbe/package.json b/function/rbe/package.json
index 4db5f001..61e07f8e 100644
--- a/function/rbe/package.json
+++ b/function/rbe/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-rbe",
- "version" : "0.2.1",
+ "version" : "0.2.2",
"description" : "A Node-RED node that provides report-by-exception (RBE) and deadband capability.",
"dependencies" : {
},
diff --git a/social/email/package.json b/social/email/package.json
index de19cd58..9d107473 100644
--- a/social/email/package.json
+++ b/social/email/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-email",
- "version": "0.1.25",
+ "version": "0.1.26",
"description": "Node-RED nodes to send and receive simple emails",
"dependencies": {
"nodemailer": "^1.11.0",
diff --git a/social/feedparser/package.json b/social/feedparser/package.json
index 7dcb87b7..1b990d8e 100644
--- a/social/feedparser/package.json
+++ b/social/feedparser/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-feedparser",
- "version": "0.1.10",
+ "version": "0.1.11",
"description": "A Node-RED node to get RSS Atom feeds.",
"dependencies": {
"feedparser": "^2.2.9",
diff --git a/social/twilio/package.json b/social/twilio/package.json
index 4c0c4e12..22b79dd7 100644
--- a/social/twilio/package.json
+++ b/social/twilio/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-twilio",
- "version" : "0.0.15",
+ "version" : "0.1.0",
"description" : "A Node-RED node to send SMS messages via the Twilio service.",
"dependencies" : {
"twilio" : "^3.11.3"
diff --git a/storage/sqlite/package.json b/storage/sqlite/package.json
index b85d3eec..6a77754f 100644
--- a/storage/sqlite/package.json
+++ b/storage/sqlite/package.json
@@ -1,18 +1,21 @@
{
- "name" : "node-red-node-sqlite",
- "version" : "0.2.0",
- "description" : "A sqlite node for Node-RED",
- "dependencies" : {
- "sqlite3" : "3.*"
+ "name": "node-red-node-sqlite",
+ "version": "0.2.1",
+ "description": "A sqlite node for Node-RED",
+ "dependencies": {
+ "sqlite3": "^4.0.0"
},
- "repository" : {
- "type":"git",
- "url":"https://github.com/node-red/node-red-nodes/storage/sqlite/"
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/node-red/node-red-nodes/storage/sqlite/"
},
"license": "Apache-2.0",
- "keywords": [ "node-red", "sqlite" ],
- "node-red" : {
- "nodes" : {
+ "keywords": [
+ "node-red",
+ "sqlite"
+ ],
+ "node-red": {
+ "nodes": {
"sqlite": "sqlite.js"
}
},
From 17744a51c0bc5afaa7a250c701b9dbe75d4b3c1d Mon Sep 17 00:00:00 2001
From: eRudy
Date: Thu, 29 Mar 2018 10:42:22 +0200
Subject: [PATCH 038/456] temporary solution for direct messages (#415)
* DMs are coming back :)
---
social/twitter/27-twitter.js | 29 ++++++++++++++++++++++-------
1 file changed, 22 insertions(+), 7 deletions(-)
diff --git a/social/twitter/27-twitter.js b/social/twitter/27-twitter.js
index 033d482a..01f20a06 100644
--- a/social/twitter/27-twitter.js
+++ b/social/twitter/27-twitter.js
@@ -386,6 +386,7 @@ module.exports = function(RED) {
this.twitterConfig = RED.nodes.getNode(this.twitter);
var credentials = RED.nodes.getCredentials(this.twitter);
var node = this;
+ var dm_user;
if (credentials && credentials.screen_name == this.twitterConfig.screen_name) {
var twit = new Ntwitter({
@@ -398,6 +399,10 @@ module.exports = function(RED) {
if (msg.hasOwnProperty("payload")) {
node.status({fill:"blue",shape:"dot",text:"twitter.status.tweeting"});
+ if (msg.payload.slice(0,2) == "D ") {
+ // direct message syntax: "D user message"
+ [dm_user,msg.payload]=msg.payload.match(/D\s+(\S+)\s+(.*)/).slice(1);
+ }
if (msg.payload.length > 280) {
msg.payload = msg.payload.slice(0,279);
node.warn(RED._("twitter.errors.truncated"));
@@ -434,13 +439,23 @@ module.exports = function(RED) {
}
else {
if (typeof msg.params === 'undefined') { msg.params = {}; }
- twit.updateStatus(msg.payload, msg.params, function (err, data) {
- if (err) {
- node.status({fill:"red",shape:"ring",text:"twitter.status.failed"});
- node.error(err,msg);
- }
- node.status({});
- });
+ if (dm_user) {
+ twit.newDirectMessage(dm_user,msg.payload, msg.params, function (err, data) {
+ if (err) {
+ node.status({fill:"red",shape:"ring",text:"twitter.status.failed"});
+ node.error(err,msg);
+ }
+ node.status({});
+ });
+ } else {
+ twit.updateStatus(msg.payload, msg.params, function (err, data) {
+ if (err) {
+ node.status({fill:"red",shape:"ring",text:"twitter.status.failed"});
+ node.error(err,msg);
+ }
+ node.status({});
+ });
+ }
}
}
else { node.warn(RED._("twitter.errors.nopayload")); }
From 84a445d9d868ff6ecbfdc008fd650127df7ec35c Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Thu, 29 Mar 2018 09:44:37 +0100
Subject: [PATCH 039/456] bump twitter node
---
social/twitter/package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/social/twitter/package.json b/social/twitter/package.json
index aa74574e..7a4f2b88 100644
--- a/social/twitter/package.json
+++ b/social/twitter/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-twitter",
- "version" : "0.1.12",
+ "version" : "0.1.13",
"description" : "A Node-RED node to talk to Twitter",
"dependencies" : {
"twitter-ng": "0.6.2",
From b8b5a92ad1e124efe9913fe2252193f15e3e6417 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Thu, 29 Mar 2018 17:39:46 +0100
Subject: [PATCH 040/456] update xmpp to keep working with open fire
---
social/xmpp/92-xmpp.js | 6 ++++--
social/xmpp/package.json | 2 +-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/social/xmpp/92-xmpp.js b/social/xmpp/92-xmpp.js
index 262b5d4c..fbadad31 100644
--- a/social/xmpp/92-xmpp.js
+++ b/social/xmpp/92-xmpp.js
@@ -102,7 +102,8 @@ module.exports = function(RED) {
host : node.host,
port : node.port,
skipPresence : true,
- reconnect : false
+ reconnect : false,
+ preferred : "PLAIN"
});
}
catch(e) {
@@ -179,7 +180,8 @@ module.exports = function(RED) {
host : node.host,
port : node.port,
skipPresence : true,
- reconnect : false
+ reconnect : false,
+ preferred : "PLAIN"
});
}
catch(e) {
diff --git a/social/xmpp/package.json b/social/xmpp/package.json
index 9b72311e..d3dca717 100644
--- a/social/xmpp/package.json
+++ b/social/xmpp/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-xmpp",
- "version" : "0.1.6",
+ "version" : "0.1.7",
"description" : "A Node-RED node to talk to an XMPP server",
"dependencies" : {
"simple-xmpp" : "1.3.*"
From 467907776088422882076f46d85e25601449564d Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Fri, 30 Mar 2018 14:50:51 +0100
Subject: [PATCH 041/456] Make extra node names more consistent i18n wise
---
function/rbe/locales/en-US/rbe.json | 1 +
function/rbe/package.json | 2 +-
function/rbe/rbe.html | 4 ++--
social/email/61-email.html | 5 ++++-
social/email/locales/en-US/61-email.json | 1 +
social/email/package.json | 2 +-
social/feedparser/32-feedparse.html | 2 +-
social/feedparser/locales/en-US/32-feedparse.json | 1 +
social/feedparser/package.json | 2 +-
utility/daemon/daemon.html | 2 +-
utility/daemon/package.json | 2 +-
11 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/function/rbe/locales/en-US/rbe.json b/function/rbe/locales/en-US/rbe.json
index d0d967bb..8adbb62a 100644
--- a/function/rbe/locales/en-US/rbe.json
+++ b/function/rbe/locales/en-US/rbe.json
@@ -1,5 +1,6 @@
{
"rbe": {
+ "rbe": "rbe",
"label": {
"func": "Mode",
"init": "Send initial value",
diff --git a/function/rbe/package.json b/function/rbe/package.json
index 61e07f8e..1d818f94 100644
--- a/function/rbe/package.json
+++ b/function/rbe/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-rbe",
- "version" : "0.2.2",
+ "version" : "0.2.3",
"description" : "A Node-RED node that provides report-by-exception (RBE) and deadband capability.",
"dependencies" : {
},
diff --git a/function/rbe/rbe.html b/function/rbe/rbe.html
index 759c7c06..48f0c103 100644
--- a/function/rbe/rbe.html
+++ b/function/rbe/rbe.html
@@ -87,8 +87,8 @@
outputs:1,
icon: "rbe.png",
label: function() {
- var ll = (this.func||"").replace("Eq","").replace("rbei","rbe")||"rbe";
- return this.name||ll||"rbe";
+ var ll = (this.func||"").replace("Eq","").replace("rbei","rbe")||this._("rbe.rbe");
+ return this.name||ll||this._("rbe.rbe");
},
labelStyle: function() {
return this.name?"node_label_italic":"";
diff --git a/social/email/61-email.html b/social/email/61-email.html
index aff990e7..7f5b1c00 100644
--- a/social/email/61-email.html
+++ b/social/email/61-email.html
@@ -245,8 +245,11 @@
inputs:0,
outputs:1,
icon: "envelope.png",
+ paletteLabel: function() {
+ return this.name||this._("email.email");
+ },
label: function() {
- return this.name||"email";
+ return this.name||this._("email.email");
},
labelStyle: function() {
return (this.name)?"node_label_italic":"";
diff --git a/social/email/locales/en-US/61-email.json b/social/email/locales/en-US/61-email.json
index a3d1c318..b7045623 100644
--- a/social/email/locales/en-US/61-email.json
+++ b/social/email/locales/en-US/61-email.json
@@ -1,5 +1,6 @@
{
"email": {
+ "email": "email",
"label": {
"to": "To",
"server": "Server",
diff --git a/social/email/package.json b/social/email/package.json
index 9d107473..fffb41bd 100644
--- a/social/email/package.json
+++ b/social/email/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-email",
- "version": "0.1.26",
+ "version": "0.1.27",
"description": "Node-RED nodes to send and receive simple emails",
"dependencies": {
"nodemailer": "^1.11.0",
diff --git a/social/feedparser/32-feedparse.html b/social/feedparser/32-feedparse.html
index 3581c75e..2175ad4a 100644
--- a/social/feedparser/32-feedparse.html
+++ b/social/feedparser/32-feedparse.html
@@ -35,7 +35,7 @@
outputs:1,
icon: "feed.png",
label: function() {
- return this.name||this.url||"feedparser";
+ return this.name||this.url||this._("feedparse.feedparse");
},
labelStyle: function() {
return this.name?"node_label_italic":"";
diff --git a/social/feedparser/locales/en-US/32-feedparse.json b/social/feedparser/locales/en-US/32-feedparse.json
index af751a4f..2a5fd943 100644
--- a/social/feedparser/locales/en-US/32-feedparse.json
+++ b/social/feedparser/locales/en-US/32-feedparse.json
@@ -1,5 +1,6 @@
{
"feedparse": {
+ "feedparse": "feedparser",
"label": {
"feedurl": "Feed url",
"refresh": "Refresh",
diff --git a/social/feedparser/package.json b/social/feedparser/package.json
index 1b990d8e..cc47eba5 100644
--- a/social/feedparser/package.json
+++ b/social/feedparser/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-feedparser",
- "version": "0.1.11",
+ "version": "0.1.12",
"description": "A Node-RED node to get RSS Atom feeds.",
"dependencies": {
"feedparser": "^2.2.9",
diff --git a/utility/daemon/daemon.html b/utility/daemon/daemon.html
index 6e7a5d8d..1b2f6963 100644
--- a/utility/daemon/daemon.html
+++ b/utility/daemon/daemon.html
@@ -64,7 +64,7 @@
icon: "arrow-in.png",
align: "right",
label: function() {
- return this.name||this.command;
+ return this.name||this.command||"daemon";
},
labelStyle: function() {
return this.name?"node_label_italic":"";
diff --git a/utility/daemon/package.json b/utility/daemon/package.json
index 089a8c26..b1ec9adc 100644
--- a/utility/daemon/package.json
+++ b/utility/daemon/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-daemon",
- "version" : "0.0.18",
+ "version" : "0.0.19",
"description" : "A Node-RED node that runs and monitors a long running system command.",
"dependencies" : {
},
From d28c5291c0a1b22eb381498e0c87e39a173a3c34 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Fri, 30 Mar 2018 14:53:25 +0100
Subject: [PATCH 042/456] bump daemon node package
---
utility/daemon/package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/utility/daemon/package.json b/utility/daemon/package.json
index b1ec9adc..67544484 100644
--- a/utility/daemon/package.json
+++ b/utility/daemon/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-daemon",
- "version" : "0.0.19",
+ "version" : "0.0.20",
"description" : "A Node-RED node that runs and monitors a long running system command.",
"dependencies" : {
},
From 99b83ea4bd88c0fd12b18ecc9be5a477fd9eb75b Mon Sep 17 00:00:00 2001
From: borpin
Date: Tue, 10 Apr 2018 12:19:41 +0100
Subject: [PATCH 043/456] io/emoncms - Modify HTTP Timeout (#430)
* Modify HTTP timeout
Increase the HTTP Timeout values from 1000 to 6000.
Modify error message.
---
io/emoncms/88-emoncms.js | 4 ++--
io/emoncms/package.json | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/io/emoncms/88-emoncms.js b/io/emoncms/88-emoncms.js
index 481ce1cd..b947e344 100644
--- a/io/emoncms/88-emoncms.js
+++ b/io/emoncms/88-emoncms.js
@@ -138,8 +138,8 @@ module.exports = function(RED) {
node.error(e,msg);
node.status({fill:"red",shape:"dot",text:"HTTP Error"});
});
- request.setTimeout(1000, function() {
- node.error("timeout: " + msg);
+ request.setTimeout(6000, function() {
+ node.error("HTTP Timeout",msg);
node.status({fill:"red",shape:"ring",text:"HTTP Timeout"});
});
});
diff --git a/io/emoncms/package.json b/io/emoncms/package.json
index 926908fe..0a52b7ac 100644
--- a/io/emoncms/package.json
+++ b/io/emoncms/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-emoncms",
- "version" : "0.2.0",
+ "version" : "0.2.1",
"description" : "A Node-RED node to fetch/post data to/from emoncms",
"dependencies" : {
},
From 025f97206f71d8136f692a45c232a348dfd45b4b Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Sat, 14 Apr 2018 22:43:14 +0100
Subject: [PATCH 044/456] tidy some labels
---
function/datagenerator/datagenerator.html | 4 +++-
function/datagenerator/locales/en-US/datagenerator.json | 1 +
io/ping/88-ping.html | 3 +++
io/ping/locales/en-US/88-ping.json | 1 +
io/ping/locales/ja/88-ping.json | 1 +
social/email/61-email.html | 5 ++++-
social/email/package.json | 2 +-
social/feedparser/32-feedparse.html | 3 +++
social/feedparser/package.json | 2 +-
9 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/function/datagenerator/datagenerator.html b/function/datagenerator/datagenerator.html
index edfabacc..d983d36d 100644
--- a/function/datagenerator/datagenerator.html
+++ b/function/datagenerator/datagenerator.html
@@ -40,7 +40,6 @@
RED.nodes.registerType('data-generator',{
color:"rgb(243, 181, 103)",
category: 'function',
- paletteLabel:"data generator",
defaults: {
name: {value:""},
field: {value:"payload"},
@@ -51,6 +50,9 @@
inputs:1,
outputs:1,
icon: "template.png",
+ paletteLabel: function() {
+ return this._("datagen.datagen");
+ },
label: function() {
return this.name || "data generator";
},
diff --git a/function/datagenerator/locales/en-US/datagenerator.json b/function/datagenerator/locales/en-US/datagenerator.json
index dffd35b3..2c038a2c 100644
--- a/function/datagenerator/locales/en-US/datagenerator.json
+++ b/function/datagenerator/locales/en-US/datagenerator.json
@@ -1,5 +1,6 @@
{
"datagen": {
+ "datagen": "datagenerator",
"label": {
"syntax": "Return",
"text": "a text string",
diff --git a/io/ping/88-ping.html b/io/ping/88-ping.html
index 32959eeb..ad1e2d26 100644
--- a/io/ping/88-ping.html
+++ b/io/ping/88-ping.html
@@ -33,6 +33,9 @@
inputs:0,
outputs:1,
icon: "alert.png",
+ paletteLabel: function() {
+ return this._("ping.ping");
+ },
label: function() {
return this.name||this.host;
},
diff --git a/io/ping/locales/en-US/88-ping.json b/io/ping/locales/en-US/88-ping.json
index 209e9da4..bcff8820 100644
--- a/io/ping/locales/en-US/88-ping.json
+++ b/io/ping/locales/en-US/88-ping.json
@@ -1,5 +1,6 @@
{
"ping": {
+ "ping": "ping",
"label": {
"target": "Target",
"ping": "Ping (S)"
diff --git a/io/ping/locales/ja/88-ping.json b/io/ping/locales/ja/88-ping.json
index 46478887..7b39cf3d 100644
--- a/io/ping/locales/ja/88-ping.json
+++ b/io/ping/locales/ja/88-ping.json
@@ -1,5 +1,6 @@
{
"ping": {
+ "ping": "ping",
"label": {
"target": "対象",
"ping": "Ping (秒)"
diff --git a/social/email/61-email.html b/social/email/61-email.html
index 7f5b1c00..d4598639 100644
--- a/social/email/61-email.html
+++ b/social/email/61-email.html
@@ -93,6 +93,9 @@
outputs:0,
icon: "envelope.png",
align: "right",
+ paletteLabel: function() {
+ return this._("email.email");
+ },
label: function() {
return this.dname||this.name||"email";
},
@@ -246,7 +249,7 @@
outputs:1,
icon: "envelope.png",
paletteLabel: function() {
- return this.name||this._("email.email");
+ return this._("email.email");
},
label: function() {
return this.name||this._("email.email");
diff --git a/social/email/package.json b/social/email/package.json
index fffb41bd..e224efc9 100644
--- a/social/email/package.json
+++ b/social/email/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-email",
- "version": "0.1.27",
+ "version": "0.1.28",
"description": "Node-RED nodes to send and receive simple emails",
"dependencies": {
"nodemailer": "^1.11.0",
diff --git a/social/feedparser/32-feedparse.html b/social/feedparser/32-feedparse.html
index 2175ad4a..0b815d5b 100644
--- a/social/feedparser/32-feedparse.html
+++ b/social/feedparser/32-feedparse.html
@@ -34,6 +34,9 @@
inputs:0,
outputs:1,
icon: "feed.png",
+ paletteLabel: function() {
+ return this._("feedparse.feedparse");
+ },
label: function() {
return this.name||this.url||this._("feedparse.feedparse");
},
diff --git a/social/feedparser/package.json b/social/feedparser/package.json
index cc47eba5..747710fb 100644
--- a/social/feedparser/package.json
+++ b/social/feedparser/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-feedparser",
- "version": "0.1.12",
+ "version": "0.1.13",
"description": "A Node-RED node to get RSS Atom feeds.",
"dependencies": {
"feedparser": "^2.2.9",
From 0f55fc160e828013aa668e9d30374fae0b807b9d Mon Sep 17 00:00:00 2001
From: cymplecy
Date: Sat, 14 Apr 2018 23:17:12 +0100
Subject: [PATCH 045/456] Add Gamma flag and Brightness control to
node-red-node-pi-neopixel (#431)
---
hardware/neopixel/neopix.py | 16 ++++++++++++++--
hardware/neopixel/neopixel.html | 24 +++++++++++++++++++++++-
hardware/neopixel/neopixel.js | 12 ++++++++++--
hardware/neopixel/package.json | 29 ++++++++++++++++-------------
4 files changed, 63 insertions(+), 18 deletions(-)
mode change 100644 => 100755 hardware/neopixel/neopixel.html
mode change 100644 => 100755 hardware/neopixel/neopixel.js
mode change 100644 => 100755 hardware/neopixel/package.json
diff --git a/hardware/neopixel/neopix.py b/hardware/neopixel/neopix.py
index 7f92fefb..ed1b51fb 100755
--- a/hardware/neopixel/neopix.py
+++ b/hardware/neopixel/neopix.py
@@ -36,9 +36,12 @@ LED_GAMMA = [
222,224,227,229,231,233,235,237,239,241,244,246,248,250,252,255]
-LED_COUNT = int(sys.argv[1])
-WAIT_MS = int(sys.argv[2])
+LED_COUNT = max(0,int(sys.argv[1]))
+WAIT_MS = max(0,int(sys.argv[2]))
MODE = sys.argv[3]
+LED_BRIGHTNESS = min(255,int(max(0,float(sys.argv[4])) * 255 / 100))
+if (sys.argv[5].lower() != "true"):
+ LED_GAMMA = range(256)
def getRGBfromI(RGBint):
blue = RGBint & 255
@@ -59,6 +62,12 @@ def setPixels(strip, s, e, color, wait_ms=30):
strip.show()
time.sleep(wait_ms/1000.0)
+def setBrightness(strip, brightness, wait_ms=30):
+ """Set overall brighness"""
+ strip.setBrightness(brightness)
+ strip.show()
+ time.sleep(wait_ms/1000.0)
+
def colorWipe(strip, color, wait_ms=30):
"""Wipe color across display a pixel at a time."""
for i in range(strip.numPixels()):
@@ -145,6 +154,9 @@ if __name__ == '__main__':
try:
data = raw_input()
bits = data.split(',')
+ if len(bits) == 2:
+ if bits[0] == "brightness":
+ setBrightness(strip, min(255,max(0,int(bits[1]))), WAIT_MS)
if len(bits) == 3:
if MODE == "shiftu":
shiftUp(strip, Color(int(bits[0]), int(bits[1]), int(bits[2])), WAIT_MS)
diff --git a/hardware/neopixel/neopixel.html b/hardware/neopixel/neopixel.html
old mode 100644
new mode 100755
index 43492c85..794599df
--- a/hardware/neopixel/neopixel.html
+++ b/hardware/neopixel/neopixel.html
@@ -31,6 +31,16 @@
+
+
+ (0-100)
+
+
+
+
+
@@ -53,6 +63,8 @@
A range of pixels from x to y can be set by msg.payload
with a CSV string x,y,r,g,b
+
By default, gamma correction is enabled but it can disabled which can be useful for working with low brightness levels
+
msg.brightness can be used to dynamically set brightness level
The pixels data line should be connected to Pi physical pin 12 - GPIO 18. Note:
this may conflict with audio playback.
msg.payloadに検索条件を指定する場合は 「検索条件」 を空欄にしてください。",
"status": {
@@ -39,7 +39,7 @@
"unexpectedend": "ストリームが予期せず終了しました",
"invalidtag": "無効なタグプロパティ",
"missingcredentials": "Twitterが認証されていません",
- "truncated": "140文字を超えるツイートが切り捨てられました",
+ "truncated": "280文字を超えるツイートが切り捨てられました",
"sendfail": "ツイートの投稿が失敗: __error__",
"nopayload": "ツイートするペイロードがありません",
"oauthbroke": "something in twitter oauth broke.",
diff --git a/social/twitter/package.json b/social/twitter/package.json
index d673a1aa..a179e78e 100644
--- a/social/twitter/package.json
+++ b/social/twitter/package.json
@@ -1,20 +1,23 @@
{
- "name" : "node-red-node-twitter",
- "version" : "0.1.15",
- "description" : "A Node-RED node to talk to Twitter",
- "dependencies" : {
+ "name": "node-red-node-twitter",
+ "version": "1.0.0",
+ "description": "A Node-RED node to talk to Twitter",
+ "dependencies": {
"twitter-ng": "0.6.2",
- "oauth" : "0.9.14",
- "request" : "^2.75.0"
+ "oauth": "0.9.14",
+ "request": "^2.75.0"
},
- "repository" : {
- "type":"git",
- "url":"https://github.com/node-red/node-red-nodes/tree/master/social/twitter"
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/node-red/node-red-nodes/tree/master/social/twitter"
},
"license": "Apache-2.0",
- "keywords": [ "node-red", "twitter" ],
- "node-red" : {
- "nodes" : {
+ "keywords": [
+ "node-red",
+ "twitter"
+ ],
+ "node-red": {
+ "nodes": {
"twitter": "27-twitter.js"
}
},
From aaf93ab587c9615d35f36284edcbbb4b018728f0 Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Thu, 7 Jun 2018 12:07:01 +0100
Subject: [PATCH 084/456] Handle upgrade from old to new twitter node better
---
social/twitter/27-twitter.js | 39 ++++++++++++++++++------------------
1 file changed, 20 insertions(+), 19 deletions(-)
diff --git a/social/twitter/27-twitter.js b/social/twitter/27-twitter.js
index edf72140..de89376e 100644
--- a/social/twitter/27-twitter.js
+++ b/social/twitter/27-twitter.js
@@ -5,6 +5,7 @@ module.exports = function(RED) {
var OAuth= require('oauth').OAuth;
var request = require('request');
var twitterRateTimeout;
+ var retry = 60000; // 60 secs backoff for now
function TwitterCredentialsNode(n) {
RED.nodes.createNode(this,n);
@@ -57,7 +58,7 @@ module.exports = function(RED) {
this.twitterConfig = RED.nodes.getNode(this.twitter);
var credentials = RED.nodes.getCredentials(this.twitter);
- if (credentials) {
+ if (credentials && credentials.consumer_key && credentials.consumer_secret && credentials.access_token && credentials.access_token_secret) {
var twit = new Ntwitter({
consumer_key: credentials.consumer_key,
consumer_secret: credentials.consumer_secret,
@@ -248,7 +249,6 @@ module.exports = function(RED) {
twit.stream(thing, st, function(stream) {
//console.log("ST",st);
node.stream = stream;
- var retry = 60000; // 60 secs backoff for now
stream.on('data', function(tweet) {
if (tweet.user !== undefined) {
var where = tweet.user.location;
@@ -358,25 +358,24 @@ module.exports = function(RED) {
node.error(err);
}
}
- }
- else {
+ this.on('close', function() {
+ if (this.tout) { clearTimeout(this.tout); }
+ if (this.tout2) { clearTimeout(this.tout2); }
+ if (this.stream) {
+ this.restart = false;
+ this.stream.removeAllListeners();
+ this.stream.destroy();
+ }
+ if (this.poll_ids) {
+ for (var i=0; i
Date: Fri, 8 Jun 2018 12:55:19 +0100
Subject: [PATCH 085/456] Fix tweet with image
---
social/twitter/27-twitter.html | 19 +++++++++++++++++--
social/twitter/27-twitter.js | 15 +++++++++++++++
social/twitter/package.json | 2 +-
3 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/social/twitter/27-twitter.html b/social/twitter/27-twitter.html
index a3646468..b501f407 100644
--- a/social/twitter/27-twitter.html
+++ b/social/twitter/27-twitter.html
@@ -59,12 +59,27 @@
},
label: function() {
if (this.screen_name) {
- return "@"+this.screen_name
+ return (this.screen_name[0]!=="@"?"@":"")+this.screen_name
} else {
return "Twitter: "+this.id
}
},
- exportable: false
+ exportable: false,
+ oneditsave: function() {
+ var trimFields = [
+ "consumer_key",
+ "consumer_secret",
+ "access_token",
+ "access_token_secret"
+ ];
+ // Just in case any whitespace has crept in with the copy-paste of the fields
+ trimFields.forEach(function(field) {
+ var v = $("#node-config-input-"+field).val();
+ v = v.trim();
+ $("#node-config-input-"+field).val(v);
+
+ });
+ }
});
})();
diff --git a/social/twitter/27-twitter.js b/social/twitter/27-twitter.js
index de89376e..531011af 100644
--- a/social/twitter/27-twitter.js
+++ b/social/twitter/27-twitter.js
@@ -10,6 +10,9 @@ module.exports = function(RED) {
function TwitterCredentialsNode(n) {
RED.nodes.createNode(this,n);
this.screen_name = n.screen_name;
+ if (this.screen_name && this.screen_name[0] !== "@") {
+ this.screen_name = "@"+this.screen_name;
+ }
}
RED.nodes.registerType("twitter-credentials",TwitterCredentialsNode,{
credentials: {
@@ -396,6 +399,18 @@ module.exports = function(RED) {
access_token_key: credentials.access_token,
access_token_secret: credentials.access_token_secret
});
+
+ var oa = new OAuth(
+ "https://api.twitter.com/oauth/request_token",
+ "https://api.twitter.com/oauth/access_token",
+ credentials.consumer_key,
+ credentials.consumer_secret,
+ "1.0",
+ null,
+ "HMAC-SHA1"
+ );
+
+
node.on("input", function(msg) {
if (msg.hasOwnProperty("payload")) {
node.status({fill:"blue",shape:"dot",text:"twitter.status.tweeting"});
diff --git a/social/twitter/package.json b/social/twitter/package.json
index a179e78e..2499af52 100644
--- a/social/twitter/package.json
+++ b/social/twitter/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-twitter",
- "version": "1.0.0",
+ "version": "1.0.1",
"description": "A Node-RED node to talk to Twitter",
"dependencies": {
"twitter-ng": "0.6.2",
From c511cf6ae7aebd3aec61429f7d32e57b2ac7c45f Mon Sep 17 00:00:00 2001
From: cymplecy
Date: Wed, 13 Jun 2018 22:09:55 +0100
Subject: [PATCH 086/456] Change DMA from 5 to 10 (#453)
I mentioned this a while ago
Following changes to Pi firmware/kernel, the DMA channel 5 is not reliable for use anymore. Other repositories have changed to use channel 10. https://github.com/jgarff/rpi_ws281x/pull/266/commits
I've been running 3 of my Pi on DMA 10 (1 new Pi3B+ and 2 older PiZeros running Jessie) for 2 months now without any issues so I'm making this pull request now
---
hardware/neopixel/neopix.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hardware/neopixel/neopix.py b/hardware/neopixel/neopix.py
index ed1b51fb..793a1d28 100755
--- a/hardware/neopixel/neopix.py
+++ b/hardware/neopixel/neopix.py
@@ -13,7 +13,7 @@ except ImportError:
LED_COUNT = 8 # Number of LED pixels.
LED_PIN = 18 # GPIO pin connected to the pixels (must support PWM!).
LED_FREQ_HZ = 800000 # LED signal frequency in hertz (usually 800khz)
-LED_DMA = 5 # DMA channel to use for generating signal (try 5)
+LED_DMA = 10 # DMA channel to use for generating signal (try 10)
LED_BRIGHTNESS = 255 # Set to 0 for darkest and 255 for brightest
LED_INVERT = False # True to invert the signal (when using NPN transistor level shift)
LED_CHANNEL = 0 # PWM channel
From 044d008e65903d427e6aaf75034fca0c130dd042 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Wed, 13 Jun 2018 22:12:33 +0100
Subject: [PATCH 087/456] bump neopixel node version for npm
to go with pr #453
---
hardware/neopixel/package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hardware/neopixel/package.json b/hardware/neopixel/package.json
index 9077022d..44a67678 100755
--- a/hardware/neopixel/package.json
+++ b/hardware/neopixel/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-pi-neopixel",
- "version" : "0.0.18",
+ "version" : "0.0.19",
"description" : "A Node-RED node to output to a neopixel (ws2812) string of LEDS from a Raspberry Pi.",
"dependencies" : {
},
From 76a221919aff54ce5e28658ce105b49ebf184bed Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Wed, 13 Jun 2018 22:13:22 +0100
Subject: [PATCH 088/456] Update Readme to remove NMA node
and add 2018 to serialport copyright
---
README.md | 2 +-
io/serialport/LICENSE | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 28dc1b13..95d0120e 100644
--- a/README.md
+++ b/README.md
@@ -151,7 +151,7 @@ Copyright JS Foundation and other contributors, http://js.foundation under [the
**node-red-node-irc** - *[91-irc](social/irc)* - Connects to an IRC server to send and receive messages.
-**node-red-node-nma** - *[57-nma](social/nma)* - Sends alerts to Android devices via the [Notify-My-Android](http://www.notifymyandroid.com/) app.
+**node-red-node-nma** - *[57-nma](social/nma)* - DEPRECATED as NMA closed down operations.
**node-red-node-notify** - *[57-notify](social/notify)* - Uses [Growl](http://growl.info/) to provide a desktop popup containing the payload. Only useful on the local Apple machine.
diff --git a/io/serialport/LICENSE b/io/serialport/LICENSE
index f5b60114..2efcba6b 100644
--- a/io/serialport/LICENSE
+++ b/io/serialport/LICENSE
@@ -1,4 +1,4 @@
-Copyright 2016 JS Foundation and other contributors, https://js.foundation/
+Copyright 2016,2018 JS Foundation and other contributors, https://js.foundation/
Copyright 2013-2016 IBM Corp.
Licensed under the Apache License, Version 2.0 (the "License");
From 88f7f52f9959ef0db202d7861ffe1e69de01e5ae Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Wed, 27 Jun 2018 21:36:06 +0100
Subject: [PATCH 089/456] Add pullup option to Arduino digital input
to Close #455
---
hardware/Arduino/35-arduino.html | 5 +++--
hardware/Arduino/35-arduino.js | 9 +++++++++
hardware/Arduino/README.md | 2 +-
hardware/Arduino/locales/en-US/35-arduino.json | 1 +
hardware/Arduino/package.json | 2 +-
5 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/hardware/Arduino/35-arduino.html b/hardware/Arduino/35-arduino.html
index 713b59dd..4cd1fef1 100644
--- a/hardware/Arduino/35-arduino.html
+++ b/hardware/Arduino/35-arduino.html
@@ -6,8 +6,9 @@
-
-
+
diff --git a/hardware/Arduino/35-arduino.js b/hardware/Arduino/35-arduino.js
index 062f11b2..8d604256 100644
--- a/hardware/Arduino/35-arduino.js
+++ b/hardware/Arduino/35-arduino.js
@@ -78,6 +78,15 @@ module.exports = function(RED) {
}
});
}
+ if (node.state === "PULLUP") {
+ node.board.pinMode(node.pin, 0x0B);
+ node.board.digitalRead(node.pin, function(v) {
+ if (v !== node.oldval) {
+ node.oldval = v;
+ node.send({payload:v, topic:node.pin});
+ }
+ });
+ }
if (node.state == "STRING") {
node.board.on('string', function(v) {
if (v !== node.oldval) {
diff --git a/hardware/Arduino/README.md b/hardware/Arduino/README.md
index 176d25a3..5a729834 100644
--- a/hardware/Arduino/README.md
+++ b/hardware/Arduino/README.md
@@ -23,7 +23,7 @@ details and examples of how to use this node.
Connects to local Arduino and monitors the selected pin for changes.
-You can select either **Digital**, **Analogue**, or **String** input type.
+You can select either **Digital**, **Pullup**, **Analogue**, or **String** input type.
Outputs the value read as `msg.payload` and the pin number as `msg.topic`.
It only outputs on a change of value - fine for digital inputs, but you can get a lot of data from analogue pins which you must then handle. For example you could use a `delay` node set to rate limit and drop intermediate values, or an `rbe` node to only report when it changes by a certain amount.
diff --git a/hardware/Arduino/locales/en-US/35-arduino.json b/hardware/Arduino/locales/en-US/35-arduino.json
index 7e731a50..640bfdc1 100644
--- a/hardware/Arduino/locales/en-US/35-arduino.json
+++ b/hardware/Arduino/locales/en-US/35-arduino.json
@@ -18,6 +18,7 @@
"state": {
"in": {
"digital": "Digital pin",
+ "pullup": "Digital pin with pullup",
"analogue": "Analogue pin",
"string": "String"
},
diff --git a/hardware/Arduino/package.json b/hardware/Arduino/package.json
index acc770eb..6b3b061a 100644
--- a/hardware/Arduino/package.json
+++ b/hardware/Arduino/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-arduino",
- "version" : "0.0.17",
+ "version" : "0.0.18",
"description" : "A Node-RED node to talk to an Arduino running firmata",
"dependencies" : {
"firmata" : "~0.19.1"
From b4fca36ab6163dd9c2a10f54fc103e64786a226b Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Sat, 7 Jul 2018 19:24:35 +0100
Subject: [PATCH 090/456] let python sub processes use python3
---
hardware/LEDborg/nrgpio.py | 32 ++++++++++++---------------
hardware/LEDborg/package.json | 2 +-
hardware/PiLcd/nrlcd.py | 8 +++----
hardware/PiLcd/package.json | 2 +-
hardware/PiLiter/nrgpio.py | 32 ++++++++++++---------------
hardware/PiLiter/package.json | 2 +-
hardware/PiSrf/nrsrf.py | 8 +++----
hardware/PiSrf/package.json | 2 +-
hardware/Pibrella/nrgpio.py | 40 +++++++++++++++-------------------
hardware/Pibrella/package.json | 2 +-
hardware/neopixel/neopix.py | 4 ++--
hardware/neopixel/package.json | 2 +-
12 files changed, 62 insertions(+), 74 deletions(-)
diff --git a/hardware/LEDborg/nrgpio.py b/hardware/LEDborg/nrgpio.py
index da5213af..d9c301cd 100755
--- a/hardware/LEDborg/nrgpio.py
+++ b/hardware/LEDborg/nrgpio.py
@@ -6,10 +6,6 @@ import sys
bounce = 20 # bounce time in mS to apply
-if sys.version_info >= (3,0):
- print("Sorry - currently only configured to work with python 2.x")
- sys.exit(1)
-
if len(sys.argv) > 1:
cmd = sys.argv[1].lower()
pin = int(sys.argv[2])
@@ -17,7 +13,7 @@ if len(sys.argv) > 1:
GPIO.setwarnings(False)
if cmd == "pwm":
- #print "Initialised pin "+str(pin)+" to PWM"
+ #print("Initialised pin "+str(pin)+" to PWM")
GPIO.setup(pin,GPIO.OUT)
p = GPIO.PWM(pin, 100)
p.start(0)
@@ -32,10 +28,10 @@ if len(sys.argv) > 1:
GPIO.cleanup(pin)
sys.exit(0)
except Exception as ex:
- print "bad data: "+data
+ print("bad data: "+data)
elif cmd == "buzz":
- #print "Initialised pin "+str(pin)+" to Buzz"
+ #print("Initialised pin "+str(pin)+" to Buzz")
GPIO.setup(pin,GPIO.OUT)
p = GPIO.PWM(pin, 100)
p.stop()
@@ -54,10 +50,10 @@ if len(sys.argv) > 1:
GPIO.cleanup(pin)
sys.exit(0)
except Exception as ex:
- print "bad data: "+data
+ print("bad data: "+data)
elif cmd == "out":
- #print "Initialised pin "+str(pin)+" to OUT"
+ #print("Initialised pin "+str(pin)+" to OUT")
GPIO.setup(pin,GPIO.OUT)
if len(sys.argv) == 4:
GPIO.output(pin,int(sys.argv[3]))
@@ -78,9 +74,9 @@ if len(sys.argv) > 1:
GPIO.output(pin,data)
elif cmd == "in":
- #print "Initialised pin "+str(pin)+" to IN"
+ #print("Initialised pin "+str(pin)+" to IN")
def handle_callback(chan):
- print GPIO.input(chan)
+ print(GPIO.input(chan))
if len(sys.argv) == 4:
if sys.argv[3].lower() == "up":
@@ -91,7 +87,7 @@ if len(sys.argv) > 1:
GPIO.setup(pin,GPIO.IN)
else:
GPIO.setup(pin,GPIO.IN)
- print GPIO.input(pin)
+ print(GPIO.input(pin))
GPIO.add_event_detect(pin, GPIO.BOTH, callback=handle_callback, bouncetime=bounce)
while True:
@@ -104,7 +100,7 @@ if len(sys.argv) > 1:
sys.exit(0)
elif cmd == "byte":
- #print "Initialised BYTE mode - "+str(pin)+
+ #print("Initialised BYTE mode - "+str(pin)+)
list = [7,11,13,12,15,16,18,22]
GPIO.setup(list,GPIO.OUT)
@@ -127,7 +123,7 @@ if len(sys.argv) > 1:
GPIO.output(list[bit], data & mask)
elif cmd == "borg":
- #print "Initialised BORG mode - "+str(pin)+
+ #print("Initialised BORG mode - "+str(pin)+)
GPIO.setup(11,GPIO.OUT)
GPIO.setup(13,GPIO.OUT)
GPIO.setup(15,GPIO.OUT)
@@ -154,10 +150,10 @@ if len(sys.argv) > 1:
data = 0
elif cmd == "rev":
- print GPIO.RPI_REVISION
+ print(GPIO.RPI_REVISION)
elif cmd == "ver":
- print GPIO.VERSION
+ print(GPIO.VERSION)
elif cmd == "mouse": # catch mice button events
file = open( "/dev/input/mice", "rb" )
@@ -171,7 +167,7 @@ if len(sys.argv) > 1:
button = ord( buf[0] ) & pin # mask out just the required button(s)
if button != oldbutt: # only send if changed
oldbutt = button
- print button
+ print(button)
while True:
try:
@@ -181,4 +177,4 @@ if len(sys.argv) > 1:
sys.exit(0)
else:
- print "Bad parameters - in|out|pwm|buzz|byte|borg|mouse|ver pin {value|up|down}"
+ print("Bad parameters - in|out|pwm|buzz|byte|borg|mouse|ver pin {value|up|down}")
diff --git a/hardware/LEDborg/package.json b/hardware/LEDborg/package.json
index f291c0fe..0250c128 100644
--- a/hardware/LEDborg/package.json
+++ b/hardware/LEDborg/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-ledborg",
- "version" : "0.0.19",
+ "version" : "0.0.20",
"description" : "A Node-RED node to control a PiBorg LedBorg board for a Raspberry Pi.",
"dependencies" : {
},
diff --git a/hardware/PiLcd/nrlcd.py b/hardware/PiLcd/nrlcd.py
index ec6dfc65..622a8c3f 100755
--- a/hardware/PiLcd/nrlcd.py
+++ b/hardware/PiLcd/nrlcd.py
@@ -107,8 +107,8 @@ def lcd_byte(bits, mode):
if len(sys.argv) > 1:
pins = sys.argv[1].lower().split(',')
if len(pins) != 6:
- print "Bad number of pins supplied"
- print " "+pins
+ print("Bad number of pins supplied")
+ print(" "+pins)
sys.exit(0)
LCD_RS = int(pins[0])
@@ -181,6 +181,6 @@ if len(sys.argv) > 1:
sys.exit(0)
else:
- print "Bad params"
- print " sudo nrlcd.py RS,E,D4,D5,D6,D7"
+ print("Bad params")
+ print(" sudo nrlcd.py RS,E,D4,D5,D6,D7")
sys.exit(0)
diff --git a/hardware/PiLcd/package.json b/hardware/PiLcd/package.json
index 2df7e705..e5526eac 100644
--- a/hardware/PiLcd/package.json
+++ b/hardware/PiLcd/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-pilcd",
- "version" : "0.0.9",
+ "version" : "0.0.10",
"description" : "A Node-RED node for Raspberry Pi to write to HD44780 style LCD panels.",
"dependencies" : {
},
diff --git a/hardware/PiLiter/nrgpio.py b/hardware/PiLiter/nrgpio.py
index da5213af..d9c301cd 100755
--- a/hardware/PiLiter/nrgpio.py
+++ b/hardware/PiLiter/nrgpio.py
@@ -6,10 +6,6 @@ import sys
bounce = 20 # bounce time in mS to apply
-if sys.version_info >= (3,0):
- print("Sorry - currently only configured to work with python 2.x")
- sys.exit(1)
-
if len(sys.argv) > 1:
cmd = sys.argv[1].lower()
pin = int(sys.argv[2])
@@ -17,7 +13,7 @@ if len(sys.argv) > 1:
GPIO.setwarnings(False)
if cmd == "pwm":
- #print "Initialised pin "+str(pin)+" to PWM"
+ #print("Initialised pin "+str(pin)+" to PWM")
GPIO.setup(pin,GPIO.OUT)
p = GPIO.PWM(pin, 100)
p.start(0)
@@ -32,10 +28,10 @@ if len(sys.argv) > 1:
GPIO.cleanup(pin)
sys.exit(0)
except Exception as ex:
- print "bad data: "+data
+ print("bad data: "+data)
elif cmd == "buzz":
- #print "Initialised pin "+str(pin)+" to Buzz"
+ #print("Initialised pin "+str(pin)+" to Buzz")
GPIO.setup(pin,GPIO.OUT)
p = GPIO.PWM(pin, 100)
p.stop()
@@ -54,10 +50,10 @@ if len(sys.argv) > 1:
GPIO.cleanup(pin)
sys.exit(0)
except Exception as ex:
- print "bad data: "+data
+ print("bad data: "+data)
elif cmd == "out":
- #print "Initialised pin "+str(pin)+" to OUT"
+ #print("Initialised pin "+str(pin)+" to OUT")
GPIO.setup(pin,GPIO.OUT)
if len(sys.argv) == 4:
GPIO.output(pin,int(sys.argv[3]))
@@ -78,9 +74,9 @@ if len(sys.argv) > 1:
GPIO.output(pin,data)
elif cmd == "in":
- #print "Initialised pin "+str(pin)+" to IN"
+ #print("Initialised pin "+str(pin)+" to IN")
def handle_callback(chan):
- print GPIO.input(chan)
+ print(GPIO.input(chan))
if len(sys.argv) == 4:
if sys.argv[3].lower() == "up":
@@ -91,7 +87,7 @@ if len(sys.argv) > 1:
GPIO.setup(pin,GPIO.IN)
else:
GPIO.setup(pin,GPIO.IN)
- print GPIO.input(pin)
+ print(GPIO.input(pin))
GPIO.add_event_detect(pin, GPIO.BOTH, callback=handle_callback, bouncetime=bounce)
while True:
@@ -104,7 +100,7 @@ if len(sys.argv) > 1:
sys.exit(0)
elif cmd == "byte":
- #print "Initialised BYTE mode - "+str(pin)+
+ #print("Initialised BYTE mode - "+str(pin)+)
list = [7,11,13,12,15,16,18,22]
GPIO.setup(list,GPIO.OUT)
@@ -127,7 +123,7 @@ if len(sys.argv) > 1:
GPIO.output(list[bit], data & mask)
elif cmd == "borg":
- #print "Initialised BORG mode - "+str(pin)+
+ #print("Initialised BORG mode - "+str(pin)+)
GPIO.setup(11,GPIO.OUT)
GPIO.setup(13,GPIO.OUT)
GPIO.setup(15,GPIO.OUT)
@@ -154,10 +150,10 @@ if len(sys.argv) > 1:
data = 0
elif cmd == "rev":
- print GPIO.RPI_REVISION
+ print(GPIO.RPI_REVISION)
elif cmd == "ver":
- print GPIO.VERSION
+ print(GPIO.VERSION)
elif cmd == "mouse": # catch mice button events
file = open( "/dev/input/mice", "rb" )
@@ -171,7 +167,7 @@ if len(sys.argv) > 1:
button = ord( buf[0] ) & pin # mask out just the required button(s)
if button != oldbutt: # only send if changed
oldbutt = button
- print button
+ print(button)
while True:
try:
@@ -181,4 +177,4 @@ if len(sys.argv) > 1:
sys.exit(0)
else:
- print "Bad parameters - in|out|pwm|buzz|byte|borg|mouse|ver pin {value|up|down}"
+ print("Bad parameters - in|out|pwm|buzz|byte|borg|mouse|ver pin {value|up|down}")
diff --git a/hardware/PiLiter/package.json b/hardware/PiLiter/package.json
index 2b9f059e..cc75478b 100644
--- a/hardware/PiLiter/package.json
+++ b/hardware/PiLiter/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-piliter",
- "version" : "0.0.12",
+ "version" : "0.0.13",
"description" : "A Node-RED node to drive a Raspberry Pi Pi-LITEr 8 LED board.",
"dependencies" : {
},
diff --git a/hardware/PiSrf/nrsrf.py b/hardware/PiSrf/nrsrf.py
index efb5a1f2..ab0d16d8 100755
--- a/hardware/PiSrf/nrsrf.py
+++ b/hardware/PiSrf/nrsrf.py
@@ -62,8 +62,8 @@ def restart():
if len(sys.argv) > 1:
pins = sys.argv[1].lower().split(',')
if len(pins) != 3:
- print "Bad parameters supplied"
- print pins
+ print("Bad parameters supplied")
+ print(pins)
sys.exit(0)
TRIGGER = int(pins[0])
@@ -91,6 +91,6 @@ if len(sys.argv) > 1:
sys.exit(0)
else:
- print "Bad params"
- print " sudo nrsrf.py trigger_pin,echo_pin,rate_in_seconds"
+ print("Bad params")
+ print(" sudo nrsrf.py trigger_pin,echo_pin,rate_in_seconds")
sys.exit(0)
diff --git a/hardware/PiSrf/package.json b/hardware/PiSrf/package.json
index 5b865604..7c26ba7f 100644
--- a/hardware/PiSrf/package.json
+++ b/hardware/PiSrf/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-pisrf",
- "version" : "0.1.1",
+ "version" : "0.1.2",
"description" : "A Node-RED node for a Raspberry Pi to use a SRF04 or SRF05 range finder",
"dependencies" : {
},
diff --git a/hardware/Pibrella/nrgpio.py b/hardware/Pibrella/nrgpio.py
index c69a5425..42a8d9b8 100755
--- a/hardware/Pibrella/nrgpio.py
+++ b/hardware/Pibrella/nrgpio.py
@@ -10,10 +10,6 @@ from time import sleep
bounce = 25;
-if sys.version_info >= (3,0):
- print("Sorry - currently only configured to work with python 2.x")
- sys.exit(1)
-
if len(sys.argv) > 2:
cmd = sys.argv[1].lower()
pin = int(sys.argv[2])
@@ -21,7 +17,7 @@ if len(sys.argv) > 2:
GPIO.setwarnings(False)
if cmd == "pwm":
- #print "Initialised pin "+str(pin)+" to PWM"
+ #print("Initialised pin "+str(pin)+" to PWM")
GPIO.setup(pin,GPIO.OUT)
p = GPIO.PWM(pin, 100)
p.start(0)
@@ -36,10 +32,10 @@ if len(sys.argv) > 2:
GPIO.cleanup(pin)
sys.exit(0)
except Exception as ex:
- print "bad data: "+data
+ print("bad data: "+data)
elif cmd == "buzz":
- #print "Initialised pin "+str(pin)+" to Buzz"
+ #print("Initialised pin "+str(pin)+" to Buzz")
GPIO.setup(pin,GPIO.OUT)
p = GPIO.PWM(pin, 100)
p.stop()
@@ -58,10 +54,10 @@ if len(sys.argv) > 2:
GPIO.cleanup(pin)
sys.exit(0)
except Exception as ex:
- print "bad data: "+data
+ print("bad data: "+data)
elif cmd == "out":
- #print "Initialised pin "+str(pin)+" to OUT"
+ #print("Initialised pin "+str(pin)+" to OUT")
GPIO.setup(pin,GPIO.OUT)
if len(sys.argv) == 4:
GPIO.output(pin,int(sys.argv[3]))
@@ -82,11 +78,11 @@ if len(sys.argv) > 2:
GPIO.output(pin,data)
elif cmd == "in":
- #print "Initialised pin "+str(pin)+" to IN"
+ #print("Initialised pin "+str(pin)+" to IN")
bounce = int(sys.argv[4])
def handle_callback(chan):
sleep(bounce/1000)
- print GPIO.input(chan)
+ print(GPIO.input(chan))
if sys.argv[3].lower() == "up":
GPIO.setup(pin,GPIO.IN,GPIO.PUD_UP)
@@ -95,7 +91,7 @@ if len(sys.argv) > 2:
else:
GPIO.setup(pin,GPIO.IN)
- print GPIO.input(pin)
+ print(GPIO.input(pin))
GPIO.add_event_detect(pin, GPIO.BOTH, callback=handle_callback, bouncetime=bounce)
while True:
@@ -108,7 +104,7 @@ if len(sys.argv) > 2:
sys.exit(0)
elif cmd == "byte":
- #print "Initialised BYTE mode - "+str(pin)+
+ #print("Initialised BYTE mode - "+str(pin)+)
list = [7,11,13,12,15,16,18,22]
GPIO.setup(list,GPIO.OUT)
@@ -131,7 +127,7 @@ if len(sys.argv) > 2:
GPIO.output(list[bit], data & mask)
elif cmd == "borg":
- #print "Initialised BORG mode - "+str(pin)+
+ #print("Initialised BORG mode - "+str(pin)+)
GPIO.setup(11,GPIO.OUT)
GPIO.setup(13,GPIO.OUT)
GPIO.setup(15,GPIO.OUT)
@@ -169,7 +165,7 @@ if len(sys.argv) > 2:
button = ord( buf[0] ) & pin # mask out just the required button(s)
if button != oldbutt: # only send if changed
oldbutt = button
- print button
+ print(button)
while True:
try:
@@ -194,7 +190,7 @@ if len(sys.argv) > 2:
# type,code,value
print("%u,%u" % (code, value))
event = file.read(EVENT_SIZE)
- print "0,0"
+ print("0,0")
file.close()
sys.exit(0)
except:
@@ -204,14 +200,14 @@ if len(sys.argv) > 2:
elif len(sys.argv) > 1:
cmd = sys.argv[1].lower()
if cmd == "rev":
- print GPIO.RPI_REVISION
+ print(GPIO.RPI_REVISION)
elif cmd == "ver":
- print GPIO.VERSION
+ print(GPIO.VERSION)
elif cmd == "info":
- print GPIO.RPI_INFO
+ print(GPIO.RPI_INFO)
else:
- print "Bad parameters - in|out|pwm|buzz|byte|borg|mouse|kbd|ver|info {pin} {value|up|down}"
- print " only ver (gpio version) and info (board information) accept no pin parameter."
+ print("Bad parameters - in|out|pwm|buzz|byte|borg|mouse|kbd|ver|info {pin} {value|up|down}")
+ print(" only ver (gpio version) and info (board information) accept no pin parameter.")
else:
- print "Bad parameters - in|out|pwm|buzz|byte|borg|mouse|kbd|ver|info {pin} {value|up|down}"
+ print("Bad parameters - in|out|pwm|buzz|byte|borg|mouse|kbd|ver|info {pin} {value|up|down}")
diff --git a/hardware/Pibrella/package.json b/hardware/Pibrella/package.json
index b7a6cd4e..ebb6bb76 100644
--- a/hardware/Pibrella/package.json
+++ b/hardware/Pibrella/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-pibrella",
- "version" : "0.0.12",
+ "version" : "0.0.13",
"description" : "A Node-RED node to read from and write to a Pibrella Raspberry Pi add-on board",
"dependencies" : {
},
diff --git a/hardware/neopixel/neopix.py b/hardware/neopixel/neopix.py
index 793a1d28..36ea2ae3 100755
--- a/hardware/neopixel/neopix.py
+++ b/hardware/neopixel/neopix.py
@@ -171,5 +171,5 @@ if __name__ == '__main__':
except (EOFError, SystemExit): # hopefully always caused by us sigint'ing the program
sys.exit(0)
except Exception as ex:
- print "bad data: "+data
- print ex
+ print("bad data: "+data)
+ print(ex)
diff --git a/hardware/neopixel/package.json b/hardware/neopixel/package.json
index 44a67678..85b1b882 100755
--- a/hardware/neopixel/package.json
+++ b/hardware/neopixel/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-pi-neopixel",
- "version" : "0.0.19",
+ "version" : "0.0.20",
"description" : "A Node-RED node to output to a neopixel (ws2812) string of LEDS from a Raspberry Pi.",
"dependencies" : {
},
From 27a103899305689791dc104b683558c81f689fef Mon Sep 17 00:00:00 2001
From: iurly
Date: Mon, 9 Jul 2018 12:14:08 +0200
Subject: [PATCH 091/456] Serial request (#426)
* serial: simplify serialPool.get
serialPool.get() has a lot of arguments.
Just pass the whole serialConfig object instead.
Also introduce early termination to remove one level of indentation.
(Just set your diff tool to ignore all whitespace changes to see
how very little this patch changes)
* serial: move splitting logic onto serialPool
All SerialIn and SerialOut nodes for a given port
share the same splitting logic as it is indeed
set by the common configuration node.
Move the code from SerialIn into serialPool so that
it can be reused by the serial request node.
Notice how the 'data' event will no longer carry
single bytes, but the whole payload instead.
Also move the output encoding logic into serialPool.
* serial: add serial request node
Add a "serial request" node to handle simple request/response
protocols. This node allows for multiple instances, all
sharing the same underlying device.
Responses coming from the serial line will only be propagated
to the output of the node where the request was originally received
(contrary to the "serial in" nodes which all emit the data
received from the serial line).
Every request received as an input to the node, is transmitted
to the serial line, and a matching response must be received
before the next one can be transmitted.
Any input message received in the meantime is internally enqueued.
The node is essentially a merge of serial in and serial out.
It shares the same configuration with serial in and serial out
for any given port and will not affect the behavior of the
existing nodes.
This means you can use, alongside with the request node:
- as many serial in nodes as you want -- e.g. to "sniff"
- serial out to inject mailicious/tampering data onto the serial
line, skipping the queueing mechanism
* serial request: provide some visual feedback on the node
add status indication:
- yellow "waiting" when a message is enqueued for sending
- green "OK" after an answer is received
- red "timeout" after a timeout occurs
More sofisticated output would include an indication of the number of messages
enqueued and the actual timeout remaining after sending.
* serial request: make default response timeout configurable
Notice it's a global setting (i.e. stored in the configuration node)
as opposed to per-node, but it can be overridden by setting msg.timeout.
* serial request: cosmetic changes
- added documentation about msg.port
- timeout field made wider so to accommodate default value of 10000ms
- replaced harcoded text with localizable strings for
"waiting" and "timeout" messages
* serial: cleanup: remove node.tout
this was probably some leftover code from previous implementations.
Now all timeouts are handled within the connection objects.
* serial: cleanup: set obj.tout to null after clearing it
clearing a Timeout without setting it back to null *might* have
adverse effects on later code which would check its null-ity.
Let's just do it.
* serial: cosmetic: add some comments
* serial request: fix "split on timeout" case
In the case of "split on timeout" case, we're reusing the same
.tout for two different purposes:
1) to send a timeout message, in case no answer is received at all [request]
2) to split messages, after receiving the first character [in+request]
So in the case of serial request, checking whether .tout is already
set is no longer a valid condition for 2).
Let's just check whether i === 1, and clear the timeout set up by 1)
if it's already there.
* serial: add "split on silence" behavior
add a fourth logic to split incoming data into messages.
The existing "split on timeout" logic starts the timeout upon
reception of the first character.
This might lead to unwanted behavior if for instance Node-RED is
restarted, as data might accumulate into OS buffers (see #410).
A different logic might be to only emit a message when enough time
has passed, without any new data being received (line silent), a.k.a.
interbyte timeout.
---
io/serialport/25-serial.html | 96 ++++-
io/serialport/25-serial.js | 465 +++++++++++++--------
io/serialport/locales/en-US/25-serial.json | 10 +
3 files changed, 398 insertions(+), 173 deletions(-)
diff --git a/io/serialport/25-serial.html b/io/serialport/25-serial.html
index 4fd2f063..835ad5a9 100644
--- a/io/serialport/25-serial.html
+++ b/io/serialport/25-serial.html
@@ -82,6 +82,63 @@
});
+
+
+
+
+
+
+
+
+
diff --git a/analysis/sentiment/72-sentiment.js b/analysis/sentiment/72-sentiment.js
new file mode 100644
index 00000000..915d5530
--- /dev/null
+++ b/analysis/sentiment/72-sentiment.js
@@ -0,0 +1,28 @@
+
+module.exports = function(RED) {
+ "use strict";
+ var sentiment = require('multilang-sentiment');
+
+ function SentimentNode(n) {
+ RED.nodes.createNode(this,n);
+ this.lang = n.lang;
+ this.property = n.property||"payload";
+ var node = this;
+
+ this.on("input", function(msg) {
+ var value = RED.util.getMessageProperty(msg,node.property);
+ if (value !== undefined) {
+ if (msg.hasOwnProperty("overrides")) {
+ msg.extras = msg.overrides;
+ delete msg.overrides;
+ }
+ sentiment(value, node.lang || msg.lang || 'en', {words: msg.extras || null}, function (err, result) {
+ msg.sentiment = result;
+ node.send(msg);
+ });
+ }
+ else { node.send(msg); } // If no matching property - just pass it on.
+ });
+ }
+ RED.nodes.registerType("sentiment",SentimentNode);
+}
diff --git a/analysis/sentiment/LICENSE b/analysis/sentiment/LICENSE
new file mode 100644
index 00000000..7fe18b61
--- /dev/null
+++ b/analysis/sentiment/LICENSE
@@ -0,0 +1,14 @@
+Copyright 2016, 2018 JS Foundation and other contributors, https://js.foundation/
+Copyright 2013-2016 IBM Corp.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/analysis/sentiment/README.md b/analysis/sentiment/README.md
new file mode 100644
index 00000000..0266b9f2
--- /dev/null
+++ b/analysis/sentiment/README.md
@@ -0,0 +1,31 @@
+node-red-node-sentiment
+========================
+
+A Node-RED node that scores incoming words
+using the AFINN-165 wordlist and attaches a sentiment.score property to the msg.
+
+Install
+-------
+
+This is a node that should be installed by default by Node-RED so you should not have to install it manually. If you do then run the following command in your Node-RED user directory - typically `~/.node-red`
+
+ npm install node-red-node-sentiment
+
+
+Usage
+-----
+
+Uses the AFINN-165 wordlist to attempt to assign scores to words in text.
+
+Attaches `msg.sentiment` to the msg and within that `msg.sentiment.score` holds the score.
+
+Supports multiple languages. These can be preselected in the node configuration. You can also set it so that `msg.lang` can be used to set the language dynamically if required. The cldr language codes supported are:
+
+ af, am, ar, az, be, bg, bn, bs, ca, ceb, co, cs, cy, da, de, el, en, eo, es, et, eu, fa, fi,
+ fr, fy, ga, gd, gl, gu, ha, haw, hi, hmn, hr, ht, hu, hy, id, ig, is, it, iw, ja, jw, ka, kk, km, kn, ko, ku, ky, la, lb, lo, lt,
+ lv, mg, mi, mk, ml, mn, mr, ms, mt, my, ne, nl, no, ny, pa, pl, ps, pt, ro, ru, sd, si, sk, sl, sm, sn, so, sq, sr, st, su, sv,
+ sw, ta, te, tg, th, tl, tr, uk, ur, uz, vi, xh, yi, yo, zh, zh-tw, zu
+
+A score greater than zero is positive and less than zero is negative. The score typically ranges from -5 to +5, but can go higher and lower.
+
+See the Multilang Sentiment docs here.
diff --git a/analysis/sentiment/locales/en-US/72-sentiment.json b/analysis/sentiment/locales/en-US/72-sentiment.json
new file mode 100644
index 00000000..b65aad90
--- /dev/null
+++ b/analysis/sentiment/locales/en-US/72-sentiment.json
@@ -0,0 +1,8 @@
+{
+ "sentiment": {
+ "sentiment": "sentiment",
+ "label": {
+ "language": "Language"
+ }
+ }
+}
diff --git a/analysis/sentiment/package.json b/analysis/sentiment/package.json
new file mode 100644
index 00000000..0a18be7d
--- /dev/null
+++ b/analysis/sentiment/package.json
@@ -0,0 +1,24 @@
+{
+ "name" : "node-red-node-sentiment",
+ "version" : "0.1.0",
+ "description" : "A Node-RED node that uses the AFINN-165 wordlists for sentiment analysis of words translated into multiple languages including emojis.",
+ "dependencies" : {
+ "multilang-sentiment" : "^1.1.6"
+ },
+ "repository" : {
+ "type":"git",
+ "url":"https://github.com/node-red/node-red-nodes/tree/master/analysis/sentiment"
+ },
+ "license": "Apache-2.0",
+ "keywords": [ "node-red", "sentiment", "anaylsis", "AFINN" ],
+ "node-red" : {
+ "nodes" : {
+ "sentiment": "72-sentiment.js"
+ }
+ },
+ "author": {
+ "name": "Dave Conway-Jones",
+ "email": "ceejay@vnet.ibm.com",
+ "url": "http://nodered.org"
+ }
+}
diff --git a/test/analysis/sentiment/72-sentiment_spec.js b/test/analysis/sentiment/72-sentiment_spec.js
new file mode 100644
index 00000000..dc61c536
--- /dev/null
+++ b/test/analysis/sentiment/72-sentiment_spec.js
@@ -0,0 +1,200 @@
+/**
+ * Copyright JS Foundation and other contributors, http://js.foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **/
+
+var should = require("should");
+var sentimentNode = require("../../../analysis/sentiment/72-sentiment.js");
+var helper = require("node-red-node-test-helper");
+
+describe('sentiment Node', function() {
+
+ before(function(done) {
+ helper.startServer(done);
+ });
+
+ after(function(done) {
+ helper.stopServer(done);
+ });
+
+ afterEach(function() {
+ helper.unload();
+ });
+
+ it('should be loaded', function(done) {
+ var flow = [{id:"sentimentNode1", type:"sentiment", name: "sentimentNode" }];
+ helper.load(sentimentNode, flow, function() {
+ var sentimentNode1 = helper.getNode("sentimentNode1");
+ sentimentNode1.should.have.property('name', 'sentimentNode');
+ done();
+ });
+ });
+
+ it('should pass on msg if no payload', function(done) {
+ var flow = [{id:"jn1",type:"sentiment",wires:[["jn2"]]},
+ {id:"jn2", type:"helper"}];
+ helper.load(sentimentNode, flow, function() {
+ var jn1 = helper.getNode("jn1");
+ var jn2 = helper.getNode("jn2");
+ jn2.on("input", function(msg) {
+ msg.should.not.have.property('sentiment');
+ msg.topic.should.equal("pass on");
+ done();
+ });
+ var testString = 'good, great, best, brilliant';
+ jn1.receive({topic:"pass on"});
+ });
+ });
+
+ it('should add a positive score for good words', function(done) {
+ var flow = [{id:"jn1",type:"sentiment",wires:[["jn2"]]},
+ {id:"jn2", type:"helper"}];
+ helper.load(sentimentNode, flow, function() {
+ var jn1 = helper.getNode("jn1");
+ var jn2 = helper.getNode("jn2");
+ jn2.on("input", function(msg) {
+ try {
+ msg.should.have.property('sentiment');
+ msg.sentiment.should.have.property('score');
+ msg.sentiment.score.should.be.a.Number();
+ msg.sentiment.score.should.be.above(10);
+ done();
+ } catch(err) {
+ done(err);
+ }
+ });
+ var testString = 'good, great, best, brilliant';
+ jn1.receive({payload:testString});
+ });
+ });
+
+ it('should add a positive score for good words (in French)', function(done) {
+ var flow = [{id:"jn1",type:"sentiment",wires:[["jn2"]],lang:"fr"},
+ {id:"jn2", type:"helper"}];
+ helper.load(sentimentNode, flow, function() {
+ var jn1 = helper.getNode("jn1");
+ var jn2 = helper.getNode("jn2");
+ jn2.on("input", function(msg) {
+ try {
+ msg.should.have.property('sentiment');
+ msg.sentiment.should.have.property('score');
+ msg.sentiment.score.should.be.a.Number();
+ msg.sentiment.score.should.be.above(5);
+ done();
+ } catch(err) {
+ done(err);
+ }
+ });
+ var testString = 'bon, belle, don du ciel, brillant';
+ jn1.receive({payload:testString});
+ });
+ });
+
+ it('should add a positive score for good words - alternative property', function(done) {
+ var flow = [{id:"jn1",type:"sentiment",property:"foo",wires:[["jn2"]]},
+ {id:"jn2", type:"helper"}];
+ helper.load(sentimentNode, flow, function() {
+ var jn1 = helper.getNode("jn1");
+ var jn2 = helper.getNode("jn2");
+ jn2.on("input", function(msg) {
+ try {
+ msg.should.have.property('sentiment');
+ msg.sentiment.should.have.property('score');
+ msg.sentiment.score.should.be.a.Number();
+ msg.sentiment.score.should.be.above(10);
+ done();
+ } catch(err) {
+ done(err);
+ }
+ });
+ var testString = 'good, great, best, brilliant';
+ jn1.receive({foo:testString});
+ });
+ });
+
+ it('should add a negative score for bad words', function(done) {
+ var flow = [{id:"jn1",type:"sentiment",wires:[["jn2"]]},
+ {id:"jn2", type:"helper"}];
+ helper.load(sentimentNode, flow, function() {
+ var jn1 = helper.getNode("jn1");
+ var jn2 = helper.getNode("jn2");
+ jn2.on("input", function(msg) {
+ msg.should.have.property('sentiment');
+ msg.sentiment.should.have.property('score');
+ msg.sentiment.score.should.be.a.Number();
+ msg.sentiment.score.should.be.below(-10);
+ done();
+ });
+ var testString = 'bad, horrible, negative, awful';
+ jn1.receive({payload:testString});
+ });
+ });
+
+ it('should add a negative score for bad words - alternative property', function(done) {
+ var flow = [{id:"jn1",type:"sentiment",property:"foo",wires:[["jn2"]]},
+ {id:"jn2", type:"helper"}];
+ helper.load(sentimentNode, flow, function() {
+ var jn1 = helper.getNode("jn1");
+ var jn2 = helper.getNode("jn2");
+ jn2.on("input", function(msg) {
+ msg.should.have.property('sentiment');
+ msg.sentiment.should.have.property('score');
+ msg.sentiment.score.should.be.a.Number();
+ msg.sentiment.score.should.be.below(-10);
+ done();
+ });
+ var testString = 'bad, horrible, negative, awful';
+ jn1.receive({foo:testString});
+ });
+ });
+
+ it('should allow you to override word scoring', function(done) {
+ var flow = [{id:"jn1",type:"sentiment",wires:[["jn2"]]},
+ {id:"jn2", type:"helper"}];
+ helper.load(sentimentNode, flow, function() {
+ var jn1 = helper.getNode("jn1");
+ var jn2 = helper.getNode("jn2");
+ jn2.on("input", function(msg) {
+ msg.should.have.property('sentiment');
+ msg.sentiment.should.have.property('score');
+ msg.sentiment.score.should.be.a.Number();
+ msg.sentiment.score.should.equal(20);
+ done();
+ });
+ var testString = 'sick, wicked';
+ var overrides = {'sick': 10, 'wicked': 10 };
+ jn1.receive({payload:testString,overrides:overrides});
+ });
+ });
+
+ it('should allow you to override word scoring - alternative property', function(done) {
+ var flow = [{id:"jn1",type:"sentiment",property:"foo",wires:[["jn2"]]},
+ {id:"jn2", type:"helper"}];
+ helper.load(sentimentNode, flow, function() {
+ var jn1 = helper.getNode("jn1");
+ var jn2 = helper.getNode("jn2");
+ jn2.on("input", function(msg) {
+ msg.should.have.property('sentiment');
+ msg.sentiment.should.have.property('score');
+ msg.sentiment.score.should.be.a.Number();
+ msg.sentiment.score.should.equal(20);
+ done();
+ });
+ var testString = 'sick, wicked';
+ var overrides = {'sick': 10, 'wicked': 10 };
+ jn1.receive({foo:testString,overrides:overrides});
+ });
+ });
+
+});
From f3b0e2277d20ecf5dba00849bd95f54a8c313f9a Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Sat, 11 Aug 2018 14:00:26 +0100
Subject: [PATCH 097/456] update blinkstick links to colors
To close #427
---
hardware/blinkstick/76-blinkstick.html | 2 +-
hardware/blinkstick/package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/hardware/blinkstick/76-blinkstick.html b/hardware/blinkstick/76-blinkstick.html
index 135fe2ba..0f9ce707 100644
--- a/hardware/blinkstick/76-blinkstick.html
+++ b/hardware/blinkstick/76-blinkstick.html
@@ -61,7 +61,7 @@
Note: Setting the database name to :memory:
+ will create a non-persistant in memory database.
@@ -96,12 +96,8 @@
-
-
- Twitter are withdrawing the API used to access a user's activity stream in August 2018 so this feature will be removed from the node in the near future. See here for details.
-
@@ -116,23 +112,28 @@
@@ -81,6 +86,7 @@
server: {value:"smtp.gmail.com",required:true},
port: {value:"465",required:true},
secure: {value: true},
+ tls: {value: true},
name: {value:""},
dname: {value:""}
},
diff --git a/social/email/61-email.js b/social/email/61-email.js
index 92a7cdea..e3e6a0fa 100644
--- a/social/email/61-email.js
+++ b/social/email/61-email.js
@@ -30,6 +30,7 @@ module.exports = function(RED) {
this.outserver = n.server;
this.outport = n.port;
this.secure = n.secure;
+ this.tls = true;
var flag = false;
if (this.credentials && this.credentials.hasOwnProperty("userid")) {
this.userid = this.credentials.userid;
@@ -50,12 +51,16 @@ module.exports = function(RED) {
if (flag) {
RED.nodes.addCredentials(n.id,{userid:this.userid, password:this.password, global:true});
}
+ if (n.tls === false){
+ this.tls = false;
+ }
var node = this;
var smtpOptions = {
host: node.outserver,
port: node.outport,
- secure: node.secure
+ secure: node.secure,
+ tls: {rejectUnauthorized: node.tls}
}
if (this.userid && this.password) {
diff --git a/social/email/locales/en-US/61-email.json b/social/email/locales/en-US/61-email.json
index fbe47766..d3f05375 100644
--- a/social/email/locales/en-US/61-email.json
+++ b/social/email/locales/en-US/61-email.json
@@ -13,6 +13,7 @@
"folder": "Folder",
"protocol": "Protocol",
"useSSL": "Use SSL?",
+ "useTLS": "Use TLS?",
"disposition": "Disposition",
"none": "None",
"read": "Mark Read",
From 1b0f573f4e1f9e71b91c402e2c4061478a81315f Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Wed, 22 Aug 2018 13:58:55 +0100
Subject: [PATCH 125/456] let sqlite add extensions
---
storage/sqlite/README.md | 2 ++
storage/sqlite/package.json | 2 +-
storage/sqlite/sqlite.html | 2 ++
storage/sqlite/sqlite.js | 39 ++++++++++++++++++++++++-------------
4 files changed, 30 insertions(+), 15 deletions(-)
diff --git a/storage/sqlite/README.md b/storage/sqlite/README.md
index 9d2b8d3c..ae94aee3 100644
--- a/storage/sqlite/README.md
+++ b/storage/sqlite/README.md
@@ -25,6 +25,8 @@ By it's very nature it is SQL injection... so *be careful* out there...
Typically the returned payload will be an array of the result rows, (or an error).
+You can load sqlite extensions by inputting a msg.extension property containing the full path and filename.
+
The reconnect timeout in milliseconds can be changed by adding a line to **settings.js**
sqliteReconnectTime: 20000,
diff --git a/storage/sqlite/package.json b/storage/sqlite/package.json
index 7bf56945..c671502c 100644
--- a/storage/sqlite/package.json
+++ b/storage/sqlite/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-sqlite",
- "version": "0.3.2",
+ "version": "0.3.3",
"description": "A sqlite node for Node-RED",
"dependencies": {
"sqlite3": "^4.0.2"
diff --git a/storage/sqlite/sqlite.html b/storage/sqlite/sqlite.html
index 923f817c..28d5d966 100644
--- a/storage/sqlite/sqlite.html
+++ b/storage/sqlite/sqlite.html
@@ -77,6 +77,8 @@
be sure to include $ on the parameter object key.
Using any SQL Query, the result is returned in msg.payload
Typically the returned payload will be an array of the result rows, (or an error).
+
You can load sqlite extensions by inputting a msg.extension property containing the full
+ path and filename.
The reconnect timeout in milliseconds can be changed by adding a line to settings.js
sqliteReconnectTime: 20000,
diff --git a/storage/sqlite/sqlite.js b/storage/sqlite/sqlite.js
index c5ec8e0b..39c0bc68 100644
--- a/storage/sqlite/sqlite.js
+++ b/storage/sqlite/sqlite.js
@@ -43,12 +43,13 @@ module.exports = function(RED) {
var node = this;
node.status({});
- if (this.mydbConfig) {
- this.mydbConfig.doConnect();
+ if (node.mydbConfig) {
+ node.mydbConfig.doConnect();
node.status({fill:"green",shape:"dot",text:this.mydbConfig.mod});
var bind = [];
- node.on("input", function(msg) {
- if (this.sqlquery == "msg.topic"){
+
+ var doQuery = function(msg) {
+ if (node.sqlquery == "msg.topic"){
if (typeof msg.topic === 'string') {
bind = Array.isArray(msg.payload) ? msg.payload : [];
node.mydbConfig.db.all(msg.topic, bind, function(err, row) {
@@ -64,7 +65,7 @@ module.exports = function(RED) {
node.status({fill:"red",shape:"dot",text:"msg.topic error"});
}
}
- if (this.sqlquery == "batch") {
+ if (node.sqlquery == "batch") {
if (typeof msg.topic === 'string') {
node.mydbConfig.db.exec(msg.topic, function(err) {
if (err) { node.error(err,msg);}
@@ -79,10 +80,10 @@ module.exports = function(RED) {
node.status({fill:"red", shape:"dot",text:"msg.topic error"});
}
}
- if (this.sqlquery == "fixed"){
- if (typeof this.sql === 'string'){
+ if (node.sqlquery == "fixed"){
+ if (typeof node.sql === 'string'){
bind = Array.isArray(msg.payload) ? msg.payload : [];
- node.mydbConfig.db.all(this.sql, bind, function(err, row) {
+ node.mydbConfig.db.all(node.sql, bind, function(err, row) {
if (err) { node.error(err,msg); }
else {
msg.payload = row;
@@ -91,15 +92,15 @@ module.exports = function(RED) {
});
}
else{
- if (this.sql === null || this.sql == ""){
+ if (node.sql === null || node.sql == ""){
node.error("SQL statement config not set up",msg);
node.status({fill:"red",shape:"dot",text:"SQL config not set up"});
}
}
}
- if (this.sqlquery == "prepared"){
- if (typeof this.sql === 'string' && typeof msg.params !== "undefined" && typeof msg.params === "object"){
- node.mydbConfig.db.all(this.sql, msg.params, function(err, row) {
+ if (node.sqlquery == "prepared"){
+ if (typeof node.sql === 'string' && typeof msg.params !== "undefined" && typeof msg.params === "object"){
+ node.mydbConfig.db.all(node.sql, msg.params, function(err, row) {
if (err) { node.error(err,msg); }
else {
msg.payload = row;
@@ -108,7 +109,7 @@ module.exports = function(RED) {
});
}
else{
- if (this.sql === null || this.sql == ""){
+ if (node.sql === null || node.sql == ""){
node.error("Prepared statement config not set up",msg);
node.status({fill:"red",shape:"dot",text:"Prepared statement not set up"});
}
@@ -122,10 +123,20 @@ module.exports = function(RED) {
}
}
}
+ }
+
+ node.on("input", function(msg) {
+ if (msg.hasOwnProperty("extension")) {
+ node.mydbConfig.db.loadExtension(msg.extension, function(err) {
+ if (err) { node.error(err,msg); }
+ else { doQuery(msg); }
+ });
+ }
+ else { doQuery(msg); }
});
}
else {
- this.error("Sqlite database not configured");
+ node.error("Sqlite database not configured");
}
}
RED.nodes.registerType("sqlite",SqliteNodeIn);
From 0b65cd86528993d7bcce7c20007241016744c189 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Wed, 22 Aug 2018 23:47:03 +0100
Subject: [PATCH 126/456] sqlite - better handle extensions timing
---
storage/sqlite/package.json | 2 +-
storage/sqlite/sqlite.js | 82 ++++++++++++++++++++-----------------
2 files changed, 46 insertions(+), 38 deletions(-)
diff --git a/storage/sqlite/package.json b/storage/sqlite/package.json
index c671502c..cc31580a 100644
--- a/storage/sqlite/package.json
+++ b/storage/sqlite/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-sqlite",
- "version": "0.3.3",
+ "version": "0.3.4",
"description": "A sqlite node for Node-RED",
"dependencies": {
"sqlite3": "^4.0.2"
diff --git a/storage/sqlite/sqlite.js b/storage/sqlite/sqlite.js
index 39c0bc68..540e21e4 100644
--- a/storage/sqlite/sqlite.js
+++ b/storage/sqlite/sqlite.js
@@ -51,14 +51,16 @@ module.exports = function(RED) {
var doQuery = function(msg) {
if (node.sqlquery == "msg.topic"){
if (typeof msg.topic === 'string') {
- bind = Array.isArray(msg.payload) ? msg.payload : [];
- node.mydbConfig.db.all(msg.topic, bind, function(err, row) {
- if (err) { node.error(err,msg); }
- else {
- msg.payload = row;
- node.send(msg);
- }
- });
+ if (msg.topic.length > 0) {
+ bind = Array.isArray(msg.payload) ? msg.payload : [];
+ node.mydbConfig.db.all(msg.topic, bind, function(err, row) {
+ if (err) { node.error(err,msg); }
+ else {
+ msg.payload = row;
+ node.send(msg);
+ }
+ });
+ }
}
else {
node.error("msg.topic : the query is not defined as a string",msg);
@@ -67,13 +69,15 @@ module.exports = function(RED) {
}
if (node.sqlquery == "batch") {
if (typeof msg.topic === 'string') {
- node.mydbConfig.db.exec(msg.topic, function(err) {
- if (err) { node.error(err,msg);}
- else {
- msg.payload = [];
- node.send(msg);
- }
- });
+ if (msg.topic.length > 0) {
+ node.mydbConfig.db.exec(msg.topic, function(err) {
+ if (err) { node.error(err,msg);}
+ else {
+ msg.payload = [];
+ node.send(msg);
+ }
+ });
+ }
}
else {
node.error("msg.topic : the query is not defined as string", msg);
@@ -81,43 +85,47 @@ module.exports = function(RED) {
}
}
if (node.sqlquery == "fixed"){
- if (typeof node.sql === 'string'){
- bind = Array.isArray(msg.payload) ? msg.payload : [];
- node.mydbConfig.db.all(node.sql, bind, function(err, row) {
- if (err) { node.error(err,msg); }
- else {
- msg.payload = row;
- node.send(msg);
- }
- });
+ if (typeof node.sql === 'string') {
+ if (msg.payload && msg.payload.length > 0) {
+ bind = Array.isArray(msg.payload) ? msg.payload : [];
+ node.mydbConfig.db.all(node.sql, bind, function(err, row) {
+ if (err) { node.error(err,msg); }
+ else {
+ msg.payload = row;
+ node.send(msg);
+ }
+ });
+ }
}
else{
- if (node.sql === null || node.sql == ""){
+ if (node.sql === null || node.sql == "") {
node.error("SQL statement config not set up",msg);
node.status({fill:"red",shape:"dot",text:"SQL config not set up"});
}
}
}
if (node.sqlquery == "prepared"){
- if (typeof node.sql === 'string' && typeof msg.params !== "undefined" && typeof msg.params === "object"){
- node.mydbConfig.db.all(node.sql, msg.params, function(err, row) {
- if (err) { node.error(err,msg); }
- else {
- msg.payload = row;
- node.send(msg);
- }
- });
+ if (typeof node.sql === 'string' && typeof msg.params !== "undefined" && typeof msg.params === "object") {
+ if (node.sql.length > 0) {
+ node.mydbConfig.db.all(node.sql, msg.params, function(err, row) {
+ if (err) { node.error(err,msg); }
+ else {
+ msg.payload = row;
+ node.send(msg);
+ }
+ });
+ }
}
- else{
- if (node.sql === null || node.sql == ""){
+ else {
+ if (node.sql === null || node.sql == "") {
node.error("Prepared statement config not set up",msg);
node.status({fill:"red",shape:"dot",text:"Prepared statement not set up"});
}
- if (typeof msg.params == "undefined"){
+ if (typeof msg.params == "undefined") {
node.error("msg.params not passed");
node.status({fill:"red",shape:"dot",text:"msg.params not defined"});
}
- else if (typeof msg.params != "object"){
+ else if (typeof msg.params != "object") {
node.error("msg.params not an object");
node.status({fill:"red",shape:"dot",text:"msg.params not an object"});
}
From 6d36f5db8a20fee08870254bbc5d0b0f29d48ef1 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Thu, 23 Aug 2018 08:55:51 +0100
Subject: [PATCH 127/456] sqlite - add test extension - half.c
---
storage/sqlite/ext/half.c | 30 ++++++++++++++++++++++++++++++
storage/sqlite/ext/half.dylib | Bin 0 -> 4616 bytes
2 files changed, 30 insertions(+)
create mode 100644 storage/sqlite/ext/half.c
create mode 100755 storage/sqlite/ext/half.dylib
diff --git a/storage/sqlite/ext/half.c b/storage/sqlite/ext/half.c
new file mode 100644
index 00000000..5c746314
--- /dev/null
+++ b/storage/sqlite/ext/half.c
@@ -0,0 +1,30 @@
+/* Add your header comment here */
+
+#include
+SQLITE_EXTENSION_INIT1
+
+/*
+** The half() SQL function returns half of its input value.
+*/
+static void halfFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ sqlite3_result_double(context, 0.5*sqlite3_value_double(argv[0]));
+}
+
+/* SQLite invokes this routine once when it loads the extension.
+** Create new functions, collating sequences, and virtual table
+** modules here. This is usually the only exported symbol in
+** the shared library.
+*/
+int sqlite3_extension_init(
+ sqlite3 *db,
+ char **pzErrMsg,
+ const sqlite3_api_routines *pApi
+){
+ SQLITE_EXTENSION_INIT2(pApi)
+ sqlite3_create_function(db, "half", 1, SQLITE_ANY, 0, halfFunc, 0, 0);
+ return 0;
+}
diff --git a/storage/sqlite/ext/half.dylib b/storage/sqlite/ext/half.dylib
new file mode 100755
index 0000000000000000000000000000000000000000..50bf666d04b3878bf6bb9755ca67e970bf774dc0
GIT binary patch
literal 4616
zcmeHLO=uHA6rR}D|C%Zk6cvL6|G;c&E4CMHrI8VT5Ntsa8QLbPE6t|uCRz`LLKR%1
zP{e}=&+4(@rQQ_9suz0@@!%n#f(HdHBI3dNeVdtf4Jw{xAG~?<&HJ18W)FFJ{{7>R
zB|=1Mgb<6t_24OhOQHcgA=ZH}M}$zSD|MpFKl*j4m@S-XjF_ShT&p!o6*41*1+(gS
zldCGauiAvz`1(h+Voa-ip;TYqaTfws$Ga1)STEI1#H{g8gm`XY*mnB0L3O-I9gj7U
z46Yy{7MYEfN)?^+wv$%2lg;C-I^L9yC$&9sb&Oz0zQYYaPG?6~M?hoxZ)8BlE#HB4
z;|YCY-*UOUqap6~`*@~rvpQk@6QHxknp=3ZJZ)kX4N!C3t6
zwt?4HouBC$$R^Sk2JBuaK%0daOIEgjUy+Y?Ovjk5z^fr8miv$^z{kKOetKlu!t9rO
z0sa%MhZXb0UR-H;Io&os;q8^nM-QEfn%R}h_H(8
zu!XA0$1k{rOfIoM*oQ5!W!xkdzSVY(S!YOL2f_}79SA!Rb|CCP*nzMEVF&(~4s=WJ
zogDwrF0a;oMosrPLv&1WDoZszO?l4_U#+(Rq&NCadc{xD>wYgwV6SlvOl7HYg)gq1
z@db?@!=~>+~KR@n+<7Eq}2KIo%oeM<7{BmFH%fo_eX*-V-_gsQvWAEGQA(bdh#K
z-zUk0UhzvMU*j!?C|w)DFM3%*l2YAu|71*JmXf6-xYIItl%@9^9VI81JwU}}G6NpquVFJus>
zfU`9bapleEDVoqJfyK=E>|Q*8sgHwop}zf590oD{+jTuRwZFl}-)|0d#Pm0qFA@VA
zqCU+<(_P3_z$PC180BZB=P9O*LT~QB6&P?nLQKr}kv*FSRSm@?n^tb2*sFT+=Rjsy
zScTl6CHyJ3Pgv)AhOKOV01DSiDywazZK!Xk`RpENPk%0XcBpk%&due{w
Date: Thu, 23 Aug 2018 08:57:15 +0100
Subject: [PATCH 128/456] Daemon - allow manual start rather than always auto
to close #479
---
utility/daemon/daemon.html | 13 +++++++++++--
utility/daemon/daemon.js | 2 ++
utility/daemon/package.json | 2 +-
3 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/utility/daemon/daemon.html b/utility/daemon/daemon.html
index 58bf99f6..bdd5f28d 100644
--- a/utility/daemon/daemon.html
+++ b/utility/daemon/daemon.html
@@ -11,12 +11,17 @@
-
+
+
+
+
+
+
-
+
@@ -62,6 +67,7 @@
name: {value:""},
command: {value:"",required:true},
args: {value:""},
+ autorun: {value:true},
cr: {value:false},
redo: {value:true},
op: {value:"string"},
@@ -77,6 +83,9 @@
},
labelStyle: function() {
return this.name?"node_label_italic":"";
+ },
+ oneditprepare: function() {
+ if (this.autorun === undefined) { $("#node-input-autorun").prop('checked', true); }
}
});
diff --git a/utility/daemon/daemon.js b/utility/daemon/daemon.js
index 07e49709..97568c7d 100644
--- a/utility/daemon/daemon.js
+++ b/utility/daemon/daemon.js
@@ -12,6 +12,8 @@ module.exports = function(RED) {
this.redo = n.redo;
this.running = false;
this.closer = n.closer || "SIGKILL";
+ this.autorun = true;
+ if (n.autorun === false) { this.autorun = false; }
var node = this;
function inputlistener(msg) {
diff --git a/utility/daemon/package.json b/utility/daemon/package.json
index faeb72bd..a45c56c0 100644
--- a/utility/daemon/package.json
+++ b/utility/daemon/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-daemon",
- "version" : "0.0.21",
+ "version" : "0.0.22",
"description" : "A Node-RED node that runs and monitors a long running system command.",
"dependencies" : {
},
From a94157efe60f83d938d75e6e8a19bb909d03c11c Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Fri, 24 Aug 2018 15:23:37 +0100
Subject: [PATCH 129/456] sqlite - fix fixed statement check
---
storage/sqlite/package.json | 2 +-
storage/sqlite/sqlite.js | 3 +--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/storage/sqlite/package.json b/storage/sqlite/package.json
index cc31580a..9dd66ecb 100644
--- a/storage/sqlite/package.json
+++ b/storage/sqlite/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-sqlite",
- "version": "0.3.4",
+ "version": "0.3.5",
"description": "A sqlite node for Node-RED",
"dependencies": {
"sqlite3": "^4.0.2"
diff --git a/storage/sqlite/sqlite.js b/storage/sqlite/sqlite.js
index 540e21e4..27a92cad 100644
--- a/storage/sqlite/sqlite.js
+++ b/storage/sqlite/sqlite.js
@@ -86,8 +86,7 @@ module.exports = function(RED) {
}
if (node.sqlquery == "fixed"){
if (typeof node.sql === 'string') {
- if (msg.payload && msg.payload.length > 0) {
- bind = Array.isArray(msg.payload) ? msg.payload : [];
+ if (node.sql.length > 0) {
node.mydbConfig.db.all(node.sql, bind, function(err, row) {
if (err) { node.error(err,msg); }
else {
From 52df7cb30f96ce6392ff9e2b11d78c93d19aff5c Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Thu, 30 Aug 2018 13:05:39 +0100
Subject: [PATCH 130/456] Fix email msg cloning
to close #442
to close #461
---
social/email/61-email.js | 8 ++++----
social/email/package.json | 4 ++--
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/social/email/61-email.js b/social/email/61-email.js
index e3e6a0fa..7294af9e 100644
--- a/social/email/61-email.js
+++ b/social/email/61-email.js
@@ -190,7 +190,7 @@ module.exports = function(RED) {
// will be used to populate the email.
// DCJ NOTE: - heirachical multipart mime parsers seem to not exist - this one is barely functional.
function processNewMessage(msg, mailMessage) {
- msg = JSON.parse(JSON.stringify(msg)); // Clone the message
+ msg = RED.util.cloneMessage(msg); // Clone the message
// Populate the msg fields from the content of the email message
// that we have just parsed.
msg.payload = mailMessage.text;
@@ -198,9 +198,9 @@ module.exports = function(RED) {
msg.date = mailMessage.date;
msg.header = mailMessage.headers;
if (mailMessage.html) { msg.html = mailMessage.html; }
- if (mailMessage.to && mailMessage.from.to > 0) { msg.to = mailMessage.to; }
- if (mailMessage.cc && mailMessage.from.cc > 0) { msg.cc = mailMessage.cc; }
- if (mailMessage.bcc && mailMessage.from.bcc > 0) { msg.bcc = mailMessage.bcc; }
+ if (mailMessage.to && mailMessage.to.length > 0) { msg.to = mailMessage.to; }
+ if (mailMessage.cc && mailMessage.cc.length > 0) { msg.cc = mailMessage.cc; }
+ if (mailMessage.bcc && mailMessage.bcc.length > 0) { msg.bcc = mailMessage.bcc; }
if (mailMessage.from && mailMessage.from.length > 0) { msg.from = mailMessage.from[0].address; }
if (mailMessage.attachments) { msg.attachments = mailMessage.attachments; }
else { msg.attachments = []; }
diff --git a/social/email/package.json b/social/email/package.json
index 985817e0..07a9289a 100644
--- a/social/email/package.json
+++ b/social/email/package.json
@@ -1,11 +1,11 @@
{
"name": "node-red-node-email",
- "version": "1.0.0",
+ "version": "1.0.1",
"description": "Node-RED nodes to send and receive simple emails",
"dependencies": {
"imap": "^0.8.19",
"mailparser": "^0.6.2",
- "nodemailer": "^4.6.4",
+ "nodemailer": "^4.6.8",
"poplib": "^0.1.7"
},
"repository": {
From 337588e7ab3271ea2af6148e5299dce3f53e9944 Mon Sep 17 00:00:00 2001
From: Tom Brusehaver <41647049+tbrusehaver@users.noreply.github.com>
Date: Mon, 3 Sep 2018 13:56:36 -0500
Subject: [PATCH 131/456] Fix for Email In Node Crashed Node-RED (#471)
When attachments aren't correct.
---
social/email/61-email.js | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/social/email/61-email.js b/social/email/61-email.js
index 7294af9e..a50ae6d8 100644
--- a/social/email/61-email.js
+++ b/social/email/61-email.js
@@ -226,6 +226,7 @@ module.exports = function(RED) {
function nextMessage() {
if (currentMessage > maxMessage) {
pop3Client.quit();
+ setInputRepeatTimeout();
return;
}
pop3Client.retr(currentMessage);
@@ -248,6 +249,7 @@ module.exports = function(RED) {
});
pop3Client.on("error", function(err) {
+ setInputRepeatTimeout();
node.log("error: " + JSON.stringify(err));
});
@@ -263,6 +265,7 @@ module.exports = function(RED) {
} else {
node.log(util.format("login error: %s %j", status, rawData));
pop3Client.quit();
+ setInputRepeatTimeout();
}
});
@@ -284,6 +287,7 @@ module.exports = function(RED) {
else {
node.log(util.format("retr error: %s %j", status, rawData));
pop3Client.quit();
+ setInputRepeatTimeout();
}
});
@@ -323,6 +327,7 @@ module.exports = function(RED) {
node.status({fill:"red", shape:"ring", text:"email.status.foldererror"});
node.error(RED._("email.errors.fetchfail", {folder:node.box}),err);
imap.end();
+ setInputRepeatTimeout();
return;
}
//console.log("> search - err=%j, results=%j", err, results);
@@ -330,6 +335,7 @@ module.exports = function(RED) {
//console.log(" [X] - Nothing to fetch");
node.status({});
imap.end();
+ setInputRepeatTimeout();
return;
}
@@ -377,10 +383,12 @@ module.exports = function(RED) {
} else {
cleanup();
}
+ setInputRepeatTimeout();
});
fetch.once('error', function(err) {
console.log('Fetch error: ' + err);
+ setInputRepeatTimeout();
});
}); // End of imap->search
}); // End of imap->openInbox
@@ -424,16 +432,19 @@ module.exports = function(RED) {
this.on("close", function() {
if (this.interval_id != null) {
- clearInterval(this.interval_id);
+ clearTimeout(this.interval_id);
}
if (imap) { imap.destroy(); }
});
- // Set the repetition timer as needed
- if (!isNaN(this.repeat) && this.repeat > 0) {
- this.interval_id = setInterval( function() {
- node.emit("input",{});
- }, this.repeat );
+ function setInputRepeatTimeout()
+ {
+ // Set the repetition timer as needed
+ if (!isNaN(node.repeat) && node.repeat > 0) {
+ node.interval_id = setTimeout( function() {
+ node.emit("input",{});
+ }, node.repeat );
+ }
}
node.emit("input",{});
From 649f9f2fbf3f4f6ebee2854cf4b68b7e41b7f1b3 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Mon, 3 Sep 2018 20:06:36 +0100
Subject: [PATCH 132/456] Bump email node for pr attachment errors fix
---
social/email/README.md | 6 ++++--
social/email/package.json | 2 +-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/social/email/README.md b/social/email/README.md
index aaf84e6e..d1c4b474 100644
--- a/social/email/README.md
+++ b/social/email/README.md
@@ -9,7 +9,7 @@ Pre-requisite
You will need valid email credentials for your email server.
-**Note :** Version 1.x of this node requires Node.js v6 or newer.
+**Note :** Version 1.x of this node requires **Node.js v6** or newer.
Install
@@ -18,10 +18,12 @@ Install
Version 0.x of this node is usually installed by default by Node-RED.
To install version 1.x you need to uninstall the existing version.
- sudo npm uninstall -g node-red-node-email
+ cd /usr/lib/node_modules/node-red
+ sudo npm uninstall --unsafe-perm node-red-node-email
Then run the following command in your Node-RED user directory - typically `~/.node-red`
+ cd ~/.node-red
npm i node-red-node-email
**Note :** this installs the new version locally rather than globally. This can then be managed by the palette manager.
diff --git a/social/email/package.json b/social/email/package.json
index 07a9289a..da414702 100644
--- a/social/email/package.json
+++ b/social/email/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-email",
- "version": "1.0.1",
+ "version": "1.0.2",
"description": "Node-RED nodes to send and receive simple emails",
"dependencies": {
"imap": "^0.8.19",
From a2b90976137cd5e4edb0278205af0a2e7983eff6 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Tue, 4 Sep 2018 18:51:20 +0100
Subject: [PATCH 133/456] Email node - report when on old node.js
---
social/email/61-email.js | 4 ++++
social/email/README.md | 4 ++--
social/email/package.json | 4 ++--
3 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/social/email/61-email.js b/social/email/61-email.js
index a50ae6d8..c33d3b6e 100644
--- a/social/email/61-email.js
+++ b/social/email/61-email.js
@@ -17,6 +17,10 @@ module.exports = function(RED) {
var MailParser = require("mailparser").MailParser;
var util = require("util");
+ if (parseInt(process.version.split("v")[1].split(".")[0]) < 8) {
+ throw "Error : Requires nodejs version >= 8.";
+ }
+
try {
var globalkeys = RED.settings.email || require(process.env.NODE_RED_HOME+"/../emailkeys.js");
}
diff --git a/social/email/README.md b/social/email/README.md
index d1c4b474..0cffc6e2 100644
--- a/social/email/README.md
+++ b/social/email/README.md
@@ -1,7 +1,7 @@
node-red-node-email
===================
-Node-RED nodes to send and receive simple emails.
+Node-RED nodes to send and receive simple emails.
Pre-requisite
@@ -9,7 +9,7 @@ Pre-requisite
You will need valid email credentials for your email server.
-**Note :** Version 1.x of this node requires **Node.js v6** or newer.
+**Note :** Version 1.x of this node requires **Node.js v8** or newer.
Install
diff --git a/social/email/package.json b/social/email/package.json
index da414702..02e447aa 100644
--- a/social/email/package.json
+++ b/social/email/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-email",
- "version": "1.0.2",
+ "version": "1.0.3",
"description": "Node-RED nodes to send and receive simple emails",
"dependencies": {
"imap": "^0.8.19",
@@ -30,6 +30,6 @@
"url": "http://nodered.org"
},
"engines": {
- "node": ">=6.0.0"
+ "node": ">=8.0.0"
}
}
From 949bbe95cde586049f0b4616912bf1e2d4cd4bb1 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Thu, 6 Sep 2018 21:33:14 +0100
Subject: [PATCH 134/456] couple of file permissions and rm node6
---
.travis.yml | 1 -
hardware/neopixel/neopixel.html | 0
hardware/neopixel/package.json | 0
3 files changed, 1 deletion(-)
mode change 100755 => 100644 hardware/neopixel/neopixel.html
mode change 100755 => 100644 hardware/neopixel/package.json
diff --git a/.travis.yml b/.travis.yml
index 7c414c5f..9bfec6ee 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,7 +4,6 @@ matrix:
include:
- node_js: 8
- node_js: 10
- - node_js: 6
- python: 2.7
language: python
before_script: pip install flake8
diff --git a/hardware/neopixel/neopixel.html b/hardware/neopixel/neopixel.html
old mode 100755
new mode 100644
diff --git a/hardware/neopixel/package.json b/hardware/neopixel/package.json
old mode 100755
new mode 100644
From 8acc5064d0503441c0b45330af1da1d319a50ff6 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Mon, 10 Sep 2018 11:37:20 -0400
Subject: [PATCH 135/456] update notify package to use a more cross platform
library
---
social/notify/57-notify.html | 15 ++++++++-------
social/notify/57-notify.js | 25 +++++++++++++++++--------
social/notify/node-red.png | Bin 0 -> 1019 bytes
social/notify/package.json | 8 ++++----
4 files changed, 29 insertions(+), 19 deletions(-)
create mode 100644 social/notify/node-red.png
diff --git a/social/notify/57-notify.html b/social/notify/57-notify.html
index d0fc85d4..fe3244a2 100644
--- a/social/notify/57-notify.html
+++ b/social/notify/57-notify.html
@@ -1,5 +1,5 @@
-
-
diff --git a/social/pushover/README.md b/social/pushover/README.md
index 86c592f9..158ccae7 100644
--- a/social/pushover/README.md
+++ b/social/pushover/README.md
@@ -16,12 +16,14 @@ Usage
Uses Pushover to push the `msg.payload` to a device that has the Pushover app installed.
-Optionally uses `msg.topic` to set the title, `msg.device` to set the device
-and `msg.priority` to set the priority, if not already set in the properties.
-Optionally uses `msg.topic` to set the title, `msg.device` to set the device,
-`msg.priority` to set the priority, `msg.url` to add a web address and `msg.url_title`
-to add a url title - if not already set in the properties.
+Optionally uses `msg.topic` to set the configuration, if not already set in the properties:
+ - `msg.device`: to set the device
+ - `msg.priority`: to set the priority
+ - `msg.topic`: to set the title
+ - `msg.url`: to add a web address
+ - `msg.url_title`: to add a url title
+ - `msg.sound`: to set the alert sound, see the [available options](https://pushover.net/api#sounds)
The User-key and API-token are stored in a separate credentials file.
From eae67c7a6c37f8887e57b2c7c0ffd598fb0788ec Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Mon, 17 Sep 2018 20:00:45 +0100
Subject: [PATCH 142/456] bump pushover packe for docs pr
---
social/pushover/package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/social/pushover/package.json b/social/pushover/package.json
index 2a52ec45..ccc56b22 100644
--- a/social/pushover/package.json
+++ b/social/pushover/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-pushover",
- "version" : "0.0.12",
+ "version" : "0.0.13",
"description" : "A Node-RED node to send alerts via Pushover",
"dependencies" : {
"pushover-notifications" : "~0.2.4"
From 23ba609653ea4c080aa41f7acda154dcf78db65b Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Fri, 21 Sep 2018 13:53:08 +0100
Subject: [PATCH 143/456] Add SPIdev choice to mcpxxxx node
---
hardware/mcp3008/README.md | 2 ++
hardware/mcp3008/package.json | 4 ++--
hardware/mcp3008/pimcp3008.html | 10 +++++++++-
hardware/mcp3008/pimcp3008.js | 5 +++--
4 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/hardware/mcp3008/README.md b/hardware/mcp3008/README.md
index 0914d49c..5ab83009 100644
--- a/hardware/mcp3008/README.md
+++ b/hardware/mcp3008/README.md
@@ -37,6 +37,8 @@ select the channel dynamically. If so then the payload must be a value from 0 to
You can also select device id 0 or 1 (CE0 or CE1) depending on how you have wired up your device. Defaults to CE0.
+And you can also select the SPI bus number 0 or 1 depending on how you have wired up your device. Defaults to 0 for spidev0.
+
Outputs a numeric `msg.payload` with a range of 0 to 1023, where 0 = 0V and 1023 = 3.3V (assuming you use the default 3.3V voltage reference).
**Hint**: use a `range` node to adjust the values to the range you want.
diff --git a/hardware/mcp3008/package.json b/hardware/mcp3008/package.json
index bf89c672..f9a6a028 100644
--- a/hardware/mcp3008/package.json
+++ b/hardware/mcp3008/package.json
@@ -1,9 +1,9 @@
{
"name" : "node-red-node-pi-mcp3008",
- "version" : "0.1.1",
+ "version" : "0.2.0",
"description" : "A Node-RED node to read from the MCP3008 Analogue to Digital Converter",
"dependencies" : {
- "mcp-spi-adc": "^1.0.0"
+ "mcp-spi-adc": "^2.0.3"
},
"repository" : {
"type":"git",
diff --git a/hardware/mcp3008/pimcp3008.html b/hardware/mcp3008/pimcp3008.html
index 59c2dbcc..3fafb671 100644
--- a/hardware/mcp3008/pimcp3008.html
+++ b/hardware/mcp3008/pimcp3008.html
@@ -33,6 +33,13 @@
+
+
+
+
+
+
+
@@ -61,7 +68,8 @@
name: {value:""},
dev: {value:"3008"},
pin: {value:0, required:true},
- dnum: {value:0}
+ dnum: {value:0},
+ bus: {value:0}
},
inputs: 1,
outputs: 1,
diff --git a/hardware/mcp3008/pimcp3008.js b/hardware/mcp3008/pimcp3008.js
index ee5e835f..492f8d6b 100644
--- a/hardware/mcp3008/pimcp3008.js
+++ b/hardware/mcp3008/pimcp3008.js
@@ -19,14 +19,15 @@ module.exports = function(RED) {
this.pin = n.pin || 0;
this.interval = n.interval || 1000;
this.dnum = parseInt(n.dnum || 0);
+ this.bus = parseInt(n.bus || 0);
this.dev = n.dev || "3008";
var node = this;
var cb = function (err) { if (err) { node.error("Error: "+err); } };
- var opt = { speedHz:20000, deviceNumber:node.dnum };
+ var opt = { speedHz:20000, deviceNumber:node.dnum, busNumber:node.bus };
var chans = parseInt(this.dev.substr(3));
try {
- fs.statSync("/dev/spidev0."+node.dnum);
+ fs.statSync("/dev/spidev"+node.bus+"."+node.dnum);
if (mcp3xxx.length === 0) {
for (var i=0; i
Date: Sun, 23 Sep 2018 20:32:11 +0100
Subject: [PATCH 144/456] check for correct version of neopixel library
---
hardware/neopixel/neopixel.js | 2 +-
hardware/neopixel/package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
mode change 100755 => 100644 hardware/neopixel/neopixel.js
diff --git a/hardware/neopixel/neopixel.js b/hardware/neopixel/neopixel.js
old mode 100755
new mode 100644
index c8781367..815326e3
--- a/hardware/neopixel/neopixel.js
+++ b/hardware/neopixel/neopixel.js
@@ -14,7 +14,7 @@ module.exports = function(RED) {
RED.log.warn("rpi-neopixels : "+RED._("node-red:rpi-gpio.errors.ignorenode"));
allOK = false;
}
- else if (execSync('python -c "import neopixel"').toString() !== "") {
+ else if (execSync('python -c "import rpi_ws281x"').toString() !== "") {
RED.log.warn("rpi-neopixels : Can't find neopixel python library");
allOK = false;
}
diff --git a/hardware/neopixel/package.json b/hardware/neopixel/package.json
index eca2cf6b..a9bf250a 100644
--- a/hardware/neopixel/package.json
+++ b/hardware/neopixel/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-pi-neopixel",
- "version" : "0.0.21",
+ "version" : "0.0.22",
"description" : "A Node-RED node to output to a neopixel (ws2812) string of LEDS from a Raspberry Pi.",
"dependencies" : {
},
From d32f11910bc28a77557755c9f9544f3dedd7dd39 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Mon, 24 Sep 2018 19:40:33 +0100
Subject: [PATCH 145/456] clarify random node info language
---
function/random/package.json | 2 +-
function/random/random.html | 6 ++++--
function/random/random.js | 4 ++--
3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/function/random/package.json b/function/random/package.json
index 4898c021..ee980c8d 100644
--- a/function/random/package.json
+++ b/function/random/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-random",
- "version" : "0.1.0",
+ "version" : "0.1.1",
"description" : "A Node-RED node that when triggered generates a random number between two values.",
"dependencies" : {
},
diff --git a/function/random/random.html b/function/random/random.html
index 0f2c3824..3e103aef 100644
--- a/function/random/random.html
+++ b/function/random/random.html
@@ -28,8 +28,10 @@
70%
@@ -33,7 +33,7 @@
defaults: {
name: {value:""},
server: {type:"xmpp-server",required:true},
- to: {value:"",required:true},
+ to: {value:""},
join: {value:false}
},
inputs:0,
@@ -107,20 +107,20 @@
diff --git a/social/xmpp/92-xmpp.js b/social/xmpp/92-xmpp.js
index fbadad31..000b04ee 100644
--- a/social/xmpp/92-xmpp.js
+++ b/social/xmpp/92-xmpp.js
@@ -2,17 +2,53 @@
module.exports = function(RED) {
"use strict";
var XMPP = require('simple-xmpp');
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
function XMPPServerNode(n) {
RED.nodes.createNode(this,n);
- this.server = n.server;
- this.port = n.port;
+ // this.server = n.server;
+ // this.port = n.port;
this.nickname = n.nickname;
+ this.username = n.user;
var credentials = this.credentials;
if (credentials) {
- this.username = credentials.user;
this.password = credentials.password;
}
+ this.client = new XMPP.SimpleXMPP();
+ this.connected = false;
+ var that = this;
+
+ this.client.con = function() {
+ if (that.connected === false ) {
+ that.connected = true;
+ that.client.connect({
+ jid : that.username,
+ password : that.password,
+ // host : node.host,
+ //port : node.port,
+ //skipPresence : true,
+ reconnect : true,
+ preferred : "PLAIN"
+ });
+ }
+ }
+
+ that.client.on('online', function(data) {
+ that.connected = true;
+ that.client.setPresence('online', data.jid.user+' is online');
+ that.log('connected as '+data.jid.user+' to '+data.jid._domain+":5222");
+ });
+ that.client.on('close', function() {
+ that.connected = false;
+ that.log('connection closed');
+ });
+ this.on("close", function(done) {
+ that.client.setPresence('offline');
+ that.client.disconnect();
+ if (that.client.conn) { that.client.conn.end(); }
+ that.client = null;
+ done();
+ });
}
RED.nodes.registerType("xmpp-server",XMPPServerNode,{
@@ -27,24 +63,21 @@ module.exports = function(RED) {
this.server = n.server;
this.serverConfig = RED.nodes.getNode(this.server);
- this.host = this.serverConfig.server;
- this.port = this.serverConfig.port;
- this.nick = this.serverConfig.nickname || "Node-RED";
- this.userid = this.serverConfig.username;
- this.password = this.serverConfig.password;
+ // this.host = this.serverConfig.server;
+ // this.port = this.serverConfig.port;
+ var pa = this.serverConfig.username.split("@");
+ this.nick = this.serverConfig.nickname || pa[0];
this.join = n.join || false;
this.sendAll = n.sendObject;
- this.to = n.to || "";
+ this.from = n.to || "";
var node = this;
- var xmpp = new XMPP.SimpleXMPP();
+ var xmpp = this.serverConfig.client;
xmpp.on('online', function(data) {
- node.log('connected to '+node.host+":"+node.port);
node.status({fill:"green",shape:"dot",text:"connected"});
- //xmpp.setPresence('online', node.nick+' online');
- if (node.join) {
+ if ((node.join) && (node.from !== "")) {
xmpp.join(node.to+'/'+node.nick);
}
});
@@ -76,17 +109,22 @@ module.exports = function(RED) {
if (err.hasOwnProperty("stanza")) {
if (err.stanza.name === 'stream:error') { node.error("stream:error - bad login id/pwd ?",err); }
else { node.error(err.stanza.name,err); }
+ node.status({fill:"red",shape:"ring",text:"bad login"});
}
else {
- if (err.errno === "ETIMEDOUT") { node.error("Timeout connecting to server",err); }
- else { node.error(err.errno,err); }
+ if (err.errno === "ETIMEDOUT") {
+ node.error("Timeout connecting to server",err);
+ node.status({fill:"red",shape:"ring",text:"timeout"});
+ }
+ else if (err === "XMPP authentication failure") {
+ node.error(err,err);
+ node.status({fill:"red",shape:"ring",text:"XMPP authentication failure"});
+ }
+ else {
+ node.error(err.errno,err);
+ node.status({fill:"red",shape:"ring",text:"error"});
+ }
}
- node.status({fill:"red",shape:"ring",text:"error"});
- });
-
- xmpp.on('close', function() {
- node.log('connection closed');
- //node.status({fill:"grey",shape:"ring",text:"not connected"});
});
xmpp.on('subscribe', function(from) {
@@ -96,55 +134,42 @@ module.exports = function(RED) {
// Now actually make the connection
try {
node.status({fill:"grey",shape:"dot",text:"connecting"});
- xmpp.connect({
- jid : node.userid,
- password : node.password,
- host : node.host,
- port : node.port,
- skipPresence : true,
- reconnect : false,
- preferred : "PLAIN"
- });
+ xmpp.con();
}
catch(e) {
node.error("Bad xmpp configuration");
node.status({fill:"red",shape:"ring",text:"not connected"});
}
- node.on("close", function(done) {
- xmpp.setPresence('offline');
- xmpp.disconnect();
- if (xmpp.conn) { xmpp.conn.end(); }
- xmpp = null;
+ node.on("close", function() {
node.status({});
- done();
});
}
RED.nodes.registerType("xmpp in",XmppInNode);
+
function XmppOutNode(n) {
RED.nodes.createNode(this,n);
this.server = n.server;
this.serverConfig = RED.nodes.getNode(this.server);
- this.host = this.serverConfig.server;
- this.port = this.serverConfig.port;
- this.nick = this.serverConfig.nickname || "Node-RED";
+ // this.host = this.serverConfig.server;
+ // this.port = this.serverConfig.port;
+ //this.nick = this.serverConfig.nickname || "Node-RED";
this.userid = this.serverConfig.username;
- this.password = this.serverConfig.password;
+ var pa = this.userid.split("@");
+ this.nick = this.serverConfig.nickname || pa[0];
this.join = n.join || false;
this.sendAll = n.sendObject;
this.to = n.to || "";
var node = this;
- var xmpp = new XMPP.SimpleXMPP();
+ var xmpp = this.serverConfig.client;
xmpp.on('online', function(data) {
node.status({fill:"green",shape:"dot",text:"connected"});
- node.log('connected to '+node.host+":"+node.port);
- xmpp.setPresence('online', node.nick+' online');
- if (node.join) {
+ if ((node.join) && (node.from !== "")) {
xmpp.join(node.to+'/'+node.nick);
}
});
@@ -154,35 +179,28 @@ module.exports = function(RED) {
if (err.hasOwnProperty("stanza")) {
if (err.stanza.name === 'stream:error') { node.error("stream:error - bad login id/pwd ?",err); }
else { node.error(err.stanza.name,err); }
+ node.status({fill:"red",shape:"ring",text:"bad login"});
}
else {
- if (err.errno === "ETIMEDOUT") { node.error("Timeout connecting to server",err); }
- else { node.error(err.errno,err); }
+ if (err.errno === "ETIMEDOUT") {
+ node.error("Timeout connecting to server",err);
+ node.status({fill:"red",shape:"ring",text:"timeout"});
+ }
+ else if (err === "XMPP authentication failure") {
+ node.error(err,err);
+ node.status({fill:"red",shape:"ring",text:"XMPP authentication failure"});
+ }
+ else {
+ node.error(err.errno,err);
+ node.status({fill:"red",shape:"ring",text:"error"});
+ }
}
- node.status({fill:"red",shape:"ring",text:"error"});
- });
-
- xmpp.on('close', function() {
- node.log('connection closed');
- //node.status({fill:"grey",shape:"ring",text:"not connected"});
- });
-
- xmpp.on('subscribe', function(from) {
- xmpp.acceptSubscription(from);
});
// Now actually make the connection
try {
node.status({fill:"grey",shape:"dot",text:"connecting"});
- xmpp.connect({
- jid : node.userid,
- password : node.password,
- host : node.host,
- port : node.port,
- skipPresence : true,
- reconnect : false,
- preferred : "PLAIN"
- });
+ xmpp.con();
}
catch(e) {
node.error("Bad xmpp configuration");
@@ -191,7 +209,7 @@ module.exports = function(RED) {
node.on("input", function(msg) {
if (msg.presence) {
- if (['away', 'dnd', 'xa','chat'].indexOf(msg.presence) > -1 ) {
+ if (['away', 'dnd', 'xa', 'chat'].indexOf(msg.presence) > -1 ) {
xmpp.setPresence(msg.presence, msg.payload);
}
else { node.warn("Can't set presence - invalid value"); }
@@ -213,13 +231,8 @@ module.exports = function(RED) {
}
});
- node.on("close", function(done) {
- xmpp.setPresence('offline');
- xmpp.disconnect();
- if (xmpp.conn) { xmpp.conn.end(); }
- xmpp = null;
+ node.on("close", function() {
node.status({});
- done();
});
}
RED.nodes.registerType("xmpp out",XmppOutNode);
diff --git a/social/xmpp/package.json b/social/xmpp/package.json
index d3dca717..e2176d39 100644
--- a/social/xmpp/package.json
+++ b/social/xmpp/package.json
@@ -1,9 +1,9 @@
{
"name" : "node-red-node-xmpp",
- "version" : "0.1.7",
+ "version" : "0.2.0",
"description" : "A Node-RED node to talk to an XMPP server",
"dependencies" : {
- "simple-xmpp" : "1.3.*"
+ "simple-xmpp" : "^1.3.0"
},
"repository" : {
"type":"git",
From 7bd255a34102455480b80bfd5dd4bdcb74d0794e Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Fri, 28 Sep 2018 21:42:36 +0100
Subject: [PATCH 150/456] better filtering for XMPP messages, stop history when
joining rooms
---
social/xmpp/92-xmpp.html | 4 ++--
social/xmpp/92-xmpp.js | 28 ++++++++++++++++++++++++----
social/xmpp/package.json | 2 +-
3 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/social/xmpp/92-xmpp.html b/social/xmpp/92-xmpp.html
index 8cd0b64b..5b5c3933 100644
--- a/social/xmpp/92-xmpp.html
+++ b/social/xmpp/92-xmpp.html
@@ -1,7 +1,7 @@
+
+
+
diff --git a/social/xmpp/92-xmpp.js b/social/xmpp/92-xmpp.js
index dc873c99..1dfb35a8 100644
--- a/social/xmpp/92-xmpp.js
+++ b/social/xmpp/92-xmpp.js
@@ -53,7 +53,6 @@ module.exports = function(RED) {
RED.nodes.registerType("xmpp-server",XMPPServerNode,{
credentials: {
- user: {type:"text"},
password: {type: "password"}
}
});
@@ -61,13 +60,8 @@ module.exports = function(RED) {
function XmppInNode(n) {
RED.nodes.createNode(this,n);
this.server = n.server;
-
this.serverConfig = RED.nodes.getNode(this.server);
- // this.host = this.serverConfig.server;
- // this.port = this.serverConfig.port;
- var pa = this.serverConfig.username.split("@");
- this.nick = this.serverConfig.nickname || pa[0];
-
+ this.nick = this.serverConfig.nickname || this.serverConfig.username.split("@")[0];
this.join = n.join || false;
this.sendAll = n.sendObject;
this.from = n.to || "";
@@ -88,17 +82,35 @@ module.exports = function(RED) {
}
});
- xmpp.on('chat', function(from, message) {
- var msg = { topic:from, payload:message };
- if (!node.join && ((node.from === "") || (node.from === from))) {
- node.send([msg,null]);
+ // xmpp.on('chat', function(from, message) {
+ // var msg = { topic:from, payload:message };
+ // if (!node.join && ((node.from === "") || (node.from === from))) {
+ // node.send([msg,null]);
+ // }
+ // });
+
+ xmpp.on('stanza', function(stanza) {
+ if (stanza.is('message')) {
+ if (stanza.attrs.type == 'chat') {
+ //console.log(stanza);
+ var body = stanza.getChild('body');
+ if (body) {
+ var msg = { payload:body.getText() };
+ var ids = stanza.attrs.from.split('/');
+ if (ids[1].length !== 36) {
+ msg.topic = stanza.attrs.from
+ }
+ else { msg.topic = ids[0]; }
+ if (!node.join && ((node.from === "") || (node.from === from))) {
+ node.send([msg,null]);
+ }
+ }
+ }
}
});
xmpp.on('groupchat', function(conference, from, message, stamp) {
- if (!stamp) {stamp = Date.now(); }
- //else { console.log("STAMP",stamp) }
- var msg = { topic:from, payload:message, room:conference, ts:stamp };
+ var msg = { topic:from, payload:message, room:conference };
if (from != node.nick) {
if ((node.join) && (node.from === conference)) {
node.send([msg,null]);
@@ -108,7 +120,7 @@ module.exports = function(RED) {
//xmpp.on('chatstate', function(from, state) {
//console.log('%s is currently %s', from, state);
- //var msg = { topic:from, payload:state };
+ //var msg = { topic:from, payload: {presence:state} };
//node.send([null,msg]);
//});
@@ -118,6 +130,11 @@ module.exports = function(RED) {
node.send([null,msg]);
});
+ // xmpp.on('groupbuddy', function(conference, from, state, statusText) {
+ // //console.log('%s: %s is in %s state - %s',conference, from, state, statusText);
+ // var msg = { topic:from, payload: { presence:state, status:statusText}, room:conference };
+ // });
+
xmpp.on('error', function(err) {
if (RED.settings.verbose) { node.log(err); }
if (err.hasOwnProperty("stanza")) {
@@ -165,15 +182,8 @@ module.exports = function(RED) {
function XmppOutNode(n) {
RED.nodes.createNode(this,n);
this.server = n.server;
-
this.serverConfig = RED.nodes.getNode(this.server);
- // this.host = this.serverConfig.server;
- // this.port = this.serverConfig.port;
- //this.nick = this.serverConfig.nickname || "Node-RED";
- this.userid = this.serverConfig.username;
- var pa = this.userid.split("@");
- this.nick = this.serverConfig.nickname || pa[0];
-
+ this.nick = this.serverConfig.nickname || this.serverConfig.username.split("@")[0];
this.join = n.join || false;
this.sendAll = n.sendObject;
this.to = n.to || "";
@@ -232,20 +242,21 @@ module.exports = function(RED) {
if (['away', 'dnd', 'xa', 'chat'].indexOf(msg.presence) > -1 ) {
xmpp.setPresence(msg.presence, msg.payload);
}
- else { node.warn("Can't set presence - invalid value"); }
+ else { node.warn("Can't set presence - invalid value: "+msg.presence); }
}
else {
- var to = msg.topic;
- if (node.to !== "") { to = node.to; }
- if (node.sendAll) {
- xmpp.send(to, JSON.stringify(msg), node.join);
- }
- else if (msg.payload) {
- if (typeof(msg.payload) === "object") {
- xmpp.send(to, JSON.stringify(msg.payload), node.join);
+ var to = node.to || msg.topic || "";
+ if (to !== "") {
+ if (node.sendAll) {
+ xmpp.send(to, JSON.stringify(msg), node.join);
}
- else {
- xmpp.send(to, msg.payload.toString(), node.join);
+ else if (msg.payload) {
+ if (typeof(msg.payload) === "object") {
+ xmpp.send(to, JSON.stringify(msg.payload), node.join);
+ }
+ else {
+ xmpp.send(to, msg.payload.toString(), node.join);
+ }
}
}
}
diff --git a/social/xmpp/package.json b/social/xmpp/package.json
index 8347ff2f..37d24572 100644
--- a/social/xmpp/package.json
+++ b/social/xmpp/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-xmpp",
- "version" : "0.2.1",
+ "version" : "0.2.2",
"description" : "A Node-RED node to talk to an XMPP server",
"dependencies" : {
"simple-xmpp" : "^1.3.0"
From f74f3402e3b9cbbe494b9c0a2dac48e6fc18ca74 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Mon, 1 Oct 2018 17:31:18 +0100
Subject: [PATCH 152/456] let twitter node DM using D or d
to close #493
---
social/twitter/27-twitter.js | 2 +-
social/twitter/package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/social/twitter/27-twitter.js b/social/twitter/27-twitter.js
index 58cb4a1f..6db5d1c6 100644
--- a/social/twitter/27-twitter.js
+++ b/social/twitter/27-twitter.js
@@ -566,7 +566,7 @@ module.exports = function(RED) {
node.on("input", function(msg) {
if (msg.hasOwnProperty("payload")) {
node.status({fill:"blue",shape:"dot",text:"twitter.status.tweeting"});
- if (msg.payload.slice(0,2) == "D ") {
+ if (msg.payload.slice(0,2).toLowerCase() === "d ") {
var dm_user;
// direct message syntax: "D user message"
var t = msg.payload.match(/D\s+(\S+)\s+(.*)/).slice(1);
diff --git a/social/twitter/package.json b/social/twitter/package.json
index 2c643ac0..13b1e8ed 100644
--- a/social/twitter/package.json
+++ b/social/twitter/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-twitter",
- "version": "1.1.2",
+ "version": "1.1.3",
"description": "A Node-RED node to talk to Twitter",
"dependencies": {
"twitter-ng": "0.6.2",
From f97a59b3e37ea4fec68bac42ca1d9574c8509819 Mon Sep 17 00:00:00 2001
From: Kazuhito Yokoi
Date: Wed, 24 Oct 2018 20:28:38 +0900
Subject: [PATCH 153/456] Update Japanese messages (#499)
* Update Japanese messages
* Fix URL
---
function/rbe/locales/ja/rbe.html | 4 +++-
social/email/locales/ja/61-email.html | 5 ++++-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/function/rbe/locales/ja/rbe.html b/function/rbe/locales/ja/rbe.html
index a5225051..509e4df7 100644
--- a/function/rbe/locales/ja/rbe.html
+++ b/function/rbe/locales/ja/rbe.html
@@ -1,3 +1,5 @@
+
+
diff --git a/social/email/locales/ja/61-email.html b/social/email/locales/ja/61-email.html
index 86da0e4f..5a6300b7 100644
--- a/social/email/locales/ja/61-email.html
+++ b/social/email/locales/ja/61-email.html
@@ -1,3 +1,5 @@
+
+
diff --git a/social/twitter/locales/en-US/27-twitter.json b/social/twitter/locales/en-US/27-twitter.json
index 58e7c029..4282327d 100644
--- a/social/twitter/locales/en-US/27-twitter.json
+++ b/social/twitter/locales/en-US/27-twitter.json
@@ -1,7 +1,7 @@
{
"twitter": {
"label": {
- "twitter-id":"Twitter ID",
+ "twitter-id": "Twitter ID",
"search": "Search",
"for": "for",
"user": "User",
@@ -10,14 +10,13 @@
"tweetslabel": "tweets",
"eventslabel": "events",
"create": "Create your own application at",
- "copy-consumer": "From the 'Keys and Access Tokens' section, copy the Consumer Key and Secret",
- "consumer_key": "Consumer Key",
- "consumer_secret": "Consumer Secret",
- "copy-accessToken": "Create a new 'Access Token' and copy the Access Token and Secret",
- "access_key": "Access Token",
- "access_secret": "Access Token Secret",
- "enter-id":"Set your Twitter ID"
-
+ "copy-consumer": "From the 'Keys and tokens' section, copy the Consumer API keys",
+ "consumer_key": "API key",
+ "consumer_secret": "API secret key",
+ "copy-accessToken": "Create a new 'Access token & access token secret' and copy them",
+ "access_key": "Access token",
+ "access_secret": "Access token secret",
+ "enter-id": "Set your Twitter ID"
},
"placeholder": {
"for": "comma-separated words, @ids, #tags",
@@ -34,22 +33,22 @@
"status": {
"using-geo": "Using geo location: __location__",
"tweeting": "tweeting",
- "failed":"failed"
+ "failed": "failed"
},
"warn": {
- "nousers":"User option selected but no users specified",
- "waiting":"Waiting for search term"
+ "nousers": "User option selected but no users specified",
+ "waiting": "Waiting for search term"
},
"errors": {
- "ratelimit":"rate limit hit",
- "limitrate":"limiting rate",
- "streamerror":"stream error: __error__ (__rc__)",
- "unexpectedend":"stream ended unexpectedly",
- "invalidtag":"invalid tag property",
- "missingcredentials":"missing twitter credentials",
- "truncated":"truncated tweet greater than 280 characters",
- "sendfail":"send tweet failed: __error__",
- "nopayload":"no payload to tweet"
+ "ratelimit": "rate limit hit",
+ "limitrate": "limiting rate",
+ "streamerror": "stream error: __error__ (__rc__)",
+ "unexpectedend": "stream ended unexpectedly",
+ "invalidtag": "invalid tag property",
+ "missingcredentials": "missing twitter credentials",
+ "truncated": "truncated tweet greater than 280 characters",
+ "sendfail": "send tweet failed: __error__",
+ "nopayload": "no payload to tweet"
}
}
}
From 5b34702ac498e7a29bcf4f7c4e83723b473a81d3 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Wed, 24 Oct 2018 15:08:42 +0100
Subject: [PATCH 155/456] Add Tail node as separate node package - adds windows
support
---
storage/tail/28-tail.html | 63 +++++++++++++++++++++++++
storage/tail/28-tail.js | 60 +++++++++++++++++++++++
storage/tail/LICENSE | 14 ++++++
storage/tail/README.md | 17 +++++++
storage/tail/locales/en-US/28-tail.json | 20 ++++++++
storage/tail/package.json | 27 +++++++++++
6 files changed, 201 insertions(+)
create mode 100644 storage/tail/28-tail.html
create mode 100644 storage/tail/28-tail.js
create mode 100644 storage/tail/LICENSE
create mode 100644 storage/tail/README.md
create mode 100644 storage/tail/locales/en-US/28-tail.json
create mode 100644 storage/tail/package.json
diff --git a/storage/tail/28-tail.html b/storage/tail/28-tail.html
new file mode 100644
index 00000000..9910de31
--- /dev/null
+++ b/storage/tail/28-tail.html
@@ -0,0 +1,63 @@
+
+
+
+
+
+
diff --git a/storage/tail/28-tail.js b/storage/tail/28-tail.js
new file mode 100644
index 00000000..4fde885d
--- /dev/null
+++ b/storage/tail/28-tail.js
@@ -0,0 +1,60 @@
+
+module.exports = function(RED) {
+ "use strict";
+ var fs = require('fs');
+ var Tail = require('tail').Tail;
+
+ function TailNode(n) {
+ RED.nodes.createNode(this,n);
+
+ this.filename = n.filename;
+ this.filetype = n.filetype || "text";
+ this.split = new RegExp(n.split || "[\r]{0,1}\n");
+ var node = this;
+
+ var fileTail = function() {
+ if (fs.existsSync(node.filename)) {
+ if (node.filetype === "text") {
+ node.tail = new Tail(node.filename,{separator:node.split, flushAtEOF:true});
+ }
+ else {
+ node.tail = new Tail(node.filename,{separator:null, flushAtEOF:true, encoding:"binary"});
+ }
+
+ node.tail.on("line", function(data) {
+ if (data.length > 0) {
+ var msg = { topic:node.filename };
+ if (node.filetype === "text") {
+ msg.payload = data.toString();
+ node.send(msg);
+ }
+ else {
+ msg.payload = Buffer.from(data,"binary");
+ //msg.payload = data;
+ node.send(msg);
+ }
+ }
+ });
+
+ node.tail.on("error", function(err) {
+ node.error(err.toString());
+ });
+ }
+ else {
+ node.tout = setTimeout(function() { fileTail(); },10000);
+ node.warn(RED._("tail.errors.filenotfound") + node.filename);
+ }
+ }
+
+ fileTail();
+
+ node.on("close", function() {
+ /* istanbul ignore else */
+ if (node.tail) { node.tail.unwatch(); }
+ delete node.tail;
+ if (node.tout) { clearTimeout(node.tout); }
+ });
+ }
+
+ RED.nodes.registerType("tail",TailNode);
+}
diff --git a/storage/tail/LICENSE b/storage/tail/LICENSE
new file mode 100644
index 00000000..f5b60114
--- /dev/null
+++ b/storage/tail/LICENSE
@@ -0,0 +1,14 @@
+Copyright 2016 JS Foundation and other contributors, https://js.foundation/
+Copyright 2013-2016 IBM Corp.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/storage/tail/README.md b/storage/tail/README.md
new file mode 100644
index 00000000..e6c9a935
--- /dev/null
+++ b/storage/tail/README.md
@@ -0,0 +1,17 @@
+node-red-node-tail
+==================
+
+A Node-Red node to tail a file and inject the contents into the flow.
+
+Install
+-------
+
+Either use the Menu - Manage palette option, or run the following command in your Node-RED user directory - typically `~/.node-red`
+
+ npm install node-red-node-tail
+
+
+Usage
+-----
+
+Allows
diff --git a/storage/tail/locales/en-US/28-tail.json b/storage/tail/locales/en-US/28-tail.json
new file mode 100644
index 00000000..dd2da852
--- /dev/null
+++ b/storage/tail/locales/en-US/28-tail.json
@@ -0,0 +1,20 @@
+{
+ "tail": {
+ "tail": "tail",
+ "label": {
+ "filename": "Filename",
+ "type": "File type",
+ "splitlines": "Split on",
+ "name": "Name",
+ "regex": "split character or regex"
+ },
+ "action": {
+ "text": "Text - returns String",
+ "binary": "Binary - returns Buffer"
+ },
+ "errors": {
+ "windowsnotsupport": "Not currently supported on Windows.",
+ "filenotfound": "File not found"
+ }
+ }
+}
diff --git a/storage/tail/package.json b/storage/tail/package.json
new file mode 100644
index 00000000..c3f7ddba
--- /dev/null
+++ b/storage/tail/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "node-red-node-tail",
+ "version": "0.0.1",
+ "description": "A node to tail files for Node-RED",
+ "dependencies": {
+ "tail": "^2.0.0"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/node-red/node-red-nodes/storage/tail/"
+ },
+ "license": "Apache-2.0",
+ "keywords": [
+ "node-red",
+ "tail"
+ ],
+ "node-red": {
+ "nodes": {
+ "tail": "28-tail.js"
+ }
+ },
+ "author": {
+ "name": "Dave Conway-Jones",
+ "email": "ceejay@vnet.ibm.com",
+ "url": "http://nodered.org"
+ }
+}
From 8eaab69d046a639b19c0998ccc7b493e25d0b7b7 Mon Sep 17 00:00:00 2001
From: Kazuhito Yokoi
Date: Wed, 24 Oct 2018 23:27:39 +0900
Subject: [PATCH 156/456] Update Japanese translation for twitter node (#500)
---
social/twitter/locales/ja/27-twitter.html | 73 +++++++++++++----------
social/twitter/locales/ja/27-twitter.json | 14 +++--
2 files changed, 49 insertions(+), 38 deletions(-)
diff --git a/social/twitter/locales/ja/27-twitter.html b/social/twitter/locales/ja/27-twitter.html
index f506cd62..db9f111c 100644
--- a/social/twitter/locales/ja/27-twitter.html
+++ b/social/twitter/locales/ja/27-twitter.html
@@ -1,41 +1,48 @@
+
+
+
+
diff --git a/social/twitter/locales/ja/27-twitter.json b/social/twitter/locales/ja/27-twitter.json
index 282445f1..3edc7f46 100644
--- a/social/twitter/locales/ja/27-twitter.json
+++ b/social/twitter/locales/ja/27-twitter.json
@@ -9,7 +9,14 @@
"followers": "followed by",
"tweetslabel": "tweets",
"eventslabel": "events",
- "clickhere": "Twitterの認証を行うため、ここをクリックしてください"
+ "create": "次のURLから自身のアプリケーションを作成",
+ "copy-consumer": "'Keys and tokens'セクションからConsumer APIキーをコピー",
+ "consumer_key": "API key",
+ "consumer_secret": "API secret key",
+ "copy-accessToken": "新たに'Access token & access token secret'を作成し、コピー",
+ "access_key": "Access token",
+ "access_secret": "Access token secret",
+ "enter-id": "Twitter IDを設定"
},
"placeholder": {
"for": "@ids, #tagsはコンマ区切りで入力",
@@ -41,10 +48,7 @@
"missingcredentials": "Twitterが認証されていません",
"truncated": "280文字を超えるツイートが切り捨てられました",
"sendfail": "ツイートの投稿が失敗: __error__",
- "nopayload": "ツイートするペイロードがありません",
- "oauthbroke": "something in twitter oauth broke.",
- "oautherror": "
+
+
+ only emit one message per most recent N values
+
@@ -44,9 +49,8 @@
A simple node to provide various functions across several previous values, including max, min, mean, high and low pass filters.
Messages arriving with different msg.topic can be treated as separate streams if so configured.
Max, Min and Mean work over a specified number of previous values.
-
The High and Low pass filters use a smoothing factor. The higher the number the more the smoothing. E.g. a value of 10 is
- similar to an α of 0.1. It is analagous to an RC time constant - but there is no time component to this as the
- time is based on events arriving.
+
The High and Low pass filters use a smoothing factor. The higher the number the more the smoothing. E.g. a value of 10 is similar to an α of 0.1. It is analagous to an RC time constant - but there is no time component to this as the time is based on events arriving.
+
Enabling the Reduce option causes the node to only emit one message per N values (available for the Max, Min and Mean functions). E.g. if set to Mean over 10 values, there will only be one outgoing message per 10 incoming ones.
If msg.reset is received (with any value), all the counters and intermediate values are reset to an initial state.
Note: This only operates on numbers. Anything else will try to be made into a number and rejected if that fails.
@@ -61,7 +65,8 @@
action: {value:"mean"},
count: {value:"10",required:true,validate:RED.validators.number()},
round: {value:""},
- mult: {value:"single"}
+ mult: {value:"single"},
+ reduce: {value:false}
},
inputs: 1,
outputs: 1,
@@ -87,10 +92,12 @@
if ((a === "high") || ( a === "low" )) {
$("#node-over").html("with a smoothing factor of ");
$("#node-over2").html("");
+ $("#row-input-reduce").hide();
}
else {
$("#node-over").html("over the most recent ");
$("#node-over2").html(" values");
+ $("#row-input-reduce").show();
}
});
$("#node-input-action").change();
diff --git a/function/smooth/17-smooth.js b/function/smooth/17-smooth.js
index 87b76c9c..c34c04aa 100644
--- a/function/smooth/17-smooth.js
+++ b/function/smooth/17-smooth.js
@@ -9,6 +9,7 @@ module.exports = function(RED) {
if (this.round == "true") { this.round = 0; }
this.count = Number(n.count);
this.mult = n.mult || "single";
+ this.reduce = n.reduce || false;
this.property = n.property || "payload";
var node = this;
var v = {};
@@ -16,6 +17,7 @@ module.exports = function(RED) {
this.on('input', function (msg) {
var value = RED.util.getMessageProperty(msg,node.property);
var top = msg.topic || "_my_default_topic";
+ var reduce = node.reduce;
if (this.mult === "single") { top = "a"; }
if ((v.hasOwnProperty(top) !== true) || msg.hasOwnProperty("reset")) {
@@ -26,15 +28,18 @@ module.exports = function(RED) {
v[top].pop = 0;
v[top].old = null;
v[top].count = this.count;
+ v[top].iter = 0;
}
if (value !== undefined) {
var n = Number(value);
if (!isNaN(n)) {
+ v[top].iter++;
if ((node.action === "low") || (node.action === "high")) {
if (v[top].old == null) { v[top].old = n; }
v[top].old = v[top].old + (n - v[top].old) / v[top].count;
if (node.action === "low") { value = v[top].old; }
else { value = n - v[top].old; }
+ reduce = false;
}
else {
v[top].a.push(n);
@@ -61,10 +66,13 @@ module.exports = function(RED) {
if (node.round !== false) {
value = Math.round(value * Math.pow(10, node.round)) / Math.pow(10, node.round);
}
- RED.util.setMessageProperty(msg,node.property,value);
- node.send(msg);
+ if (reduce == false || v[top].iter == v[top].count) {
+ v[top].iter = 0;
+ RED.util.setMessageProperty(msg,node.property,value);
+ node.send(msg);
+ }
}
- else { node.log("Not a number: "+value); }
+ else { node.log("Not a number: " + value); }
} // ignore msg with no payload property.
});
}
diff --git a/test/function/smooth/17-smooth_spec.js b/test/function/smooth/17-smooth_spec.js
index 33188765..ac7c7fc7 100644
--- a/test/function/smooth/17-smooth_spec.js
+++ b/test/function/smooth/17-smooth_spec.js
@@ -316,5 +316,79 @@ describe('smooth node', function() {
n1.emit("input", {payload:9, topic:"B"});
});
});
-
+ it("should reduce the number of messages by averaging if asked", function(done) {
+ var flow = [{"id":"n1", "type":"smooth", action:"mean", count:"5", reduce:"true", wires:[["n2"]] },
+ {id:"n2", type:"helper"} ];
+ helper.load(testNode, flow, function() {
+ var n1 = helper.getNode("n1");
+ var n2 = helper.getNode("n2");
+ var c = 0;
+ n2.on("input", function(msg) {
+ c += 1;
+ if (c === 1) { msg.should.have.a.property("payload", 3); }
+ else if (c === 2) { msg.should.have.a.property("payload", 6); done(); }
+ else if (c > 2) { done(new Error("should not emit more than two messages.")); }
+ });
+ n1.emit("input", {payload:1});
+ n1.emit("input", {payload:2});
+ n1.emit("input", {payload:3});
+ n1.emit("input", {payload:4});
+ n1.emit("input", {payload:5});
+ n1.emit("input", {payload:6});
+ n1.emit("input", {payload:7});
+ n1.emit("input", {payload:8});
+ n1.emit("input", {payload:9})
+; n1.emit("input", {payload:0});
+ });
+ });
+ it("should reduce the number of messages by max value, if asked", function(done) {
+ var flow = [{"id":"n1", "type":"smooth", action:"max", count:"5", reduce:"true", wires:[["n2"]] },
+ {id:"n2", type:"helper"} ];
+ helper.load(testNode, flow, function() {
+ var n1 = helper.getNode("n1");
+ var n2 = helper.getNode("n2");
+ var c = 0;
+ n2.on("input", function(msg) {
+ c += 1;
+ if (c === 1) { msg.should.have.a.property("payload", 5); }
+ else if (c === 2) { msg.should.have.a.property("payload", 9); done(); }
+ else if (c > 2) { done(new Error("should not emit more than two messages.")); }
+ });
+ n1.emit("input", {payload:1});
+ n1.emit("input", {payload:2});
+ n1.emit("input", {payload:3});
+ n1.emit("input", {payload:4});
+ n1.emit("input", {payload:5});
+ n1.emit("input", {payload:6});
+ n1.emit("input", {payload:7});
+ n1.emit("input", {payload:8});
+ n1.emit("input", {payload:9});
+ n1.emit("input", {payload:0});
+ });
+ });
+ it("should reduce the number of messages by min value, if asked", function(done) {
+ var flow = [{"id":"n1", "type":"smooth", action:"min", count:"5", reduce:"true", wires:[["n2"]] },
+ {id:"n2", type:"helper"} ];
+ helper.load(testNode, flow, function() {
+ var n1 = helper.getNode("n1");
+ var n2 = helper.getNode("n2");
+ var c = 0;
+ n2.on("input", function(msg) {
+ c += 1;
+ if (c === 1) { msg.should.have.a.property("payload", 1); }
+ else if (c === 2) { msg.should.have.a.property("payload", 0); done(); }
+ else if (c > 2) { done(new Error("should not emit more than two messages.")); }
+ });
+ n1.emit("input", {payload:1});
+ n1.emit("input", {payload:2});
+ n1.emit("input", {payload:3});
+ n1.emit("input", {payload:4});
+ n1.emit("input", {payload:5});
+ n1.emit("input", {payload:6});
+ n1.emit("input", {payload:7});
+ n1.emit("input", {payload:8});
+ n1.emit("input", {payload:9});
+ n1.emit("input", {payload:0});
+ });
+ });
});
From cabf2889e54ab365911ec45ecd44b59964869666 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Thu, 19 Sep 2019 09:25:44 +0100
Subject: [PATCH 264/456] Bump Smooth node for PR and add output labels
---
function/smooth/17-smooth.html | 1 +
function/smooth/package.json | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/function/smooth/17-smooth.html b/function/smooth/17-smooth.html
index 1b22a635..9658a7ce 100644
--- a/function/smooth/17-smooth.html
+++ b/function/smooth/17-smooth.html
@@ -77,6 +77,7 @@
labelStyle: function() {
return this.name ? "node_label_italic" : "";
},
+ outputLabels: function() { return this.reduce === true ? (this.action+" of "+this.count) : (this.action); },
oneditprepare: function() {
if (this.property === undefined) {
$("#node-input-property").val("payload");
diff --git a/function/smooth/package.json b/function/smooth/package.json
index 198a625d..2be74523 100644
--- a/function/smooth/package.json
+++ b/function/smooth/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-smooth",
- "version" : "0.1.0",
+ "version" : "0.1.1",
"description" : "A Node-RED node that provides several simple smoothing algorithms for incoming data values.",
"dependencies" : {
},
From 003655f1b3c8fa72ffc018831ec58554df8a2f16 Mon Sep 17 00:00:00 2001
From: Takeshi Ueno
Date: Thu, 19 Sep 2019 17:27:07 +0900
Subject: [PATCH 265/456] update support languages (#578)
https://docs.what3words.com/api/v3/#available-languages
---
parsers/what3words/what3words.html | 27 +++++++++++++++++++++++----
1 file changed, 23 insertions(+), 4 deletions(-)
diff --git a/parsers/what3words/what3words.html b/parsers/what3words/what3words.html
index 871159a7..ab3775a7 100644
--- a/parsers/what3words/what3words.html
+++ b/parsers/what3words/what3words.html
@@ -11,13 +11,32 @@
Tip: leave blank if you want to use msg.mac or msg.host to dynamically set target mac address.
+
Tip: leave blank if you want to use msg.mac, msg.host or msg.udpport to dynamically set target information.
-
-
-
-
-
-
-
-
-
-
diff --git a/function/rbe/locales/en-US/rbe.html b/function/rbe/locales/en-US/rbe.html
new file mode 100644
index 00000000..ce85d5a5
--- /dev/null
+++ b/function/rbe/locales/en-US/rbe.html
@@ -0,0 +1,37 @@
+
diff --git a/function/rbe/rbe.html b/function/rbe/rbe.html
index 48f0c103..a1505fe1 100644
--- a/function/rbe/rbe.html
+++ b/function/rbe/rbe.html
@@ -33,44 +33,6 @@
-
-
-
-
-
-
+
+
+
diff --git a/social/feedparser/32-feedparse.html b/social/feedparser/32-feedparse.html
index 0b815d5b..0e62d3ac 100644
--- a/social/feedparser/32-feedparse.html
+++ b/social/feedparser/32-feedparse.html
@@ -1,4 +1,3 @@
-
-
-
diff --git a/social/twitter/27-twitter.html b/social/twitter/27-twitter.html
index 3f14c7de..3d72a66c 100644
--- a/social/twitter/27-twitter.html
+++ b/social/twitter/27-twitter.html
@@ -1,4 +1,3 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/storage/tail/28-tail.html b/storage/tail/28-tail.html
index b0542d03..4f7c2063 100644
--- a/storage/tail/28-tail.html
+++ b/storage/tail/28-tail.html
@@ -1,4 +1,3 @@
-
-
-
From 3d60aa4c0029ee58421d3ccdff7b36b5e9e8bc36 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Thu, 5 Dec 2019 21:36:59 +0000
Subject: [PATCH 310/456] bump sentiment, rbe, email, feedparser, twitter, tail
nodes
Locale files moved out
---
analysis/sentiment/locales/en-US/72-sentiment.html | 2 +-
analysis/sentiment/locales/ja/72-sentiment.html | 2 +-
analysis/sentiment/package.json | 4 ++--
function/rbe/locales/en-US/rbe.html | 2 +-
function/rbe/locales/ja/rbe.html | 2 +-
function/rbe/package.json | 2 +-
package.json | 8 ++++----
social/email/locales/en-US/61-email.html | 4 ++--
social/email/locales/ja/61-email.html | 4 ++--
social/email/package.json | 4 ++--
social/feedparser/locales/en-US/32-feedparse.html | 2 +-
social/feedparser/locales/ja/32-feedparse.html | 2 +-
social/feedparser/package.json | 2 +-
social/twitter/locales/en-US/27-twitter.html | 6 +++---
social/twitter/locales/ja/27-twitter.html | 6 +++---
social/twitter/package.json | 2 +-
storage/tail/locales/en-US/28-tail.html | 2 +-
storage/tail/locales/ja/28-tail.html | 2 +-
storage/tail/package.json | 2 +-
19 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/analysis/sentiment/locales/en-US/72-sentiment.html b/analysis/sentiment/locales/en-US/72-sentiment.html
index da1bc83c..583d48bf 100644
--- a/analysis/sentiment/locales/en-US/72-sentiment.html
+++ b/analysis/sentiment/locales/en-US/72-sentiment.html
@@ -1,4 +1,4 @@
-
-
-
-
-
-
-
-
-
@@ -130,7 +132,7 @@
});
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -86,7 +91,7 @@
var levelNode = RED.nodes.node(this.mydb);
return this.name||(levelNode?levelNode.label():"mysql");
},
- labelStyle: function() {
+ labelStyle: function() {
return this.name?"node_label_italic":"";
}
});
diff --git a/storage/mysql/README.md b/storage/mysql/README.md
index 4371cfaa..0af76eba 100644
--- a/storage/mysql/README.md
+++ b/storage/mysql/README.md
@@ -7,7 +7,7 @@ Install
Either use the `Node-RED Menu - Manage Palette - Install`, or run the following command in your Node-RED user directory - typically `~/.node-red`
- npm install node-red-node-mysql
+ npm i node-red-node-mysql
Usage
@@ -17,7 +17,7 @@ Allows basic access to a MySQL database.
This node uses the query operation against the configured database. This does allow both INSERTS and DELETES.
-By it's very nature it allows SQL injection... so be careful out there...
+By its very nature it allows SQL injection... so be careful out there...
The `msg.topic` must hold the query for the database, and the result is returned in `msg.payload`.
diff --git a/storage/mysql/package.json b/storage/mysql/package.json
index 2e053b75..c328ef50 100644
--- a/storage/mysql/package.json
+++ b/storage/mysql/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-mysql",
- "version": "0.0.2-",
+ "version": "0.0.20",
"description": "A Node-RED node to read and write to a MySQL database",
"dependencies": {
"mysql": "^2.18.1"
From a57de3d8f21a6bed175a839107a54d432e9ba854 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Fri, 27 Mar 2020 11:36:18 +0000
Subject: [PATCH 339/456] Fix serialport to not try to log error and tell user
instead
to close #637
---
io/serialport/25-serial.js | 2 +-
io/serialport/locales/en-US/25-serial.json | 3 ++-
io/serialport/locales/ja/25-serial.json | 3 ++-
io/serialport/package.json | 4 ++--
4 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/io/serialport/25-serial.js b/io/serialport/25-serial.js
index 17035d14..5f32a35b 100644
--- a/io/serialport/25-serial.js
+++ b/io/serialport/25-serial.js
@@ -465,7 +465,7 @@ module.exports = function(RED) {
res.json(a);
},
err => {
- node.log('Error listing serial ports', err)
+ res.json([RED._("serial.errors.list")]);
}
)
});
diff --git a/io/serialport/locales/en-US/25-serial.json b/io/serialport/locales/en-US/25-serial.json
index 503cb0b8..fd52c996 100644
--- a/io/serialport/locales/en-US/25-serial.json
+++ b/io/serialport/locales/en-US/25-serial.json
@@ -65,7 +65,8 @@
"error": "serial port __port__ error: __error__",
"unexpected-close": "serial port __port__ closed unexpectedly",
"disconnected": "serial port __port__ disconnected",
- "closed": "serial port __port__ closed"
+ "closed": "serial port __port__ closed",
+ "list": "Failed to list ports. Please enter manually."
}
}
}
diff --git a/io/serialport/locales/ja/25-serial.json b/io/serialport/locales/ja/25-serial.json
index 42e4dfc0..f2189c85 100644
--- a/io/serialport/locales/ja/25-serial.json
+++ b/io/serialport/locales/ja/25-serial.json
@@ -50,7 +50,8 @@
"error": "serial port __port__ error: __error__",
"unexpected-close": "serial port __port__ closed unexpectedly",
"disconnected": "serial port __port__ disconnected",
- "closed": "serial port __port__ closed"
+ "closed": "serial port __port__ closed",
+ "list": "ポートのリスト化に失敗しました。手動で入力してください。"
}
}
}
diff --git a/io/serialport/package.json b/io/serialport/package.json
index 851c5123..35a87f6e 100644
--- a/io/serialport/package.json
+++ b/io/serialport/package.json
@@ -1,9 +1,9 @@
{
"name" : "node-red-node-serialport",
- "version" : "0.10.0",
+ "version" : "0.10.1",
"description" : "Node-RED nodes to talk to serial ports",
"dependencies" : {
- "serialport" : "^8.0.5"
+ "serialport" : "^8.0.7"
},
"repository" : {
"type":"git",
From 3087e8e2a1ea189f394bca0a2af159ad859d7722 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Tue, 31 Mar 2020 17:07:22 +0100
Subject: [PATCH 340/456] ensure clone msg for multi line output
to close #642
---
utility/daemon/daemon.js | 6 ++++--
utility/daemon/package.json | 2 +-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/utility/daemon/daemon.js b/utility/daemon/daemon.js
index 633d8154..6d6546a6 100644
--- a/utility/daemon/daemon.js
+++ b/utility/daemon/daemon.js
@@ -60,8 +60,10 @@ module.exports = function(RED) {
line += data.toString();
var bits = line.split("\n");
while (bits.length > 1) {
- lastmsg.payload = bits.shift();
- node.send([lastmsg,null,null]);
+ var m = RED.util.cloneMessage(lastmsg);
+ m.payload = bits.shift();
+ console.log(m);
+ node.send([m,null,null]);
}
line = bits[0];
}
diff --git a/utility/daemon/package.json b/utility/daemon/package.json
index 7650fe9b..be7932aa 100644
--- a/utility/daemon/package.json
+++ b/utility/daemon/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-daemon",
- "version" : "0.0.25",
+ "version" : "0.0.26",
"description" : "A Node-RED node that runs and monitors a long running system command.",
"dependencies" : {
},
From 34c3beb4305b11d2c59c58de543914cdc1f2e3bd Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Wed, 1 Apr 2020 17:51:51 +0100
Subject: [PATCH 341/456] bump daemon so npm update has a chance to update it
in future
---
utility/daemon/README.md | 3 ++-
utility/daemon/daemon.html | 4 ++--
utility/daemon/package.json | 2 +-
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/utility/daemon/README.md b/utility/daemon/README.md
index 2c46037b..57577643 100644
--- a/utility/daemon/README.md
+++ b/utility/daemon/README.md
@@ -13,7 +13,8 @@ Useful for monitoring command line based processes.
Install
-------
-Run the following command in your Node-RED user directory - typically `~/.node-red`
+Either use the Editor - Menu - Manage Palette - Install option or
+run the following command in your Node-RED user directory - typically `~/.node-red`
npm i node-red-node-daemon
diff --git a/utility/daemon/daemon.html b/utility/daemon/daemon.html
index 73e77450..2d0afb48 100644
--- a/utility/daemon/daemon.html
+++ b/utility/daemon/daemon.html
@@ -1,6 +1,6 @@
-
-
diff --git a/io/ping/88-ping.js b/io/ping/88-ping.js
index 1db1f59e..2b3ed337 100644
--- a/io/ping/88-ping.js
+++ b/io/ping/88-ping.js
@@ -1,61 +1,134 @@
module.exports = function(RED) {
"use strict";
- var spawn = require('child_process').spawn;
- var plat = require('os').platform();
+ var spawn = require("child_process").spawn;
+ var plat = require("os").platform();
+
+ function doPing(node, host, arrayMode){
+ const defTimeout = 5000;
+ var ex, hostOptions, commandLineOptions;
+ if(typeof host === "string"){
+ hostOptions = {
+ host: host,
+ timeout: defTimeout
+ }
+ } else {
+ hostOptions = host;
+ hostOptions.timeout = isNaN(parseInt(hostOptions.timeout)) ? defTimeout : parseInt(hostOptions.timeout);
+ }
+ //clamp timeout between 1 and 30 sec
+ hostOptions.timeout = hostOptions.timeout < 1000 ? 1000 : hostOptions.timeout;
+ hostOptions.timeout = hostOptions.timeout > 30000 ? 30000 : hostOptions.timeout;
+ var timeoutS = Math.round(hostOptions.timeout / 1000); //whole numbers only
+ var msg = { payload:false, topic:hostOptions.host };
+ //only include the extra msg object if operating in advance/array mode.
+ if(arrayMode){
+ msg.ping = hostOptions
+ }
+ if (plat == "linux" || plat == "android") {
+ commandLineOptions = ["-n", "-w", timeoutS, "-c", "1"]
+ } else if (plat.match(/^win/)) {
+ commandLineOptions = ["-n", "1", "-w", hostOptions.timeout]
+ } else if (plat == "darwin" || plat == "freebsd") {
+ commandLineOptions = ["-n", "-t", timeoutS, "-c", "1"]
+ } else {
+ node.error("Sorry - your platform - "+plat+" - is not recognised.", msg);
+ return; //dont pass go - just return!
+ }
+
+ //spawn with timeout in case of os issue
+ ex = spawn("ping", [...commandLineOptions, hostOptions.host]);
+
+ //monitor every spawned process & SIGINT if too long
+ var spawnTout = setTimeout(() => {
+ node.log(`ping - Host '${hostOptions.host}' process timeout - sending SIGINT`)
+ try{if(ex && ex.pid){ ex.kill("SIGINT"); }} catch(e){console.warn(e)}
+ }, hostOptions.timeout+1000); //add 1s for grace
+
+ var res = false;
+ var line = "";
+ var fail = false;
+ //var regex = /from.*time.(.*)ms/;
+ var regex = /=.*[<|=]([0-9]*).*TTL|ttl..*=([0-9\.]*)/;
+ ex.stdout.on("data", function (data) {
+ line += data.toString();
+ });
+ ex.on("exit", function (err) {
+ clearTimeout(spawnTout);
+ });
+ ex.on("error", function (err) {
+ fail = true;
+ if (err.code === "ENOENT") {
+ node.error(err.code + " ping command not found", msg);
+ }
+ else if (err.code === "EACCES") {
+ node.error(err.code + " can't run ping command", msg);
+ }
+ else {
+ node.error(err.code, msg);
+ }
+ });
+ ex.on("close", function (code) {
+ if (fail) { fail = false; return; }
+ var m = regex.exec(line)||"";
+ if (m !== "") {
+ if (m[1]) { res = Number(m[1]); }
+ if (m[2]) { res = Number(m[2]); }
+ }
+ if (code === 0) { msg.payload = res }
+ try { node.send(msg); }
+ catch(e) {console.warn(e)}
+ });
+ }
function PingNode(n) {
RED.nodes.createNode(this,n);
+ this.mode = n.mode;
this.host = n.host;
this.timer = n.timer * 1000;
var node = this;
- node.tout = setInterval(function() {
- var ex;
- if (plat == "linux" || plat == "android") { ex = spawn('ping', ['-n', '-w', '5', '-c', '1', node.host]); }
- else if (plat.match(/^win/)) { ex = spawn('ping', ['-n', '1', '-w', '5000', node.host]); }
- else if (plat == "darwin" || plat == "freebsd") { ex = spawn('ping', ['-n', '-t', '5', '-c', '1', node.host]); }
- else { node.error("Sorry - your platform - "+plat+" - is not recognised."); }
- var res = false;
- var line = "";
- var fail = false;
- //var regex = /from.*time.(.*)ms/;
- var regex = /=.*[<|=]([0-9]*).*TTL|ttl..*=([0-9\.]*)/;
- ex.stdout.on('data', function (data) {
- line += data.toString();
- });
- //ex.stderr.on('data', function (data) {
- //console.log('[ping] stderr: ' + data);
- //});
- ex.on('error', function (err) {
- fail = true;
- if (err.code === "ENOENT") {
- node.error(err.code + " ping command not found");
+ function generatePingList(str) {
+ return (str + "").split(",").map((e) => (e + "").trim()).filter((e) => e != "");
+ }
+ function clearPingInterval(){
+ if (node.tout) { clearInterval(node.tout); }
+ }
+
+ if(node.mode === "triggered"){
+ clearPingInterval();
+ } else if(node.timer){
+ node.tout = setInterval(function() {
+ let pingables = generatePingList(node.host);
+ for (let index = 0; index < pingables.length; index++) {
+ const element = pingables[index];
+ if(element){ doPing(node, element, false); }
}
- else if (err.code === "EACCES") {
- node.error(err.code + " can't run ping command");
+ }, node.timer);
+ }
+
+ this.on("input", function (msg) {
+ let node = this;
+ let payload = node.host || msg.payload;
+ if(typeof payload == "string"){
+ let pingables = generatePingList(payload)
+ for (let index = 0; index < pingables.length; index++) {
+ const element = pingables[index];
+ if(element){ doPing(node, element, false); }
}
- else {
- node.error(err.code);
+ } else if (Array.isArray(payload) ) {
+ for (let index = 0; index < payload.length; index++) {
+ const element = payload[index];
+ if(element){ doPing(node, element, true); }
}
- });
- ex.on('close', function (code) {
- if (fail) { fail = false; return; }
- var m = regex.exec(line)||"";
- if (m !== '') {
- if (m[1]) { res = Number(m[1]); }
- if (m[2]) { res = Number(m[2]); }
- }
- var msg = { payload:false, topic:node.host };
- if (code === 0) { msg = { payload:res, topic:node.host }; }
- try { node.send(msg); }
- catch(e) {}
- });
- }, node.timer);
+ }
+ });
this.on("close", function() {
- if (this.tout) { clearInterval(this.tout); }
+ clearPingInterval();
});
+
+
}
RED.nodes.registerType("ping",PingNode);
-}
+}
\ No newline at end of file
diff --git a/io/ping/README.md b/io/ping/README.md
index 36127c73..44cb27d0 100644
--- a/io/ping/README.md
+++ b/io/ping/README.md
@@ -27,7 +27,7 @@ The fix is to allow it as follows
Usage
-----
-Pings a machine and returns the trip time in mS as `msg.payload`.
+Pings 1 or more devices and returns the trip time in mS as `msg.payload`.
Returns boolean `false` if no response received, or if the host is unresolveable.
@@ -35,4 +35,9 @@ Returns boolean `false` if no response received, or if the host is unresolveable
`msg.topic` contains the ip address of the target host.
-Default ping is every 20 seconds but can be configured.
+There are 2 modes - `Timed` and `Triggered`.
+
+* Timed mode - this is the default mode that pings your devices on a timed basis. Default ping is every 20 seconds but can be configured.
+* Triggered mode - this mode permits you to trigger the ping by an input message. If the `Target` is left blank and `msg.payload` is a string or array, you can ping 1 or more devices on demand.
+
+Refer to the built in help on the side-bar info panel for more details.
diff --git a/io/ping/locales/en-US/88-ping.html b/io/ping/locales/en-US/88-ping.html
index 4ba4dde9..cd81ec09 100644
--- a/io/ping/locales/en-US/88-ping.html
+++ b/io/ping/locales/en-US/88-ping.html
@@ -1,8 +1,53 @@
-
diff --git a/io/ping/locales/en-US/88-ping.json b/io/ping/locales/en-US/88-ping.json
index bcff8820..f1a9093e 100644
--- a/io/ping/locales/en-US/88-ping.json
+++ b/io/ping/locales/en-US/88-ping.json
@@ -3,7 +3,12 @@
"ping": "ping",
"label": {
"target": "Target",
- "ping": "Ping (S)"
+ "ping": "Ping (S)",
+ "mode": "Mode",
+ "mode_option": {
+ "timed": "Timed",
+ "triggered": "Triggered"
+ }
}
}
}
diff --git a/io/ping/locales/ja/88-ping.html b/io/ping/locales/ja/88-ping.html
index 922747bf..ead433ad 100644
--- a/io/ping/locales/ja/88-ping.html
+++ b/io/ping/locales/ja/88-ping.html
@@ -1,8 +1,82 @@
- -->
+
+
+
diff --git a/io/ping/locales/ja/88-ping.json b/io/ping/locales/ja/88-ping.json
index 7b39cf3d..5eefe0e2 100644
--- a/io/ping/locales/ja/88-ping.json
+++ b/io/ping/locales/ja/88-ping.json
@@ -3,7 +3,12 @@
"ping": "ping",
"label": {
"target": "対象",
- "ping": "Ping (秒)"
+ "ping": "Ping (秒)",
+ "mode": "モード",
+ "mode_option": {
+ "timed": "時限",
+ "triggered": "引き金になった"
+ }
}
}
}
From 7667de5ced55bec815ccb730a28eccb074deded8 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Fri, 3 Apr 2020 16:50:09 +0100
Subject: [PATCH 343/456] Tidy up ping notes for pub
---
io/ping/88-ping.html | 12 +++++---
io/ping/locales/en-US/88-ping.html | 47 ++++++++++++++++--------------
io/ping/locales/en-US/88-ping.json | 3 +-
io/ping/package.json | 7 +++--
4 files changed, 40 insertions(+), 29 deletions(-)
diff --git a/io/ping/88-ping.html b/io/ping/88-ping.html
index 7826c500..b82abfda 100644
--- a/io/ping/88-ping.html
+++ b/io/ping/88-ping.html
@@ -19,6 +19,7 @@
+
diff --git a/io/ping/locales/en-US/88-ping.json b/io/ping/locales/en-US/88-ping.json
index f1a9093e..0bfc7373 100644
--- a/io/ping/locales/en-US/88-ping.json
+++ b/io/ping/locales/en-US/88-ping.json
@@ -8,7 +8,8 @@
"mode_option": {
"timed": "Timed",
"triggered": "Triggered"
- }
+ },
+ "tip": "Note: Leave Target field blank to allow msg.payload to set hosts dynamically."
}
}
}
diff --git a/io/ping/package.json b/io/ping/package.json
index 6ce6cffe..31edb417 100644
--- a/io/ping/package.json
+++ b/io/ping/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-ping",
- "version" : "0.1.0",
+ "version" : "0.2.0",
"description" : "A Node-RED node to ping a remote server, for use as a keep-alive check.",
"dependencies" : {
},
@@ -19,5 +19,8 @@
"name": "Dave Conway-Jones",
"email": "ceejay@vnet.ibm.com",
"url": "http://nodered.org"
- }
+ },
+ "contributors": [
+ { "name": "@Steve-Mcl" }
+ ]
}
From 9b1eeb2756f836d75da49c592e458361561799aa Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Fri, 3 Apr 2020 17:55:30 +0100
Subject: [PATCH 344/456] shorten ping label if more than one target
---
io/ping/88-ping.html | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/io/ping/88-ping.html b/io/ping/88-ping.html
index b82abfda..db087d8e 100644
--- a/io/ping/88-ping.html
+++ b/io/ping/88-ping.html
@@ -74,8 +74,8 @@ var timerParameterValidator = function(node,v){
},
label: function() {
let lbl = this.name||this.host||this._("ping.ping");
- if(lbl.length > 20){
- lbl = lbl.substring(0,17) + "..."
+ if (lbl.split(',').length > 1){
+ lbl = this._("ping.ping");
}
return lbl;
},
From 7c759e10dd304911a04f756925e6a015bc30ac59 Mon Sep 17 00:00:00 2001
From: Kazuhito Yokoi
Date: Sat, 4 Apr 2020 06:12:22 +0900
Subject: [PATCH 345/456] Add and remove namespaces for i18n (#627)
* Add necessary name spaces for i18n
* Remove unnecessary name spaces for i18n
---
hardware/PiGpio/36-rpi-gpio.html | 16 ++++++++--------
hardware/PiGpio/36-rpi-gpio.js | 8 ++++----
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/hardware/PiGpio/36-rpi-gpio.html b/hardware/PiGpio/36-rpi-gpio.html
index 0c3d28e4..47f8e4c7 100644
--- a/hardware/PiGpio/36-rpi-gpio.html
+++ b/hardware/PiGpio/36-rpi-gpio.html
@@ -173,8 +173,8 @@
-
-
+
+
@@ -366,8 +366,8 @@
Hz
-
-
+
+
@@ -497,8 +497,8 @@
-
-
+
+
@@ -528,8 +528,8 @@
diff --git a/hardware/PiGpio/36-rpi-gpio.js b/hardware/PiGpio/36-rpi-gpio.js
index fc3d43bf..a922e5fd 100644
--- a/hardware/PiGpio/36-rpi-gpio.js
+++ b/hardware/PiGpio/36-rpi-gpio.js
@@ -87,7 +87,7 @@ module.exports = function(RED) {
}
}
else {
- node.status({fill:"grey",shape:"dot",text:"node-red:rpi-gpio.status.not-available"});
+ node.status({fill:"grey",shape:"dot",text:"rpi-gpio.status.not-available"});
if (node.read === true) {
var val;
if (node.intype == "up") { val = 1; }
@@ -193,7 +193,7 @@ module.exports = function(RED) {
}
}
else {
- node.status({fill:"grey",shape:"dot",text:"node-red:rpi-gpio.status.not-available"});
+ node.status({fill:"grey",shape:"dot",text:"rpi-gpio.status.not-available"});
node.on("input", function(msg) {
node.status({fill:"grey",shape:"dot",text:RED._("rpi-gpio.status.na",{value:msg.payload.toString()})});
});
@@ -260,7 +260,7 @@ module.exports = function(RED) {
});
}
else {
- node.status({fill:"grey",shape:"dot",text:"node-red:rpi-gpio.status.not-available"});
+ node.status({fill:"grey",shape:"dot",text:"rpi-gpio.status.not-available"});
}
}
RED.nodes.registerType("rpi-mouse",PiMouseNode);
@@ -313,7 +313,7 @@ module.exports = function(RED) {
});
}
else {
- node.status({fill:"grey",shape:"dot",text:"node-red:rpi-gpio.status.not-available"});
+ node.status({fill:"grey",shape:"dot",text:"rpi-gpio.status.not-available"});
}
}
RED.nodes.registerType("rpi-keyboard",PiKeyboardNode);
From 3c4337f2383c60ae398da5f866d6fad3f1d72a39 Mon Sep 17 00:00:00 2001
From: arneman <7462507+arneman@users.noreply.github.com>
Date: Fri, 3 Apr 2020 23:13:10 +0200
Subject: [PATCH 346/456] add an example for a prepared sql query (#621)
An example sql query for the given parameter example would help users to understand how they could use prepared statements.
---
storage/sqlite/sqlite.html | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/storage/sqlite/sqlite.html b/storage/sqlite/sqlite.html
index 65f30774..ceeca265 100644
--- a/storage/sqlite/sqlite.html
+++ b/storage/sqlite/sqlite.html
@@ -74,7 +74,8 @@
$name:"John Doe"
}
Parameter object names must match parameters set up in the Prepared Statement. If you get the error SQLITE_RANGE: bind or column index out of range
- be sure to include $ on the parameter object key.
+ be sure to include $ on the parameter object key.
+ The sql query for the example above could be: insert into user_table (user_id, user) VALUES ($id, $name);
Using any SQL Query, the result is returned in msg.payload
Typically the returned payload will be an array of the result rows, (or an error).
You can load sqlite extensions by inputting a msg.extension property containing the full
From 3d9b3823cc999138f0318369d2e59aa427d5e6e5 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Fri, 3 Apr 2020 22:25:35 +0100
Subject: [PATCH 347/456] suncalc rearrange sorti of times into time order
to close #633
---
time/suncalc/79-suncalc.html | 14 +++++++-------
time/suncalc/package.json | 2 +-
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/time/suncalc/79-suncalc.html b/time/suncalc/79-suncalc.html
index 69feede9..2776a656 100644
--- a/time/suncalc/79-suncalc.html
+++ b/time/suncalc/79-suncalc.html
@@ -1,5 +1,5 @@
-
- -->
-
-
diff --git a/io/ping/locales/ja/88-ping.json b/io/ping/locales/ja/88-ping.json
index 5eefe0e2..9828b1d9 100644
--- a/io/ping/locales/ja/88-ping.json
+++ b/io/ping/locales/ja/88-ping.json
@@ -2,13 +2,14 @@
"ping": {
"ping": "ping",
"label": {
- "target": "対象",
+ "target": "ターゲット",
"ping": "Ping (秒)",
"mode": "モード",
"mode_option": {
- "timed": "時限",
- "triggered": "引き金になった"
- }
+ "timed": "時間",
+ "triggered": "トリガー"
+ },
+ "tip": "注: msg.payloadでホスト名を動的に指定する場合は、ターゲットフィールドを空にします。"
}
}
}
From 705dd1ffc11ab1101007df08474b50a4541db261 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Sun, 5 Apr 2020 11:44:27 +0100
Subject: [PATCH 350/456] mysql - ensure connection released back to pool more
often
and try to ensure status is shown more correctly on error.
---
storage/mysql/68-mysql.js | 7 +++++--
storage/mysql/package.json | 2 +-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/storage/mysql/68-mysql.js b/storage/mysql/68-mysql.js
index 4b4b8ac0..7d8e3aee 100644
--- a/storage/mysql/68-mysql.js
+++ b/storage/mysql/68-mysql.js
@@ -19,8 +19,8 @@ module.exports = function(RED) {
function checkVer() {
node.connection.query("SELECT version();", [], function(err, rows) {
+ node.connection.release();
if (err) {
- node.connection.release();
node.error(err);
node.status({fill:"red",shape:"ring",text:"Bad Ping"});
doConnect();
@@ -86,6 +86,7 @@ module.exports = function(RED) {
if (this.tick) { clearTimeout(this.tick); }
if (this.check) { clearInterval(this.check); }
node.connected = false;
+ node.connection.release();
node.emit("state"," ");
node.pool.end(function (err) { done(); });
});
@@ -124,8 +125,9 @@ module.exports = function(RED) {
var bind = Array.isArray(msg.payload) ? msg.payload : [];
node.mydbConfig.connection.query(msg.topic, bind, function(err, rows) {
if (err) {
+ status = {fill:"red",shape:"ring",text:"Error: "+err.code};
+ node.status(status);
node.error(err,msg);
- status = {fill:"red",shape:"ring",text:"Error"};
}
else {
if (rows.constructor.name === "OkPacket") {
@@ -134,6 +136,7 @@ module.exports = function(RED) {
else { msg.payload = rows; }
node.send(msg);
status = {fill:"green",shape:"dot",text:"OK"};
+ node.status(status);
}
});
}
diff --git a/storage/mysql/package.json b/storage/mysql/package.json
index c328ef50..8140d1c4 100644
--- a/storage/mysql/package.json
+++ b/storage/mysql/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-mysql",
- "version": "0.0.20",
+ "version": "0.0.21",
"description": "A Node-RED node to read and write to a MySQL database",
"dependencies": {
"mysql": "^2.18.1"
From fa8e174d0b12419d02b6382dabaee158ab5c2665 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Sun, 5 Apr 2020 12:35:15 +0100
Subject: [PATCH 351/456] mysql - slightly overzealous closing of connections -
causes crash. backed off slightly
---
storage/mysql/68-mysql.js | 3 ++-
storage/mysql/package.json | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/storage/mysql/68-mysql.js b/storage/mysql/68-mysql.js
index 7d8e3aee..95444e7f 100644
--- a/storage/mysql/68-mysql.js
+++ b/storage/mysql/68-mysql.js
@@ -19,8 +19,8 @@ module.exports = function(RED) {
function checkVer() {
node.connection.query("SELECT version();", [], function(err, rows) {
- node.connection.release();
if (err) {
+ node.connection.release();
node.error(err);
node.status({fill:"red",shape:"ring",text:"Bad Ping"});
doConnect();
@@ -103,6 +103,7 @@ module.exports = function(RED) {
RED.nodes.createNode(this,n);
this.mydb = n.mydb;
this.mydbConfig = RED.nodes.getNode(this.mydb);
+ this.status({});
if (this.mydbConfig) {
this.mydbConfig.connect();
diff --git a/storage/mysql/package.json b/storage/mysql/package.json
index 8140d1c4..1bad178a 100644
--- a/storage/mysql/package.json
+++ b/storage/mysql/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-mysql",
- "version": "0.0.21",
+ "version": "0.0.22",
"description": "A Node-RED node to read and write to a MySQL database",
"dependencies": {
"mysql": "^2.18.1"
From a37fa35a8aed6b533f3fb0796fa18d5d57f2549d Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Mon, 6 Apr 2020 21:42:44 +0100
Subject: [PATCH 352/456] [groups] Add node-red-node-group node
---
utility/group/LICENSE | 14 ++++++++++++++
utility/group/README.md | 25 ++++++++++++++++++++++++
utility/group/group.html | 39 ++++++++++++++++++++++++++++++++++++++
utility/group/group.js | 16 ++++++++++++++++
utility/group/package.json | 20 +++++++++++++++++++
5 files changed, 114 insertions(+)
create mode 100644 utility/group/LICENSE
create mode 100644 utility/group/README.md
create mode 100644 utility/group/group.html
create mode 100644 utility/group/group.js
create mode 100644 utility/group/package.json
diff --git a/utility/group/LICENSE b/utility/group/LICENSE
new file mode 100644
index 00000000..f5b60114
--- /dev/null
+++ b/utility/group/LICENSE
@@ -0,0 +1,14 @@
+Copyright 2016 JS Foundation and other contributors, https://js.foundation/
+Copyright 2013-2016 IBM Corp.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/utility/group/README.md b/utility/group/README.md
new file mode 100644
index 00000000..4c6f56e2
--- /dev/null
+++ b/utility/group/README.md
@@ -0,0 +1,25 @@
+node-red-node-group
+===================
+
+A Node-RED node to allow flows containing groups to be imported into older versions
+of Node-RED.
+
+The ability to create groups was introduced in Node-RED 1.1.0, adding a new core
+node type called `group`.
+
+This module provides its own `group` node type that can be installed into older
+versions of Node-RED to allow them to run flows containing that type.
+
+It does *not* provide any group-like functionality - it *only* registers a
+placeholder `group` node type.
+
+The module will only register the type if it detects it is being loaded into
+Node-RED 1.0.x or older, otherwise it does nothing.
+
+
+Install
+-------
+
+Run the following command in your Node-RED user directory - typically `~/.node-red`
+
+ npm i node-red-node-group
diff --git a/utility/group/group.html b/utility/group/group.html
new file mode 100644
index 00000000..d002ba40
--- /dev/null
+++ b/utility/group/group.html
@@ -0,0 +1,39 @@
+
+
+
+
+
diff --git a/utility/group/group.js b/utility/group/group.js
new file mode 100644
index 00000000..f976d2f4
--- /dev/null
+++ b/utility/group/group.js
@@ -0,0 +1,16 @@
+
+module.exports = function(RED) {
+ var version = RED.version();
+ var parts = /^(\d)+\.(\d)+\.(\d)+/.exec(version);
+ if (parts) {
+ var major = parseInt(parts[1]);
+ var minor = parseInt(parts[2]);
+ if (major > 1 || (major === 1 && minor > 0)) {
+ throw new Error("This module is not required for Node-RED 1.1.0 or later")
+ }
+ }
+ function GroupPolyfillNode(n) {
+ RED.nodes.createNode(this,n);
+ }
+ RED.nodes.registerType("group",GroupPolyfillNode);
+}
diff --git a/utility/group/package.json b/utility/group/package.json
new file mode 100644
index 00000000..fb88571e
--- /dev/null
+++ b/utility/group/package.json
@@ -0,0 +1,20 @@
+{
+ "name": "node-red-node-group",
+ "version": "1.0.0",
+ "description": "A Node-RED node to allow flows containing groups to be imported into Node-RED 1.0.x or earlier.",
+ "dependencies": {},
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/node-red/node-red-nodes/tree/master/utility/group"
+ },
+ "license": "Apache-2.0",
+ "keywords": [
+ "node-red"
+ ],
+ "node-red": {
+ "nodes": {
+ "group": "group.js"
+ }
+ },
+ "author": "Nick O'Leary "
+}
From 7ccbb6fc9fa627a94ec2f1268201f3a9a8d8b0d5 Mon Sep 17 00:00:00 2001
From: Hiroyasu Nishiyama
Date: Sat, 11 Apr 2020 06:40:57 +0900
Subject: [PATCH 353/456] Update Japanese message catalogue of RPI-GPIO (#645)
---
hardware/PiGpio/locales/ja/36-rpi-gpio.json | 140 ++++++++++----------
1 file changed, 71 insertions(+), 69 deletions(-)
diff --git a/hardware/PiGpio/locales/ja/36-rpi-gpio.json b/hardware/PiGpio/locales/ja/36-rpi-gpio.json
index a76daba6..619eb3ef 100644
--- a/hardware/PiGpio/locales/ja/36-rpi-gpio.json
+++ b/hardware/PiGpio/locales/ja/36-rpi-gpio.json
@@ -1,73 +1,75 @@
-"rpi-gpio": {
- "label": {
- "gpiopin": "GPIO",
- "selectpin": "端子の選択",
- "resistor": "抵抗",
- "readinitial": "デプロイや再起動時に端子の初期状態を読み込む",
- "type": "出力形式",
- "initpin": "端子の状態を初期化",
- "debounce": "デバウンス",
- "freq": "頻度",
- "button": "ボタン",
- "pimouse": "Pi Mouse",
- "pikeyboard": "Pi Keyboard",
- "left": "Left",
- "right": "Right",
- "middle": "Middle"
- },
- "resistor": {
- "none": "なし",
- "pullup": "プルアップ",
- "pulldown": "プルダウン"
- },
- "digout": "デジタル出力",
- "pwmout": "PWM出力",
- "servo": "サーボ出力",
- "initpin0": "端子の初期レベル - Low (0)",
- "initpin1": "端子の初期レベル - High (1)",
- "left": "左",
- "right": "右",
- "middle": "中間",
- "any": "全て",
- "pinname": "端子",
- "alreadyuse": "使用中",
- "alreadyset": "設定済",
- "tip": {
- "pin": "使用中の端子: ",
- "in": "注釈: 入力値は、0または1の数値のみ対応しています。",
- "dig": "注釈: 「出力形式」として「デジタル出力」を用いる場合、入力値は0または1の数値である必要があります。",
- "pwm": "注釈: 「出力形式」として「PWM出力」を用いる場合、入力値は0~100の数値である必要があります。",
- "ser": "注釈: サーボ出力向け - 入力値は0~100の間である必要があります。50が中心値です。"
- },
- "types": {
+{
+ "rpi-gpio": {
+ "label": {
+ "gpiopin": "GPIO",
+ "selectpin": "端子の選択",
+ "resistor": "抵抗",
+ "readinitial": "デプロイや再起動時に端子の初期状態を読み込む",
+ "type": "出力形式",
+ "initpin": "端子の状態を初期化",
+ "debounce": "デバウンス",
+ "freq": "頻度",
+ "button": "ボタン",
+ "pimouse": "Pi Mouse",
+ "pikeyboard": "Pi Keyboard",
+ "left": "Left",
+ "right": "Right",
+ "middle": "Middle"
+ },
+ "resistor": {
+ "none": "なし",
+ "pullup": "プルアップ",
+ "pulldown": "プルダウン"
+ },
"digout": "デジタル出力",
- "input": "入力",
- "pullup": "プルアップの入力",
- "pulldown": "プルダウンの入力",
"pwmout": "PWM出力",
- "servo": "サーボ出力"
- },
- "status": {
- "stopped": "停止",
- "closed": "切断",
- "not-running": "停止中",
- "not-available": "利用不可",
- "na": "N/A : __value__",
- "ok": "OK"
- },
- "errors": {
- "ignorenode": "Raspberry Pi固有のノードを無視しました",
- "version": "バージョンコマンドが失敗しました",
- "sawpitype": "Saw Pi Type",
- "libnotfound": "RPi.GPIO pythonライブラリを見つけられませんでした",
- "alreadyset": "GPIO端子 __pin__ は既に出力形式が設定されています: __type__",
- "invalidpin": "GPIO端子が不正です",
- "invalidinput": "入力が不正です",
- "needtobeexecutable": "__command__ は実行可能である必要があります",
- "mustbeexecutable": "nrgpio は実行可能である必要があります",
- "commandnotfound": "nrgpio コマンドが見つかりません",
- "commandnotexecutable": "nrgpio コマンドが実行可能ではありません",
- "error": "エラー: __error__",
- "pythoncommandnotfound": "nrgpio python コマンドが実行されていません"
+ "servo": "サーボ出力",
+ "initpin0": "端子の初期レベル - Low (0)",
+ "initpin1": "端子の初期レベル - High (1)",
+ "left": "左",
+ "right": "右",
+ "middle": "中間",
+ "any": "全て",
+ "pinname": "端子",
+ "alreadyuse": "使用中",
+ "alreadyset": "設定済",
+ "tip": {
+ "pin": "使用中の端子: ",
+ "in": "注釈: 入力値は、0または1の数値のみ対応しています。",
+ "dig": "注釈: 「出力形式」として「デジタル出力」を用いる場合、入力値は0または1の数値である必要があります。",
+ "pwm": "注釈: 「出力形式」として「PWM出力」を用いる場合、入力値は0~100の数値である必要があります。",
+ "ser": "注釈: サーボ出力向け - 入力値は0~100の間である必要があります。50が中心値です。"
+ },
+ "types": {
+ "digout": "デジタル出力",
+ "input": "入力",
+ "pullup": "プルアップの入力",
+ "pulldown": "プルダウンの入力",
+ "pwmout": "PWM出力",
+ "servo": "サーボ出力"
+ },
+ "status": {
+ "stopped": "停止",
+ "closed": "切断",
+ "not-running": "停止中",
+ "not-available": "利用不可",
+ "na": "N/A : __value__",
+ "ok": "OK"
+ },
+ "errors": {
+ "ignorenode": "Raspberry Pi固有のノードを無視しました",
+ "version": "バージョンコマンドが失敗しました",
+ "sawpitype": "Saw Pi Type",
+ "libnotfound": "RPi.GPIO pythonライブラリを見つけられませんでした",
+ "alreadyset": "GPIO端子 __pin__ は既に出力形式が設定されています: __type__",
+ "invalidpin": "GPIO端子が不正です",
+ "invalidinput": "入力が不正です",
+ "needtobeexecutable": "__command__ は実行可能である必要があります",
+ "mustbeexecutable": "nrgpio は実行可能である必要があります",
+ "commandnotfound": "nrgpio コマンドが見つかりません",
+ "commandnotexecutable": "nrgpio コマンドが実行可能ではありません",
+ "error": "エラー: __error__",
+ "pythoncommandnotfound": "nrgpio python コマンドが実行されていません"
+ }
}
}
From bf1c5abd7d6aa4aee4927bae651904445ec77d54 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Fri, 10 Apr 2020 22:44:55 +0100
Subject: [PATCH 354/456] Merge branch 'master' of
https://github.com/node-red/node-red-nodes
---
hardware/PiGpio/locales/ja/36-rpi-gpio.json | 140 ++++++++++----------
hardware/PiGpio/package.json | 2 +-
utility/group/LICENSE | 14 ++
utility/group/README.md | 25 ++++
utility/group/group.html | 39 ++++++
utility/group/group.js | 16 +++
utility/group/package.json | 20 +++
7 files changed, 186 insertions(+), 70 deletions(-)
create mode 100644 utility/group/LICENSE
create mode 100644 utility/group/README.md
create mode 100644 utility/group/group.html
create mode 100644 utility/group/group.js
create mode 100644 utility/group/package.json
diff --git a/hardware/PiGpio/locales/ja/36-rpi-gpio.json b/hardware/PiGpio/locales/ja/36-rpi-gpio.json
index a76daba6..619eb3ef 100644
--- a/hardware/PiGpio/locales/ja/36-rpi-gpio.json
+++ b/hardware/PiGpio/locales/ja/36-rpi-gpio.json
@@ -1,73 +1,75 @@
-"rpi-gpio": {
- "label": {
- "gpiopin": "GPIO",
- "selectpin": "端子の選択",
- "resistor": "抵抗",
- "readinitial": "デプロイや再起動時に端子の初期状態を読み込む",
- "type": "出力形式",
- "initpin": "端子の状態を初期化",
- "debounce": "デバウンス",
- "freq": "頻度",
- "button": "ボタン",
- "pimouse": "Pi Mouse",
- "pikeyboard": "Pi Keyboard",
- "left": "Left",
- "right": "Right",
- "middle": "Middle"
- },
- "resistor": {
- "none": "なし",
- "pullup": "プルアップ",
- "pulldown": "プルダウン"
- },
- "digout": "デジタル出力",
- "pwmout": "PWM出力",
- "servo": "サーボ出力",
- "initpin0": "端子の初期レベル - Low (0)",
- "initpin1": "端子の初期レベル - High (1)",
- "left": "左",
- "right": "右",
- "middle": "中間",
- "any": "全て",
- "pinname": "端子",
- "alreadyuse": "使用中",
- "alreadyset": "設定済",
- "tip": {
- "pin": "使用中の端子: ",
- "in": "注釈: 入力値は、0または1の数値のみ対応しています。",
- "dig": "注釈: 「出力形式」として「デジタル出力」を用いる場合、入力値は0または1の数値である必要があります。",
- "pwm": "注釈: 「出力形式」として「PWM出力」を用いる場合、入力値は0~100の数値である必要があります。",
- "ser": "注釈: サーボ出力向け - 入力値は0~100の間である必要があります。50が中心値です。"
- },
- "types": {
+{
+ "rpi-gpio": {
+ "label": {
+ "gpiopin": "GPIO",
+ "selectpin": "端子の選択",
+ "resistor": "抵抗",
+ "readinitial": "デプロイや再起動時に端子の初期状態を読み込む",
+ "type": "出力形式",
+ "initpin": "端子の状態を初期化",
+ "debounce": "デバウンス",
+ "freq": "頻度",
+ "button": "ボタン",
+ "pimouse": "Pi Mouse",
+ "pikeyboard": "Pi Keyboard",
+ "left": "Left",
+ "right": "Right",
+ "middle": "Middle"
+ },
+ "resistor": {
+ "none": "なし",
+ "pullup": "プルアップ",
+ "pulldown": "プルダウン"
+ },
"digout": "デジタル出力",
- "input": "入力",
- "pullup": "プルアップの入力",
- "pulldown": "プルダウンの入力",
"pwmout": "PWM出力",
- "servo": "サーボ出力"
- },
- "status": {
- "stopped": "停止",
- "closed": "切断",
- "not-running": "停止中",
- "not-available": "利用不可",
- "na": "N/A : __value__",
- "ok": "OK"
- },
- "errors": {
- "ignorenode": "Raspberry Pi固有のノードを無視しました",
- "version": "バージョンコマンドが失敗しました",
- "sawpitype": "Saw Pi Type",
- "libnotfound": "RPi.GPIO pythonライブラリを見つけられませんでした",
- "alreadyset": "GPIO端子 __pin__ は既に出力形式が設定されています: __type__",
- "invalidpin": "GPIO端子が不正です",
- "invalidinput": "入力が不正です",
- "needtobeexecutable": "__command__ は実行可能である必要があります",
- "mustbeexecutable": "nrgpio は実行可能である必要があります",
- "commandnotfound": "nrgpio コマンドが見つかりません",
- "commandnotexecutable": "nrgpio コマンドが実行可能ではありません",
- "error": "エラー: __error__",
- "pythoncommandnotfound": "nrgpio python コマンドが実行されていません"
+ "servo": "サーボ出力",
+ "initpin0": "端子の初期レベル - Low (0)",
+ "initpin1": "端子の初期レベル - High (1)",
+ "left": "左",
+ "right": "右",
+ "middle": "中間",
+ "any": "全て",
+ "pinname": "端子",
+ "alreadyuse": "使用中",
+ "alreadyset": "設定済",
+ "tip": {
+ "pin": "使用中の端子: ",
+ "in": "注釈: 入力値は、0または1の数値のみ対応しています。",
+ "dig": "注釈: 「出力形式」として「デジタル出力」を用いる場合、入力値は0または1の数値である必要があります。",
+ "pwm": "注釈: 「出力形式」として「PWM出力」を用いる場合、入力値は0~100の数値である必要があります。",
+ "ser": "注釈: サーボ出力向け - 入力値は0~100の間である必要があります。50が中心値です。"
+ },
+ "types": {
+ "digout": "デジタル出力",
+ "input": "入力",
+ "pullup": "プルアップの入力",
+ "pulldown": "プルダウンの入力",
+ "pwmout": "PWM出力",
+ "servo": "サーボ出力"
+ },
+ "status": {
+ "stopped": "停止",
+ "closed": "切断",
+ "not-running": "停止中",
+ "not-available": "利用不可",
+ "na": "N/A : __value__",
+ "ok": "OK"
+ },
+ "errors": {
+ "ignorenode": "Raspberry Pi固有のノードを無視しました",
+ "version": "バージョンコマンドが失敗しました",
+ "sawpitype": "Saw Pi Type",
+ "libnotfound": "RPi.GPIO pythonライブラリを見つけられませんでした",
+ "alreadyset": "GPIO端子 __pin__ は既に出力形式が設定されています: __type__",
+ "invalidpin": "GPIO端子が不正です",
+ "invalidinput": "入力が不正です",
+ "needtobeexecutable": "__command__ は実行可能である必要があります",
+ "mustbeexecutable": "nrgpio は実行可能である必要があります",
+ "commandnotfound": "nrgpio コマンドが見つかりません",
+ "commandnotexecutable": "nrgpio コマンドが実行可能ではありません",
+ "error": "エラー: __error__",
+ "pythoncommandnotfound": "nrgpio python コマンドが実行されていません"
+ }
}
}
diff --git a/hardware/PiGpio/package.json b/hardware/PiGpio/package.json
index 9e74c11f..708ef257 100644
--- a/hardware/PiGpio/package.json
+++ b/hardware/PiGpio/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-pi-gpio",
- "version": "1.0.8",
+ "version": "1.0.9",
"description": "The basic Node-RED node for Pi GPIO",
"dependencies" : {
},
diff --git a/utility/group/LICENSE b/utility/group/LICENSE
new file mode 100644
index 00000000..f5b60114
--- /dev/null
+++ b/utility/group/LICENSE
@@ -0,0 +1,14 @@
+Copyright 2016 JS Foundation and other contributors, https://js.foundation/
+Copyright 2013-2016 IBM Corp.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/utility/group/README.md b/utility/group/README.md
new file mode 100644
index 00000000..4c6f56e2
--- /dev/null
+++ b/utility/group/README.md
@@ -0,0 +1,25 @@
+node-red-node-group
+===================
+
+A Node-RED node to allow flows containing groups to be imported into older versions
+of Node-RED.
+
+The ability to create groups was introduced in Node-RED 1.1.0, adding a new core
+node type called `group`.
+
+This module provides its own `group` node type that can be installed into older
+versions of Node-RED to allow them to run flows containing that type.
+
+It does *not* provide any group-like functionality - it *only* registers a
+placeholder `group` node type.
+
+The module will only register the type if it detects it is being loaded into
+Node-RED 1.0.x or older, otherwise it does nothing.
+
+
+Install
+-------
+
+Run the following command in your Node-RED user directory - typically `~/.node-red`
+
+ npm i node-red-node-group
diff --git a/utility/group/group.html b/utility/group/group.html
new file mode 100644
index 00000000..d002ba40
--- /dev/null
+++ b/utility/group/group.html
@@ -0,0 +1,39 @@
+
+
+
+
+
diff --git a/utility/group/group.js b/utility/group/group.js
new file mode 100644
index 00000000..f976d2f4
--- /dev/null
+++ b/utility/group/group.js
@@ -0,0 +1,16 @@
+
+module.exports = function(RED) {
+ var version = RED.version();
+ var parts = /^(\d)+\.(\d)+\.(\d)+/.exec(version);
+ if (parts) {
+ var major = parseInt(parts[1]);
+ var minor = parseInt(parts[2]);
+ if (major > 1 || (major === 1 && minor > 0)) {
+ throw new Error("This module is not required for Node-RED 1.1.0 or later")
+ }
+ }
+ function GroupPolyfillNode(n) {
+ RED.nodes.createNode(this,n);
+ }
+ RED.nodes.registerType("group",GroupPolyfillNode);
+}
diff --git a/utility/group/package.json b/utility/group/package.json
new file mode 100644
index 00000000..fb88571e
--- /dev/null
+++ b/utility/group/package.json
@@ -0,0 +1,20 @@
+{
+ "name": "node-red-node-group",
+ "version": "1.0.0",
+ "description": "A Node-RED node to allow flows containing groups to be imported into Node-RED 1.0.x or earlier.",
+ "dependencies": {},
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/node-red/node-red-nodes/tree/master/utility/group"
+ },
+ "license": "Apache-2.0",
+ "keywords": [
+ "node-red"
+ ],
+ "node-red": {
+ "nodes": {
+ "group": "group.js"
+ }
+ },
+ "author": "Nick O'Leary "
+}
From 03514410755ef26b06c6331d592a6d27609bfea7 Mon Sep 17 00:00:00 2001
From: Marco <53404825+gre000@users.noreply.github.com>
Date: Fri, 10 Apr 2020 23:53:17 +0200
Subject: [PATCH 355/456] MySQL allows to pass named parameters as object
(#565)
* add check isobj
* added example to readme.md
* edit if Syntax
* add Documentation link to readme.md
* fixed Syntax and edit readme.md
---
storage/mysql/68-mysql.js | 18 +++++++++++++++++-
storage/mysql/README.md | 23 +++++++++++++++++++++++
2 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/storage/mysql/68-mysql.js b/storage/mysql/68-mysql.js
index 95444e7f..c14ecccc 100644
--- a/storage/mysql/68-mysql.js
+++ b/storage/mysql/68-mysql.js
@@ -123,7 +123,23 @@ module.exports = function(RED) {
node.on("input", function(msg) {
if (node.mydbConfig.connected) {
if (typeof msg.topic === 'string') {
- var bind = Array.isArray(msg.payload) ? msg.payload : [];
+ //console.log("query:",msg.topic);
+ var bind = [];
+ if (Array.isArray(msg.payload)) { bind = msg.payload; }
+ else if (typeof msg.payload === 'object' && msg.payload !== null) {
+ bind=msg.payload;
+ node.mydbConfig.connection.config.queryFormat = function (query, values) {
+ if (!values){
+ return query;
+ }
+ return query.replace(/\:(\w+)/g, function (txt, key) {
+ if (values.hasOwnProperty(key)) {
+ return this.escape(values[key]);
+ }
+ return txt;
+ }.bind(this));
+ };
+ }
node.mydbConfig.connection.query(msg.topic, bind, function(err, rows) {
if (err) {
status = {fill:"red",shape:"ring",text:"Error: "+err.code};
diff --git a/storage/mysql/README.md b/storage/mysql/README.md
index 0af76eba..015adf0c 100644
--- a/storage/mysql/README.md
+++ b/storage/mysql/README.md
@@ -27,3 +27,26 @@ If nothing is found for the key then null is returned.
The reconnect retry timeout in milliseconds can be changed by adding a line to settings.js
mysqlReconnectTime: 30000,
+
+
+Preparing Queries
+-----
+```javascript
+msg.payload=[24, 'example-user'];
+msg.topic="INSERT INTO users (`userid`, `username`) VALUES (?, ?);"
+return msg;
+```
+
+with named parameters:
+
+```javascript
+msg.payload={}
+msg.payload.userToChange=42;
+msg.payload.newUsername="example-user";
+msg.topic="INSERT INTO users (`userid`, `username`) VALUES (:userToChange, :newUsername) ON DUPLICATE KEY UPDATE `username`=:newUsername;"
+return msg;
+```
+Documentation
+-----
+
+Documentation of the used Node.js package
From 397b7cdaec7cafb3ef420f1ad33c9bde979c85ab Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Fri, 10 Apr 2020 22:56:28 +0100
Subject: [PATCH 356/456] bump mysql thanks to PR
---
storage/mysql/package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/storage/mysql/package.json b/storage/mysql/package.json
index 1bad178a..496fdd60 100644
--- a/storage/mysql/package.json
+++ b/storage/mysql/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-mysql",
- "version": "0.0.22",
+ "version": "0.1.0",
"description": "A Node-RED node to read and write to a MySQL database",
"dependencies": {
"mysql": "^2.18.1"
From 436f169fd436433d848ea7ddaf1c4538ed10b9b3 Mon Sep 17 00:00:00 2001
From: Ben Hardill
Date: Sat, 11 Apr 2020 10:47:47 +0100
Subject: [PATCH 357/456] More Wemo update (#631)
* Reduce resubscription time
Halve the resubscrciption timeout to make sure event
subscriptions get renewed
* Big Update
Includes:
- New lookup node to check state of a device
- Fix dimming control for lights
- Fix light group control
- Set the node label to match the device name
- The event now includes the text description of the light capability
* Fix groups properly
* Fix travis error with comparitor
* Bump node-ssdp version
* Add extra check for empty results in discovery
* Bump twitter to 280 chars
fixes #371
* Bump twitter node version
* Remove extra whitespace
* Add catch for HTTP timeout
If the device drops off line then with no catch for the timeout
Node-RED will crash
Should fix #616
* More timeout catch blocks
* Version bump
* Bump Wemo version
---
hardware/wemo/lib/wemo.js | 29 ++++++++++++++++++++---------
hardware/wemo/package.json | 2 +-
2 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/hardware/wemo/lib/wemo.js b/hardware/wemo/lib/wemo.js
index 2e8d6f9b..acb6fc5c 100644
--- a/hardware/wemo/lib/wemo.js
+++ b/hardware/wemo/lib/wemo.js
@@ -215,6 +215,10 @@ WeMoNG.prototype.start = function start() {
});
});
+ post_request.on('timeout', function(){
+ post_request.abort();
+ });
+
post_request.write(util.format(getenddevs.body, udn));
post_request.end();
@@ -291,9 +295,9 @@ WeMoNG.prototype.toggleSocket = function toggleSocket(socket, on) {
console.log("%j", postoptions);
});
- post_request.on('timeout', function (e) {
- console.log(e);
- console.log("%j");
+ post_request.on('timeout', function () {
+ console.log("Timeout");
+ post_request.abort();
});
var body = [
@@ -347,6 +351,11 @@ WeMoNG.prototype.getSocketStatus = function getSocketStatus(socket) {
def.reject();
});
+ post_request.on('timeout', function(){
+ post_request.abort();
+ def.reject();
+ });
+
post_request.write(getSocketState.body);
post_request.end();
@@ -409,9 +418,9 @@ WeMoNG.prototype.getLightStatus = function getLightStatus(light) {
def.reject();
});
- post_request.on('timeout', function (e) {
- console.log(e);
- console.log("%j");
+ post_request.on('timeout', function () {
+ console.log("Timeout");
+ post_request.abort();
def.reject();
});
@@ -451,9 +460,9 @@ WeMoNG.prototype.setStatus = function setStatus(light, capability, value) {
console.log("%j", postoptions);
});
- post_request.on('timeout', function (e) {
- console.log(e);
- console.log("%j");
+ post_request.on('timeout', function () {
+ console.log("Timeout");
+ post_request.abort();
});
//console.log(util.format(setdevstatus.body, light.id, capability, value));
@@ -493,9 +502,11 @@ WeMoNG.prototype.parseEvent = function parseEvent(evt) {
def.resolve(msg);
} else {
console.log("unhandled wemo event type \n%s", util.inspect(prop, {depth:null}));
+
}
} else {
//error
+ def.reject();
}
});
diff --git a/hardware/wemo/package.json b/hardware/wemo/package.json
index fd668081..b116b9a6 100644
--- a/hardware/wemo/package.json
+++ b/hardware/wemo/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-node-wemo",
- "version": "0.1.16",
+ "version": "0.1.17",
"description": "Input and Output nodes for Belkin WeMo devices",
"repository": "https://github.com/node-red/node-red-nodes/tree/master/hardware",
"main": "WeMoNG.js",
From 92adb10fb347849e9c14f241081158378445423f Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Fri, 17 Apr 2020 09:43:45 +0100
Subject: [PATCH 358/456] pushover: ensure handles missing payload.
---
social/pushover/57-pushover.js | 1 +
social/pushover/package.json | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/social/pushover/57-pushover.js b/social/pushover/57-pushover.js
index cbfbe3e0..dd020f9e 100644
--- a/social/pushover/57-pushover.js
+++ b/social/pushover/57-pushover.js
@@ -42,6 +42,7 @@ module.exports = function(RED) {
if (isNaN(pri)) {pri=0;}
if (pri > 2) {pri = 2;}
if (pri < -2) {pri = -2;}
+ if (!msg.payload) { msg.payload = ""; }
if (typeof(msg.payload) === 'object') {
msg.payload = JSON.stringify(msg.payload);
}
diff --git a/social/pushover/package.json b/social/pushover/package.json
index b7cb0b96..6fa315e0 100644
--- a/social/pushover/package.json
+++ b/social/pushover/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-pushover",
- "version" : "0.0.17",
+ "version" : "0.0.18",
"description" : "A Node-RED node to send alerts via Pushover",
"dependencies" : {
"pushover-notifications" : "^1.2.1"
From 667c7588f95400acf7a1f7c89ae34914fd00e3f4 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Sat, 18 Apr 2020 13:55:57 +0100
Subject: [PATCH 359/456] Add offsets to suncalc node.
---
time/suncalc/79-suncalc.html | 17 +++++++++++++++--
time/suncalc/79-suncalc.js | 10 +++++++---
time/suncalc/README.md | 9 ++++++---
time/suncalc/package.json | 2 +-
4 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/time/suncalc/79-suncalc.html b/time/suncalc/79-suncalc.html
index 2776a656..47cd4d77 100644
--- a/time/suncalc/79-suncalc.html
+++ b/time/suncalc/79-suncalc.html
@@ -30,6 +30,11 @@
+
+
+ start mins
+ end mins
+
@@ -39,9 +44,11 @@
diff --git a/time/suncalc/79-suncalc.js b/time/suncalc/79-suncalc.js
index 6ce278b6..905ff846 100644
--- a/time/suncalc/79-suncalc.js
+++ b/time/suncalc/79-suncalc.js
@@ -9,6 +9,8 @@ module.exports = function(RED) {
this.lon = n.lon;
this.start = n.start;
this.end = n.end;
+ this.soff = (n.soff || 0) * 60000; // minutes
+ this.eoff = (n.eoff || 0) * 60000; // minutes
var node = this;
var oldval = null;
@@ -19,12 +21,14 @@ module.exports = function(RED) {
var nowMillis = Date.UTC(now.getUTCFullYear(),now.getUTCMonth(),now.getUTCDate(),now.getUTCHours(),now.getUTCMinutes());
var startMillis = Date.UTC(times[node.start].getUTCFullYear(),times[node.start].getUTCMonth(),times[node.start].getUTCDate(),times[node.start].getUTCHours(),times[node.start].getUTCMinutes());
var endMillis = Date.UTC(times[node.end].getUTCFullYear(),times[node.end].getUTCMonth(),times[node.end].getUTCDate(),times[node.end].getUTCHours(),times[node.end].getUTCMinutes());
- var e1 = nowMillis - startMillis;
- var e2 = nowMillis - endMillis;
+ var e1 = nowMillis - startMillis - node.soff;
+ var e2 = nowMillis - endMillis - node.eoff;
+ var s1 = new Date(startMillis + node.soff);
+ var s2 = new Date(endMillis + node.eoff);
if (isNaN(e1)) { e1 = 1; }
if (isNaN(e2)) { e2 = -1; }
var moon = parseInt(SunCalc.getMoonIllumination(now).fraction * 100 + 0.5) / 100;
- var msg = {payload:0, topic:"sun", moon:moon};
+ var msg = {payload:0, topic:"sun", moon:moon, start:s1, end:s2, now:now};
if ((e1 > 0) & (e2 < 0)) { msg.payload = 1; }
if (oldval == null) { oldval = msg.payload; }
if (msg.payload == 1) { node.status({fill:"yellow",shape:"dot",text:"day"}); }
diff --git a/time/suncalc/README.md b/time/suncalc/README.md
index 51de9d25..dac87938 100644
--- a/time/suncalc/README.md
+++ b/time/suncalc/README.md
@@ -6,11 +6,10 @@ A Node-RED node to provide a sign
Install
-------
-Run the following command in your Node-RED user directory - typically `~/.node-red`
+Either use the `Node-RED Menu - Manage Palette - Install`, or run the following command in your Node-RED user directory - typically `~/.node-red`
npm install node-red-node-suncalc
-
Usage
-----
@@ -19,10 +18,14 @@ Uses the suncalc npm to generate an output at sunrise and sunset based on a spec
Several choices of definition of sunrise and sunset are available, see the
suncalc module for details.
+The start and end times can be offset by a number of minutes before (minus) or after (plus) the chosen event time.
+
The node provide two outputs. The first output emits a `msg.payload` of 1 or 0 every minute
depending if day-time (1) or night-time (0).
The second output emits only on the transition between night to day (-> 1) or day to night (-> 0).
-It also sets the `msg.topic` to sun and `msg.moon` to the fraction of the moon currently visible
+It also outputs msg.start, msg.end and msg.now which are todays start and end times, with offsets applied, in ISO format, and the current ISO time.
+
+The `msg.topic` is set to sun, and `msg.moon` to the fraction of the moon currently visible
(a value between 0 for no moon and 1 for full moon).
diff --git a/time/suncalc/package.json b/time/suncalc/package.json
index ecb27bcf..cf675cac 100644
--- a/time/suncalc/package.json
+++ b/time/suncalc/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red-node-suncalc",
- "version" : "0.1.0",
+ "version" : "0.2.0",
"description" : "A Node-RED node to provide a signal at sunrise and sunset",
"dependencies" : {
"suncalc" : "^1.8.0"
From 4641d10beb6d98c34a7a11436d27bf3ebfd14860 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Sat, 18 Apr 2020 18:03:59 +0100
Subject: [PATCH 360/456] mysql: add charset option (defaults as-is to old
UTF8)
---
storage/mysql/68-mysql.html | 15 ++++++++++++---
storage/mysql/68-mysql.js | 6 ++++--
storage/mysql/README.md | 21 ++++++++++++++-------
storage/mysql/package.json | 2 +-
4 files changed, 31 insertions(+), 13 deletions(-)
diff --git a/storage/mysql/68-mysql.html b/storage/mysql/68-mysql.html
index 075fb6f7..37dca22d 100644
--- a/storage/mysql/68-mysql.html
+++ b/storage/mysql/68-mysql.html
@@ -24,6 +24,10 @@