mirror of
https://github.com/node-red/node-red-nodes.git
synced 2023-10-10 13:36:58 +02:00
Merge branch 'master' of github.com:node-red/node-red-nodes
This commit is contained in:
commit
1f34239fbb
@ -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
|
||||
|
@ -9,15 +9,17 @@ Install
|
||||
Run the following command in your Node-RED user directory - typically `~/.node-red`
|
||||
|
||||
npm install node-red-node-random
|
||||
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
A simple node to generate a random number when triggered.
|
||||
|
||||
If integer mode is selected (default) it will return an integer **between and including** the two values given - so selecting 1 to 6 will return values 1,2,3,4,5 or 6.
|
||||
If you return an integer it can include both the low and high values.
|
||||
`min <= n <= max` - so selecting 1 to 6 will return values 1,2,3,4,5 or 6.
|
||||
|
||||
If floating point mode is selected then it will return a number **between** the two values given - so selecting 1 to 6 will return values 1 < x < 6 .
|
||||
If you return a floating point value it will be from the low value, up to, but
|
||||
not including the high value. `min <= n < max` - so selecting 1 to 6 will return values 1 <= n < 6 .
|
||||
|
||||
**Note:** This generates **numbers**.
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name" : "node-red-node-random",
|
||||
"version" : "0.1.0",
|
||||
"version" : "0.1.2",
|
||||
"description" : "A Node-RED node that when triggered generates a random number between two values.",
|
||||
"dependencies" : {
|
||||
},
|
||||
|
@ -28,8 +28,10 @@
|
||||
70%
|
||||
<script type="text/x-red" data-help-name="random">
|
||||
<p>Generates a random number between a low and high value.</p>
|
||||
<p>If you return an integer it can <i>include</i> both the low and high values.</p>
|
||||
<p>If you return a floating point value it will be <i>between</i> the low and high values.</p>
|
||||
<p>If you return an integer it can <i>include</i> both the low and high values.
|
||||
<code>min <= n <= max</code></p>
|
||||
<p>If you return a floating point value it will be from the low value, up to, but
|
||||
not including the high value. <code>min <= n < max</code></p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
@ -11,10 +11,10 @@ module.exports = function(RED) {
|
||||
this.on("input", function(msg) {
|
||||
var value;
|
||||
if (node.inte == "true" || node.inte === true) {
|
||||
value = Math.round(Number(Math.random()) * (node.high - node.low + 1) + node.low - 0.5);
|
||||
value = Math.round(Math.random() * (node.high - node.low + 1) + node.low - 0.5);
|
||||
}
|
||||
else {
|
||||
value = Number(Math.random()) * (node.high - node.low) + node.low;
|
||||
value = Math.random() * (node.high - node.low) + node.low;
|
||||
}
|
||||
RED.util.setMessageProperty(msg,node.property,value);
|
||||
node.send(msg);
|
||||
|
@ -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.
|
||||
|
@ -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",
|
||||
|
@ -33,6 +33,13 @@
|
||||
<option value=1>CE1</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-bus"><i class="fa fa-toggle-on"></i> SPI bus</label>
|
||||
<select type="text" id="node-input-bus" style="width:150px;">
|
||||
<option value=0>0</option>
|
||||
<option value=1>1</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name"/>
|
||||
@ -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,
|
||||
|
@ -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<chans; i++) {
|
||||
if (node.dev === "3002") { mcp3xxx.push(mcpadc.openMcp3002(i, opt, cb)); }
|
||||
|
0
hardware/neopixel/neopixel.html
Executable file → Normal file
0
hardware/neopixel/neopixel.html
Executable file → Normal file
2
hardware/neopixel/neopixel.js
Executable file → Normal file
2
hardware/neopixel/neopixel.js
Executable file → Normal file
@ -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;
|
||||
}
|
||||
|
2
hardware/neopixel/package.json
Executable file → Normal file
2
hardware/neopixel/package.json
Executable file → Normal file
@ -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" : {
|
||||
},
|
||||
|
@ -2,7 +2,7 @@
|
||||
module.exports = function(RED) {
|
||||
"use strict";
|
||||
var wol = require('wake_on_lan');
|
||||
var chk = /^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$/;
|
||||
var chk = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/;
|
||||
|
||||
function WOLnode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
@ -17,9 +17,13 @@ module.exports = function(RED) {
|
||||
if (chk.test(mac)) {
|
||||
try {
|
||||
wol.wake(mac, {address: host}, function(error) {
|
||||
if (error) { node.warn(error); }
|
||||
if (error) {
|
||||
node.warn(error);
|
||||
node.status({fill:"red",shape:"ring",text:" "});
|
||||
}
|
||||
else if (RED.settings.verbose) {
|
||||
node.log("sent WOL magic packet");
|
||||
node.status({fill:"green",shape:"dot",text:" "});
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -31,6 +35,10 @@ module.exports = function(RED) {
|
||||
}
|
||||
else { node.warn("WOL: no mac address specified"); }
|
||||
});
|
||||
|
||||
this.on("close", function () {
|
||||
node.status({});
|
||||
})
|
||||
}
|
||||
RED.nodes.registerType("wake on lan",WOLnode);
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"name" : "node-red-node-wol",
|
||||
"version" : "0.0.8",
|
||||
"version" : "0.0.9",
|
||||
"description" : "A Node-RED node to send Wake-On-LAN (WOL) magic packets",
|
||||
"dependencies" : {
|
||||
"wake_on_lan" : "0.0.4"
|
||||
"wake_on_lan" : "1.0.0"
|
||||
},
|
||||
"repository" : {
|
||||
"type":"git",
|
||||
|
2857
package-lock.json
generated
2857
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
24
package.json
24
package.json
@ -32,30 +32,30 @@
|
||||
],
|
||||
"devDependencies": {
|
||||
"exif": "^0.6.0",
|
||||
"grunt": "~1.0.3",
|
||||
"grunt-cli": "^1.2.0",
|
||||
"grunt-contrib-jshint": "^1.1.0",
|
||||
"grunt": "^1.0.3",
|
||||
"grunt-cli": "^1.3.1",
|
||||
"grunt-contrib-jshint": "^2.0.0",
|
||||
"grunt-jscs": "^3.0.1",
|
||||
"grunt-lint-inline": "^1.0.0",
|
||||
"grunt-simple-mocha": "^0.4.1",
|
||||
"imap": "^0.8.19",
|
||||
"mailparser": "^0.6.2",
|
||||
"mocha": "~5.1.1",
|
||||
"mailparser-mit": "^0.6.2",
|
||||
"mocha": "^5.2.0",
|
||||
"msgpack-lite": "^0.1.26",
|
||||
"multilang-sentiment": "^1.1.6",
|
||||
"ngeohash": "^0.6.0",
|
||||
"node-red": "*",
|
||||
"node-red-node-test-helper": "*",
|
||||
"nodemailer": "~4.6.7",
|
||||
"nodemailer": "^4.6.8",
|
||||
"poplib": "^0.1.7",
|
||||
"proxyquire": "^2.0.1",
|
||||
"pushbullet": "~2.2.0",
|
||||
"should": "~13.2.3",
|
||||
"sinon": "~5.0.10",
|
||||
"supertest": "~3.1.0",
|
||||
"proxyquire": "^2.1.0",
|
||||
"pushbullet": "^2.3.0",
|
||||
"should": "^13.2.3",
|
||||
"sinon": "^6.3.4",
|
||||
"supertest": "^3.3.0",
|
||||
"when": "^3.7.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,10 @@
|
||||
<input type="password" id="node-input-password">
|
||||
</div>
|
||||
<br/>
|
||||
<div class="form-row">
|
||||
<label for="node-input-useTLS"><i class="fa fa-lock"></i> <span data-i18n="email.label.useTLS"></label>
|
||||
<input type="checkbox" id="node-input-tls" style="display:inline-block; width:20px; vertical-align:baseline;">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-dname"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
|
||||
<input type="text" id="node-input-dname" data-i18n="[placeholder]node-red:common.label.name">
|
||||
@ -69,6 +73,7 @@
|
||||
<p>Alternatively you may provide <code>msg.attachments</code> which should contain an array of one or
|
||||
more attachments in <a href="https://www.npmjs.com/package/nodemailer#attachments" target="_new">nodemailer</a> format.</p>
|
||||
<p>If required by your recipient you may also pass in a <code>msg.envelope</code> object, typically containing extra from and to properties.</p>
|
||||
<p>If you have own signed certificates, Nodemailer can complain about that and refuse sending the message. In this case you can try switching off TLS.</p>
|
||||
<p>Note: uses SMTP with SSL to port 465.</p>
|
||||
</script>
|
||||
|
||||
@ -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:""}
|
||||
},
|
||||
|
@ -14,9 +14,13 @@ module.exports = function(RED) {
|
||||
var nodemailer = require("nodemailer");
|
||||
var Imap = require('imap');
|
||||
var POP3Client = require("poplib");
|
||||
var MailParser = require("mailparser").MailParser;
|
||||
var MailParser = require("mailparser-mit").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");
|
||||
}
|
||||
@ -30,6 +34,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 +55,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) {
|
||||
@ -185,7 +194,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;
|
||||
@ -193,9 +202,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 = []; }
|
||||
@ -221,6 +230,7 @@ module.exports = function(RED) {
|
||||
function nextMessage() {
|
||||
if (currentMessage > maxMessage) {
|
||||
pop3Client.quit();
|
||||
setInputRepeatTimeout();
|
||||
return;
|
||||
}
|
||||
pop3Client.retr(currentMessage);
|
||||
@ -243,6 +253,7 @@ module.exports = function(RED) {
|
||||
});
|
||||
|
||||
pop3Client.on("error", function(err) {
|
||||
setInputRepeatTimeout();
|
||||
node.log("error: " + JSON.stringify(err));
|
||||
});
|
||||
|
||||
@ -258,6 +269,7 @@ module.exports = function(RED) {
|
||||
} else {
|
||||
node.log(util.format("login error: %s %j", status, rawData));
|
||||
pop3Client.quit();
|
||||
setInputRepeatTimeout();
|
||||
}
|
||||
});
|
||||
|
||||
@ -279,6 +291,7 @@ module.exports = function(RED) {
|
||||
else {
|
||||
node.log(util.format("retr error: %s %j", status, rawData));
|
||||
pop3Client.quit();
|
||||
setInputRepeatTimeout();
|
||||
}
|
||||
});
|
||||
|
||||
@ -318,6 +331,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);
|
||||
@ -325,6 +339,7 @@ module.exports = function(RED) {
|
||||
//console.log(" [X] - Nothing to fetch");
|
||||
node.status({});
|
||||
imap.end();
|
||||
setInputRepeatTimeout();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -372,10 +387,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
|
||||
@ -419,16 +436,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",{});
|
||||
|
@ -1,7 +1,7 @@
|
||||
node-red-node-email
|
||||
===================
|
||||
|
||||
<a href="http://nodered.org" target="_new">Node-RED</a> nodes to send and receive simple emails.
|
||||
<a href="http://nodered.org" target="info">Node-RED</a> 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
|
||||
@ -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.
|
||||
|
@ -13,6 +13,7 @@
|
||||
"folder": "Folder",
|
||||
"protocol": "Protocol",
|
||||
"useSSL": "Use SSL?",
|
||||
"useTLS": "Use TLS?",
|
||||
"disposition": "Disposition",
|
||||
"none": "None",
|
||||
"read": "Mark Read",
|
||||
|
@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "node-red-node-email",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.4",
|
||||
"description": "Node-RED nodes to send and receive simple emails",
|
||||
"dependencies": {
|
||||
"imap": "^0.8.19",
|
||||
"mailparser": "^0.6.2",
|
||||
"nodemailer": "^4.6.4",
|
||||
"mailparser-mit": "^0.6.2",
|
||||
"nodemailer": "^4.6.8",
|
||||
"poplib": "^0.1.7"
|
||||
},
|
||||
"repository": {
|
||||
@ -30,6 +30,6 @@
|
||||
"url": "http://nodered.org"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ module.exports = function(RED) {
|
||||
var req = request(node.url, {timeout:10000, pool:false});
|
||||
//req.setMaxListeners(50);
|
||||
req.setHeader('user-agent', 'Mozilla/5.0 (Node-RED)');
|
||||
req.setHeader('accept', 'text/html,application/xhtml+xml');
|
||||
req.setHeader('accept', 'application/rss+xml,text/html,application/xhtml+xml');
|
||||
|
||||
var feedparser = new FeedParser();
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "node-red-node-feedparser",
|
||||
"version": "0.1.13",
|
||||
"version": "0.1.14",
|
||||
"description": "A Node-RED node to get RSS Atom feeds.",
|
||||
"dependencies": {
|
||||
"feedparser": "^2.2.9",
|
||||
"request": "^2.83.0"
|
||||
"request": "^2.88.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="notify">
|
||||
<script type="text/x-red" data-template-name="nnotify">
|
||||
<div class="form-row">
|
||||
<label for="node-input-title"><i class="fa fa-flag"></i> Title</label>
|
||||
<input type="text" id="node-input-title" placeholder="Node-RED">
|
||||
@ -10,15 +10,15 @@
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="notify">
|
||||
<p>Uses Growl to provide a desktop popup containing the <code>msg.payload</code>. Only useful on the local machine.</p>
|
||||
<p>Optionally uses <code>msg.topic</code> as the title.</p>
|
||||
<p>Uses Growl so should work cross platform but will need pre-reqs installed... see <i><a href="https://npmjs.org/package/growl" target="_new">this link.</a></i></p>
|
||||
<p>If installing on Windows you MUST read the install instructions ... especially the bit about adding growlnotify to your path... or it WILL NOT work.</p>
|
||||
<script type="text/x-red" data-help-name="nnotify">
|
||||
<p>Uses node-notifier to provide a desktop popup containing the <code>msg.payload</code>. Only useful on the local machine.</p>
|
||||
<p>Optionally uses <code>msg.topic</code> as the title, and <code>msg.icon</code> as the full path to an icon file to display.</p>
|
||||
<p>Uses node-notifier so should work cross platform but may need to intall pre-reqs... see <i><a href="https://www.npmjs.com/package/node-notifier" target="_new">this link.</a></i></p>
|
||||
<p>If installing on Windows you MUST read the install instructions... or it WILL NOT work.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('notify',{
|
||||
RED.nodes.registerType('nnotify',{
|
||||
category: 'output',
|
||||
defaults: {
|
||||
title: {value:""},
|
||||
@ -29,6 +29,7 @@
|
||||
outputs:0,
|
||||
icon: "alert.png",
|
||||
align: "right",
|
||||
paletteLabel: "notify",
|
||||
label: function() {
|
||||
return this.name||this.title||"notify";
|
||||
},
|
||||
|
@ -1,26 +1,35 @@
|
||||
|
||||
module.exports = function(RED) {
|
||||
"use strict";
|
||||
var growl = require('growl');
|
||||
var imagefile = process.env.NODE_RED_HOME+"/public/node-red.png";
|
||||
var notifier = require('node-notifier');
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var image = path.join(__dirname, "/node-red.png");
|
||||
|
||||
function NotifyNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.title = n.title;
|
||||
var node = this;
|
||||
|
||||
node.on("input",function(msg) {
|
||||
var titl = node.title || msg.topic;
|
||||
if (typeof(msg.payload) == 'object') {
|
||||
var title = node.title || msg.topic;
|
||||
if (typeof msg.payload === 'object') {
|
||||
msg.payload = JSON.stringify(msg.payload);
|
||||
}
|
||||
if (typeof(titl) != 'undefined') {
|
||||
growl(msg.payload, { title: titl, image: imagefile });
|
||||
var icon = image;
|
||||
if (msg.icon) {
|
||||
if (fs.existsSync(msg.icon)) { icon = msg.icon; }
|
||||
else { node.error("Bad Icon file: "+msg.icon,msg); }
|
||||
}
|
||||
var icon = msg.icon || image;
|
||||
if (typeof(title) !== 'undefined') {
|
||||
notifier.notify({ message:msg.payload, title:title, icon:icon });
|
||||
}
|
||||
else {
|
||||
growl(msg.payload, { image: imagefile });
|
||||
notifier.notify({ message:msg.payload, icon:imagefile });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType("notify",NotifyNode);
|
||||
RED.nodes.registerType("nnotify",NotifyNode);
|
||||
}
|
||||
|
BIN
social/notify/node-red.png
Normal file
BIN
social/notify/node-red.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1019 B |
@ -1,17 +1,17 @@
|
||||
{
|
||||
"name" : "node-red-node-notify",
|
||||
"version" : "0.0.5",
|
||||
"version" : "0.1.1",
|
||||
"description" : "A Node-RED node to send local popup Notify alerts",
|
||||
"dependencies" : {
|
||||
"growl" : "1.8.1"
|
||||
"node-notifier" : "5.2.1"
|
||||
},
|
||||
"repository" : {
|
||||
"type":"git",
|
||||
"url":"https://github.com/node-red/node-red-nodes.git",
|
||||
"path":"/tree/master/social/growl"
|
||||
"path":"/tree/master/social/notify"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"keywords": [ "node-red", "growl", "notify"],
|
||||
"keywords": [ "node-red", "notify", "growl"],
|
||||
"node-red" : {
|
||||
"nodes" : {
|
||||
"notify": "57-notify.js"
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"name" : "node-red-node-pushbullet",
|
||||
"version" : "0.0.13",
|
||||
"version" : "0.0.14",
|
||||
"description" : "A Node-RED node to send alerts via Pushbullet",
|
||||
"dependencies" : {
|
||||
"pushbullet": "~2.2.0",
|
||||
"pushbullet": "^2.3.0",
|
||||
"when": "^3.7.8"
|
||||
},
|
||||
"repository" : {
|
||||
|
@ -73,10 +73,15 @@
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="pushover">
|
||||
<p>Uses Pushover to push the <code>msg.payload</code> to a device that has the Pushover app installed.</p>
|
||||
<p>Optionally uses <code>msg.topic</code> to set the title, <code>msg.device</code> to set the device,
|
||||
<code>msg.priority</code> to set the priority, <code>msg.url</code> to add a web address and <code>msg.url_title</code>
|
||||
to add a url title if not already set in the properties.</p>
|
||||
<p>Uses Pushover to push the msg.payload to a device that has the Pushover app installed.</p>
|
||||
<br>
|
||||
<p>Optionally uses msg.topic to set the configuration:</p>
|
||||
<p><code>msg.topic</code>: set the title</p>
|
||||
<p><code>msg.device</code>: set the device</p>
|
||||
<p><code>msg.priority</code>: set the priority</p>
|
||||
<p><code>msg.url</code>: to add a web address</p>
|
||||
<p><code>msg.url_title</code>: to add a url title if not already set in the properties</p>
|
||||
<p><code>msg.sound</code>: set the notification sound, <i><a href="https://pushover.net/api#sounds" target="_new">see the available options</a></i></p>
|
||||
<p>Uses Pushover. See <i><a href="https://pushover.net" target="_new">this link</a></i> for more details.</p>
|
||||
</script>
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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 <code>msg.extension</code> property containing the full path and filename.
|
||||
|
||||
The reconnect timeout in milliseconds can be changed by adding a line to **settings.js**
|
||||
|
||||
sqliteReconnectTime: 20000,
|
||||
|
30
storage/sqlite/ext/half.c
Normal file
30
storage/sqlite/ext/half.c
Normal file
@ -0,0 +1,30 @@
|
||||
/* Add your header comment here */
|
||||
|
||||
#include <sqlite3ext.h>
|
||||
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;
|
||||
}
|
BIN
storage/sqlite/ext/half.dylib
Executable file
BIN
storage/sqlite/ext/half.dylib
Executable file
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "node-red-node-sqlite",
|
||||
"version": "0.3.2",
|
||||
"version": "0.3.5",
|
||||
"description": "A sqlite node for Node-RED",
|
||||
"dependencies": {
|
||||
"sqlite3": "^4.0.2"
|
||||
|
@ -77,6 +77,8 @@
|
||||
be sure to include $ on the parameter object key.</p>
|
||||
<p>Using any SQL Query, the result is returned in <code>msg.payload</code></p>
|
||||
<p>Typically the returned payload will be an array of the result rows, (or an error).</p>
|
||||
<p>You can load sqlite extensions by inputting a <code>msg.extension</code> property containing the full
|
||||
path and filename.</p>
|
||||
<p>The reconnect timeout in milliseconds can be changed by adding a line to <b>settings.js</b>
|
||||
<pre>sqliteReconnectTime: 20000,</pre></p>
|
||||
</script>
|
||||
|
@ -43,89 +43,107 @@ 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) {
|
||||
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);
|
||||
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);}
|
||||
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);
|
||||
node.status({fill:"red", shape:"dot",text:"msg.topic error"});
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
});
|
||||
if (node.sqlquery == "fixed"){
|
||||
if (typeof node.sql === 'string') {
|
||||
if (node.sql.length > 0) {
|
||||
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 (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 (err) { node.error(err,msg); }
|
||||
else {
|
||||
msg.payload = row;
|
||||
node.send(msg);
|
||||
}
|
||||
});
|
||||
if (node.sqlquery == "prepared"){
|
||||
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 (this.sql === null || this.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"});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -11,12 +11,17 @@
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label> </label>
|
||||
<input type="checkbox" id="node-input-cr" style="display: inline-block; width: auto; vertical-align: top;">
|
||||
<input type="checkbox" id="node-input-autorun" style="display:inline-block; width: auto; vertical-align:baseline;">
|
||||
<label for="node-input-autorun" style="width: 70%;">Auto-start daemon on deploy ?</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label> </label>
|
||||
<input type="checkbox" id="node-input-cr" style="display:inline-block; width:auto; vertical-align:baseline;">
|
||||
<label for="node-input-cr" style="width: 70%;">Add [enter] to every message sent ?</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label> </label>
|
||||
<input type="checkbox" id="node-input-redo" style="display: inline-block; width: auto; vertical-align: top;">
|
||||
<input type="checkbox" id="node-input-redo" style="display:inline-block; width:auto; vertical-align:baseline;">
|
||||
<label for="node-input-redo" style="width: 70%;">Relaunch command on exit or error ?</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
@ -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); }
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@ -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) {
|
||||
|
@ -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" : {
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user