Merge remote-tracking branch 'upstream/master'
77
99-sample.html.demo
Normal file
@ -0,0 +1,77 @@
|
||||
<!--
|
||||
Copyright 2013 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.
|
||||
-->
|
||||
|
||||
<!-- Sample html file that corresponds to the 99-sample.js file -->
|
||||
<!-- This creates and configures the onscreen elements of the node -->
|
||||
|
||||
<!-- If you use this as a template, replace IBM Corp. with your own name. -->
|
||||
|
||||
<!-- First, the content of the edit dialog is defined. -->
|
||||
|
||||
<script type="text/x-red" data-template-name="sample">
|
||||
<!-- data-template-name identifies the node type this is for -->
|
||||
|
||||
<!-- Each of the following divs creates a field in the edit dialog. -->
|
||||
<!-- Generally, there should be an input for each property of the node. -->
|
||||
<!-- The for and id attributes identify the corresponding property -->
|
||||
<!-- (with the 'node-input-' prefix). -->
|
||||
<!-- The available icon classes are defined in Twitter Bootstrap -->
|
||||
<div class="form-row">
|
||||
<label for="node-input-topic"><i class="icon-tasks"></i> Topic</label>
|
||||
<input type="text" id="node-input-topic" placeholder="Topic">
|
||||
</div>
|
||||
|
||||
<!-- By convention, most nodes have a 'name' property. The following div -->
|
||||
<!-- provides the necessary field. -->
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<!-- Next, some simple help text is provided for the node. -->
|
||||
<script type="text/x-red" data-help-name="sample">
|
||||
<!-- data-help-name identifies the node type this help is for -->
|
||||
<!-- This content appears in the Info sidebar when a node is selected -->
|
||||
<!-- The first <p> is used as the pop-up tool tip when hovering over a -->
|
||||
<!-- node in the palette. -->
|
||||
<p>Simple sample input node. Just sends a single message when it starts up.
|
||||
This is not very useful.</p>
|
||||
<p>Outputs an object called <b>msg</b> containing <b>msg.topic</b> and
|
||||
<b>msg.payload</b>. msg.payload is a String.</p>
|
||||
</script>
|
||||
|
||||
<!-- Finally, the node type is registered along with all of its properties -->
|
||||
<!-- The example below shows a small subset of the properties that can be set-->
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('sample',{
|
||||
category: 'input', // the palette category
|
||||
defaults: { // defines the editable properties of the node
|
||||
name: {value:""}, // along with default values.
|
||||
topic: {value:"", required:true}
|
||||
},
|
||||
inputs:0, // set the number of inputs - only 0 or 1
|
||||
outputs:1, // set the number of outputs - 0 to n
|
||||
icon: "arrow-in.png", // set the icon (held in public/icons)
|
||||
label: function() { // sets the default label contents
|
||||
return this.name||this.topic||"sample";
|
||||
},
|
||||
labelStyle: function() { // sets the class to apply to the label
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
52
99-sample.js.demo
Normal file
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Copyright 2013 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.
|
||||
**/
|
||||
|
||||
// If you use this as a template, replace IBM Corp. with your own name.
|
||||
|
||||
// Sample Node-RED node file
|
||||
|
||||
// Require main module
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
|
||||
// The main node definition - most things happen in here
|
||||
function SampleNode(n) {
|
||||
// Create a RED node
|
||||
RED.nodes.createNode(this,n);
|
||||
|
||||
// Store local copies of the node configuration (as defined in the .html)
|
||||
this.topic = n.topic;
|
||||
|
||||
// Do whatever you need to do in here - declare callbacks etc
|
||||
// Note: this sample doesn't do anything much - it will only send
|
||||
// this message once at startup...
|
||||
// Look at other real nodes for some better ideas of what to do....
|
||||
var msg = {};
|
||||
msg.topic = this.topic;
|
||||
msg.payload = "Hello world !"
|
||||
|
||||
// send out the message to the rest of the workspace.
|
||||
this.send(msg);
|
||||
|
||||
this.on("close", function() {
|
||||
// Called when the node is shutdown - eg on redeploy.
|
||||
// Allows ports to be closed, connections dropped etc.
|
||||
// eg: this.client.disconnect();
|
||||
});
|
||||
}
|
||||
|
||||
// Register the node by name. This must be called before overriding any of the
|
||||
// Node functions.
|
||||
RED.nodes.registerType("sample",SampleNode);
|
69
README.md
@ -1,6 +1,6 @@
|
||||
# Node-RED Nodes
|
||||
|
||||
A collection of nodes for [Node-RED](http://nodered.org).
|
||||
A collection of nodes for [Node-RED](http://nodered.org). See below for a list.
|
||||
|
||||
## Installation
|
||||
|
||||
@ -27,9 +27,9 @@ The key points are:
|
||||
### Contributor License Agreement
|
||||
|
||||
In order for us to accept pull-requests, the contributor must first complete
|
||||
a Contributor License Agreement (CLA). This clarifies the intellectual
|
||||
property license granted with any contribution. It is for your protection as a
|
||||
Contributor as well as the protection of IBM and its customers; it does not
|
||||
a Contributor License Agreement (CLA). This clarifies the intellectual
|
||||
property license granted with any contribution. It is for your protection as a
|
||||
Contributor as well as the protection of IBM and its customers; it does not
|
||||
change your rights to use your own Contributions for any other purpose.
|
||||
|
||||
Once you have created a pull-request, we'll provide a link to the appropriate
|
||||
@ -42,3 +42,64 @@ slightly different.
|
||||
## Copyright and license
|
||||
|
||||
Copyright 2013 IBM Corp. under [the Apache 2.0 license](LICENSE).
|
||||
|
||||
# Extra Node Information
|
||||
|
||||
### Analysis
|
||||
|
||||
**72-wordpos** - Analyses the payload and classifies the part-of-speech of each word. The resulting message has msg.pos added with the results. A word may appear in multiple categories (eg, 'great' is both a noun and an adjective).
|
||||
|
||||
**74-swearfilter** - Analyses the payload and tries to filter out any messages containing bad swear words. This only operates on payloads of type string. Everything else is blocked.
|
||||
|
||||
### Hardware
|
||||
|
||||
**37-rpi-piface** - Adds support for the PiFace interface module for Raspberry Pi.
|
||||
|
||||
**78-ledborg** - A simple driver for the LEDborg plug on module for Raspberry Pi.
|
||||
|
||||
**60-wemo** - Basic node to drive a WeMo socket and switch. Does not use discovery.
|
||||
|
||||
**76-blinkstick** - Provides support for the BlinkStick USB LED device.
|
||||
|
||||
**77-blink1** - Provides support for the Blink1 USB LED from ThingM.
|
||||
|
||||
**78-digiRGB** - Provides support for the DigiSpark RGB USB LED.
|
||||
|
||||
**79-sensorTag** - Reads data from the Ti BLE SensorTag device.
|
||||
|
||||
**101-scanBLE** - Scans for a particular Bluetooth Low Energy (BLE) device.
|
||||
|
||||
### IO
|
||||
|
||||
**26-rawserial** - Only really needed for Windows boxes without serialport npm module installed.
|
||||
Uses a simple read of the serial port as a file to input data. You **must** set the baud rate etc externally *before* starting Node-RED. This node does not implement pooling of connections so only one instance of each port may be used - so in **or** out but **not** both.
|
||||
|
||||
**39-wol** - Sends a Wake-On-LAN magic packet to the mac address specified. You may instead set msg.mac to dynamically set the target device mac to wake up.
|
||||
|
||||
**88-ping** - Pings a machine and returns the trip time in mS. Returns false if no response received within 3 seconds, or if the host is unresolveable. Default ping is every 20 seconds but can be configured.
|
||||
|
||||
### Social
|
||||
|
||||
**69-mpd** - MPD music control nodes. Output node expects payload to be a valid mpc command. Currently only simple commands that expect no reply are supported. Input node creates a payload object with Artist, Album, Title, Genre and Date.
|
||||
|
||||
**57-notify** - Uses Growl to provide a desktop popup containing the payload. Only useful on the local machine.
|
||||
|
||||
**57-prowl** - Uses Prowl to push the payload to an Apple device that has the Prowl app installed.
|
||||
|
||||
**57-pushbullet** - Uses PushBullet to push the payload to an Android device that has the PushBullet app installed.
|
||||
|
||||
**92-xmpp** - Connects to an XMPP server to send and receive messages.
|
||||
|
||||
### Storage
|
||||
|
||||
**67-leveldb** - Uses LevelDB for a simple key value pair database.
|
||||
|
||||
**68-mysql** - 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...*
|
||||
|
||||
### Time
|
||||
|
||||
**79-suncalc** - Uses the suncalc module to generate an output at sunrise and sunset based on a specified location. Several choices of definition of sunrise and sunset are available,
|
||||
|
||||
### Misc
|
||||
|
||||
**99-sample** - A sample node with more comments than most to try to help you get started without any other docs...
|
||||
|
46
analysis/swearfilter/74-swearfilter.html
Normal file
@ -0,0 +1,46 @@
|
||||
<!--
|
||||
Copyright 2013 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.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="badwords">
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="badwords">
|
||||
<p>Analyses the <b>msg.payload</b> and tries to filter out any messages containing bad swear words...</p>
|
||||
<p><b>Note:</b> this only operates on payloads of type <b>string</b>. Everything else is blocked.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('badwords',{
|
||||
category: 'analysis-function',
|
||||
color:"#E6E0F8",
|
||||
defaults: {
|
||||
name: {value:""}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
icon: "arrow-in.png",
|
||||
label: function() {
|
||||
return this.name||"badwords";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
29
analysis/swearfilter/74-swearfilter.js
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright 2013 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.
|
||||
**/
|
||||
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
var badwordsRegExp = require('badwords/regexp');
|
||||
|
||||
function BadwordsNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
var node = this;
|
||||
this.on("input", function(msg) {
|
||||
if (typeof msg.payload === "string") {
|
||||
if ( !badwordsRegExp.test(msg.payload) ) { node.send(msg); }
|
||||
}
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("badwords",BadwordsNode);
|
56
analysis/wordpos/72-wordpos.html
Normal file
@ -0,0 +1,56 @@
|
||||
<!--
|
||||
Copyright 2013 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.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="wordpos">
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
<div class="form-tips">Adds <b>msg.pos</b> as the anaylsis result.
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="wordpos">
|
||||
<p>Analyses <b>msg.payload</b> and classifies the part-of-speech of each word.</p>
|
||||
<p>The resulting message has <b>msg.pos</b> added with the results:</p>
|
||||
<pre>{
|
||||
nouns:[],
|
||||
verbs:[],
|
||||
adjectives:[],
|
||||
adverbs:[],
|
||||
rest:[]
|
||||
}</pre>
|
||||
<p>Note: a word may appear in multiple POS (eg, 'great' is both a noun and an adjective)</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('wordpos',{
|
||||
category: 'analysis-function',
|
||||
color:"#E6E0F8",
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
icon: "arrow-in.png",
|
||||
label: function() {
|
||||
return this.name||"wordpos";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
31
analysis/wordpos/72-wordpos.js
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright 2013 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.
|
||||
**/
|
||||
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
var WordPos = require('wordpos');
|
||||
var wordpos = new WordPos();
|
||||
|
||||
function WordPOSNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.on("input", function(msg) {
|
||||
var node = this;
|
||||
wordpos.getPOS(msg.payload, function (result) {
|
||||
msg.pos = result;
|
||||
node.send(msg);
|
||||
});
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("wordpos",WordPOSNode);
|
@ -52,10 +52,10 @@
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="rpi-piface in">
|
||||
<p>Raspberry Pi PiFace input node. Generates a <b>msg.payload</b> with either a 0 or 1 depending on the state of the input pin. Requires the gpio command to work.</p>
|
||||
<p>You may also enable the input pullup resitor if required.</p>
|
||||
<p>The <b>msg.topic</b> is set to <i>pi/{the pin number}</i></p>
|
||||
<p><b>Note:</b> This node currently polls the pin every 250mS. This is not ideal as it loads the cpu, and will be rewritten shortly to try to use interrupts.</p>
|
||||
<p>Raspberry Pi PiFace input node. Generates a <b>msg.payload</b> with either a 0 or 1 depending on the state of the input pin. Requires the gpio command to work.</p>
|
||||
<p>You may also enable the input pullup resitor if required.</p>
|
||||
<p>The <b>msg.topic</b> is set to <i>pi/{the pin number}</i></p>
|
||||
<p><b>Note:</b> This node currently polls the pin every 250mS. This is not ideal as it loads the cpu, and will be rewritten shortly to try to use interrupts.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
@ -103,9 +103,9 @@
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="rpi-piface out">
|
||||
<p>Raspberry Pi PiFace output node. The PiFace board must be fitted. Requires the gpio command to work.</p>
|
||||
<p>Expects a <b>msg.payload</b> with either a 0 or 1 (or true or false).</p>
|
||||
<p>Will set the selected relay, LED, or pin on or off depending on the value passed in.</p>
|
||||
<p>Raspberry Pi PiFace output node. The PiFace board must be fitted. Requires the gpio command to work.</p>
|
||||
<p>Expects a <b>msg.payload</b> with either a 0 or 1 (or true or false).</p>
|
||||
<p>Will set the selected relay, LED, or pin on or off depending on the value passed in.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
@ -14,121 +14,121 @@
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
var RED = require("../../red/red");
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
var util = require("util");
|
||||
var exec = require('child_process').exec;
|
||||
var fs = require('fs');
|
||||
|
||||
if (!fs.existsSync("/usr/local/bin/gpio")) {
|
||||
exec("cat /proc/cpuinfo | grep BCM27",function(err,stdout,stderr) {
|
||||
if (stdout.indexOf('BCM27') > -1) {
|
||||
util.log('[37-rpi-piface.js] Error: Cannot find Wiring-Pi "gpio" command');
|
||||
}
|
||||
// else not on a Pi so don't worry anyone with needless messages.
|
||||
});
|
||||
return;
|
||||
exec("cat /proc/cpuinfo | grep BCM27",function(err,stdout,stderr) {
|
||||
if (stdout.indexOf('BCM27') > -1) {
|
||||
util.log('[37-rpi-piface.js] Error: Cannot find Wiring-Pi "gpio" command');
|
||||
}
|
||||
// else not on a Pi so don't worry anyone with needless messages.
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Map names of pins to Gordon's gpio PiFace pin numbers
|
||||
var pintable = {
|
||||
// Physical : WiringPi
|
||||
"Button S1":"200",
|
||||
"Button S2":"201",
|
||||
"Button S3":"202",
|
||||
"Button S4":"203",
|
||||
"Input 5":"204",
|
||||
"Input 6":"205",
|
||||
"Input 7":"206",
|
||||
"Input 8":"207",
|
||||
"Output0":"208",
|
||||
"Output1":"209",
|
||||
"Output2":"210",
|
||||
"Output3":"211",
|
||||
"Output4":"212",
|
||||
"Output5":"213",
|
||||
"Output6":"214",
|
||||
"Output7":"215",
|
||||
"LED 0 / Relay 0":"200",
|
||||
"LED 1 / Relay 1":"201",
|
||||
"LED 2":"202",
|
||||
"LED 3":"203",
|
||||
"LED 4":"204",
|
||||
"LED 5":"205",
|
||||
"LED 6":"206",
|
||||
"LED 7":"207"
|
||||
"Button S1":"200",
|
||||
"Button S2":"201",
|
||||
"Button S3":"202",
|
||||
"Button S4":"203",
|
||||
"Input 5":"204",
|
||||
"Input 6":"205",
|
||||
"Input 7":"206",
|
||||
"Input 8":"207",
|
||||
"Output0":"208",
|
||||
"Output1":"209",
|
||||
"Output2":"210",
|
||||
"Output3":"211",
|
||||
"Output4":"212",
|
||||
"Output5":"213",
|
||||
"Output6":"214",
|
||||
"Output7":"215",
|
||||
"LED 0 / Relay 0":"200",
|
||||
"LED 1 / Relay 1":"201",
|
||||
"LED 2":"202",
|
||||
"LED 3":"203",
|
||||
"LED 4":"204",
|
||||
"LED 5":"205",
|
||||
"LED 6":"206",
|
||||
"LED 7":"207"
|
||||
}
|
||||
|
||||
function PiFACEInNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.buttonState = -1;
|
||||
this.pin = pintable[n.pin];
|
||||
this.intype = n.intype;
|
||||
var node = this;
|
||||
if (node.pin) {
|
||||
exec("gpio -p mode "+node.pin+" "+node.intype, function(err,stdout,stderr) {
|
||||
if (err) node.error(err);
|
||||
else {
|
||||
node._interval = setInterval( function() {
|
||||
exec("gpio -p read "+node.pin, function(err,stdout,stderr) {
|
||||
if (err) node.error(err);
|
||||
else {
|
||||
if (node.buttonState !== Number(stdout)) {
|
||||
var previousState = node.buttonState;
|
||||
node.buttonState = Number(stdout);
|
||||
if (previousState !== -1) {
|
||||
var msg = {topic:"pi/"+node.pin, payload:node.buttonState};
|
||||
node.send(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 250);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
node.error("Invalid PiFACE pin: "+node.pin);
|
||||
}
|
||||
RED.nodes.createNode(this,n);
|
||||
this.buttonState = -1;
|
||||
this.pin = pintable[n.pin];
|
||||
this.intype = n.intype;
|
||||
var node = this;
|
||||
if (node.pin) {
|
||||
exec("gpio -p mode "+node.pin+" "+node.intype, function(err,stdout,stderr) {
|
||||
if (err) node.error(err);
|
||||
else {
|
||||
node._interval = setInterval( function() {
|
||||
exec("gpio -p read "+node.pin, function(err,stdout,stderr) {
|
||||
if (err) node.error(err);
|
||||
else {
|
||||
if (node.buttonState !== Number(stdout)) {
|
||||
var previousState = node.buttonState;
|
||||
node.buttonState = Number(stdout);
|
||||
if (previousState !== -1) {
|
||||
var msg = {topic:"pi/"+node.pin, payload:node.buttonState};
|
||||
node.send(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 250);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
node.error("Invalid PiFACE pin: "+node.pin);
|
||||
}
|
||||
}
|
||||
|
||||
function PiFACEOutNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.pin = pintable[n.pin];
|
||||
var node = this;
|
||||
if (node.pin) {
|
||||
node.on("input", function(msg) {
|
||||
if (msg.payload === "true") msg.payload = true;
|
||||
if (msg.payload === "false") msg.payload = false;
|
||||
var out = Number(msg.payload);
|
||||
if ((out == 0)|(out == 1)) {
|
||||
exec("gpio -p write "+node.pin+" "+out, function(err,stdout,stderr) {
|
||||
if (err) node.error(err);
|
||||
});
|
||||
}
|
||||
else node.warn("Invalid input - not 0 or 1");
|
||||
});
|
||||
}
|
||||
else {
|
||||
node.error("Invalid PiFACE pin: "+node.pin);
|
||||
}
|
||||
RED.nodes.createNode(this,n);
|
||||
this.pin = pintable[n.pin];
|
||||
var node = this;
|
||||
if (node.pin) {
|
||||
node.on("input", function(msg) {
|
||||
if (msg.payload === "true") msg.payload = true;
|
||||
if (msg.payload === "false") msg.payload = false;
|
||||
var out = Number(msg.payload);
|
||||
if ((out == 0)|(out == 1)) {
|
||||
exec("gpio -p write "+node.pin+" "+out, function(err,stdout,stderr) {
|
||||
if (err) node.error(err);
|
||||
});
|
||||
}
|
||||
else node.warn("Invalid input - not 0 or 1");
|
||||
});
|
||||
}
|
||||
else {
|
||||
node.error("Invalid PiFACE pin: "+node.pin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
exec("gpio load spi",function(err,stdout,stderr) {
|
||||
if (err) {
|
||||
util.log('[37-rpi-piface.js] Error: "gpio load spi" command failed for some reason.');
|
||||
}
|
||||
exec("gpio -p reset",function(err,stdout,stderr) {
|
||||
if (err) {
|
||||
util.log('[37-rpi-piface.js] Error: "gpio -p reset" command failed for some reason.');
|
||||
}
|
||||
RED.nodes.registerType("rpi-piface in",PiFACEInNode);
|
||||
RED.nodes.registerType("rpi-piface out",PiFACEOutNode);
|
||||
PiFACEInNode.prototype.close = function() {
|
||||
clearInterval(this._interval);
|
||||
}
|
||||
PiFACEOutNode.prototype.close = function() {
|
||||
}
|
||||
});
|
||||
if (err) {
|
||||
util.log('[37-rpi-piface.js] Error: "gpio load spi" command failed for some reason.');
|
||||
}
|
||||
exec("gpio -p reset",function(err,stdout,stderr) {
|
||||
if (err) {
|
||||
util.log('[37-rpi-piface.js] Error: "gpio -p reset" command failed for some reason.');
|
||||
}
|
||||
RED.nodes.registerType("rpi-piface in",PiFACEInNode);
|
||||
RED.nodes.registerType("rpi-piface out",PiFACEOutNode);
|
||||
PiFACEInNode.prototype.close = function() {
|
||||
clearInterval(this._interval);
|
||||
}
|
||||
PiFACEOutNode.prototype.close = function() {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -23,10 +23,10 @@
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="ledborg">
|
||||
<p>PiBorg LedBorg LED output node. Expects a <b>msg.payload</b> with a three digit rgb triple, from <b>000</b> to <b>222</b>.</p>
|
||||
<p>See <i><a href="http://www.piborg.com/ledborg/install" target="_new">the PiBorg site</a></i> for more information.</p>
|
||||
<p>You can also now use a <b>msg.payload</b> in the standard hex format "#rrggbb". The clip levels are :</p>
|
||||
<p><pre>0x00 - 0x57 = off<br/>0x58 - 0xA7 = 50%<br/>0xA8 - 0xFF = fully on</pre></p>
|
||||
<p>PiBorg LedBorg LED output node. Expects a <b>msg.payload</b> with a three digit rgb triple, from <b>000</b> to <b>222</b>.</p>
|
||||
<p>See <i><a href="http://www.piborg.com/ledborg/install" target="_new">the PiBorg site</a></i> for more information.</p>
|
||||
<p>You can also now use a <b>msg.payload</b> in the standard hex format "#rrggbb". The clip levels are :</p>
|
||||
<p><pre>0x00 - 0x57 = off<br/>0x58 - 0xA7 = 50%<br/>0xA8 - 0xFF = fully on</pre></p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
@ -14,40 +14,39 @@
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
var RED = require("../../red/red");
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
var util = require('util');
|
||||
var fs = require('fs');
|
||||
|
||||
// check if /dev/ledborg exists - if not then don't even show the node.
|
||||
if (!fs.existsSync("/dev/ledborg")) {
|
||||
util.log("[78-ledborg.js] Error: PiBorg hardware : LedBorg not found");
|
||||
return;
|
||||
util.log("[78-ledborg.js] Warning: PiBorg hardware : LedBorg not found");
|
||||
return;
|
||||
}
|
||||
|
||||
function LedBorgNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
var p1 = /[0-2][0-2][0-2]/
|
||||
var p2 = /^\#[A-Fa-f0-9]{6}$/
|
||||
var node = this;
|
||||
RED.nodes.createNode(this,n);
|
||||
var p1 = /[0-2][0-2][0-2]/
|
||||
var p2 = /^\#[A-Fa-f0-9]{6}$/
|
||||
var node = this;
|
||||
|
||||
this.on("input", function(msg) {
|
||||
if (p1.test(msg.payload)) {
|
||||
fs.writeFile('/dev/ledborg', msg.payload, function (err) {
|
||||
if (err) node.warn(msg.payload+" : No LedBorg found");
|
||||
});
|
||||
}
|
||||
if (p2.test(msg.payload)) {
|
||||
var r = Math.floor(parseInt(msg.payload.slice(1,3),16)/88).toString();
|
||||
var g = Math.floor(parseInt(msg.payload.slice(3,5),16)/88).toString();
|
||||
var b = Math.floor(parseInt(msg.payload.slice(5),16)/88).toString();
|
||||
fs.writeFile('/dev/ledborg', r+g+b, function (err) {
|
||||
if (err) node.warn(r+g+b+" : No LedBorg found");
|
||||
});
|
||||
}
|
||||
else {
|
||||
node.warn("Invalid LedBorg colour code");
|
||||
}
|
||||
});
|
||||
this.on("input", function(msg) {
|
||||
if (p1.test(msg.payload)) {
|
||||
fs.writeFile('/dev/ledborg', msg.payload, function (err) {
|
||||
if (err) node.warn(msg.payload+" : No LedBorg found");
|
||||
});
|
||||
}
|
||||
if (p2.test(msg.payload)) {
|
||||
var r = Math.floor(parseInt(msg.payload.slice(1,3),16)/88).toString();
|
||||
var g = Math.floor(parseInt(msg.payload.slice(3,5),16)/88).toString();
|
||||
var b = Math.floor(parseInt(msg.payload.slice(5),16)/88).toString();
|
||||
fs.writeFile('/dev/ledborg', r+g+b, function (err) {
|
||||
if (err) node.warn(r+g+b+" : No LedBorg found");
|
||||
});
|
||||
}
|
||||
else {
|
||||
node.warn("Invalid LedBorg colour code");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType("ledborg",LedBorgNode);
|
||||
|
50
hardware/blink/76-blinkstick.html
Normal file
@ -0,0 +1,50 @@
|
||||
<!--
|
||||
Copyright 2013 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.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="blinkstick">
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
<div class="form-tips">Expects a msg.payload with either hex #rrggbb or decimal red,green,blue.</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="blinkstick">
|
||||
<p>BlinkStick output node. Expects a <b>msg.payload</b> with either a hex string #rrggbb triple or red,green,blue as three 0-255 values.
|
||||
It can also accept <i><a href="http://www.w3schools.com/html/html_colornames.asp" target="_new">standard HTML colour</a></i> names</p>
|
||||
<p><b>NOTE:</b> currently only works with a single BlinkStick. (As it uses the findFirst() function to attach).</p>
|
||||
<p>For more info see the <i><a href="http://blinkstick.com/" target="_new">BlinkStick website</a></i> or the <i><a href="https://github.com/arvydas/blinkstick-node" target="_new">node module</a></i> documentation.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('blinkstick',{
|
||||
category: 'output',
|
||||
color:"GoldenRod",
|
||||
defaults: {
|
||||
name: {value:""}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "light.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
return this.name||"blinkstick";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
62
hardware/blink/76-blinkstick.js
Normal file
@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Copyright 2013 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.
|
||||
**/
|
||||
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
var blinkstick = require("blinkstick");
|
||||
|
||||
Object.size = function(obj) {
|
||||
var size = 0, key;
|
||||
for (key in obj) { if (obj.hasOwnProperty(key)) size++; }
|
||||
return size;
|
||||
};
|
||||
|
||||
function BlinkStick(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
var p1 = /^\#[A-Fa-f0-9]{6}$/
|
||||
var p2 = /[0-9]+,[0-9]+,[0-9]+/
|
||||
this.led = blinkstick.findFirst(); // maybe try findAll() (one day)
|
||||
var node = this;
|
||||
|
||||
this.on("input", function(msg) {
|
||||
if (msg != null) {
|
||||
if (Object.size(node.led) !== 0) {
|
||||
try {
|
||||
if (p2.test(msg.payload)) {
|
||||
var rgb = msg.payload.split(",");
|
||||
node.led.setColor(parseInt(rgb[0])&255, parseInt(rgb[1])&255, parseInt(rgb[2])&255);
|
||||
}
|
||||
else {
|
||||
node.led.setColor(msg.payload.toLowerCase().replace(/\s+/g,''));
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
node.warn("BlinkStick missing ?");
|
||||
node.led = blinkstick.findFirst();
|
||||
}
|
||||
}
|
||||
else {
|
||||
//node.warn("No BlinkStick found");
|
||||
node.led = blinkstick.findFirst();
|
||||
}
|
||||
}
|
||||
});
|
||||
if (Object.size(node.led) === 0) {
|
||||
node.error("No BlinkStick found");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RED.nodes.registerType("blinkstick",BlinkStick);
|
52
hardware/blink/77-blink1.html
Normal file
@ -0,0 +1,52 @@
|
||||
<!--
|
||||
Copyright 2013 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.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="blink1">
|
||||
<div class="form-row">
|
||||
<label for="node-input-fade"><i class="icon-signal"></i> Fade (mS)</label>
|
||||
<input type="text" id="node-input-fade" placeholder="0">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
<div class="form-tips">Expects a msg.payload with three part csv string of r,g,b.</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="blink1">
|
||||
<p>ThingM Blink1 output node. Expects a msg.payload with a three part csv string of r,g,b.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('blink1',{
|
||||
category: 'output',
|
||||
color:"GoldenRod",
|
||||
defaults: {
|
||||
fade: {value:"0",required:true,validate:RED.validators.number()},
|
||||
name: {value:""}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "light.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
return this.name||"blink1";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
59
hardware/blink/77-blink1.js
Normal file
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright 2013 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.
|
||||
**/
|
||||
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
var Blink1 = require("node-blink1");
|
||||
|
||||
function Blink1Node(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.fade = n.fade||0;
|
||||
var node = this;
|
||||
|
||||
try {
|
||||
var p1 = /^\#[A-Fa-f0-9]{6}$/
|
||||
var p2 = /[0-9]+,[0-9]+,[0-9]+/
|
||||
this.on("input", function(msg) {
|
||||
if (blink1) {
|
||||
if (p1.test(msg.payload)) {
|
||||
// if it is a hex colour string
|
||||
var r = parseInt(msg.payload.slice(1,3),16);
|
||||
var g = parseInt(msg.payload.slice(3,5),16);
|
||||
var b = parseInt(msg.payload.slice(5),16);
|
||||
if (node.fade == 0) { blink1.setRGB( r, g, b ); }
|
||||
else { blink1.fadeToRGB(node.fade, r, g, b ); }
|
||||
}
|
||||
else if (p2.test(msg.payload)) {
|
||||
// if it is a r,g,b triple
|
||||
var rgb = msg.payload.split(',');
|
||||
if (node.fade == 0) { blink1.setRGB(parseInt(rgb[0])&255, parseInt(rgb[1])&255, parseInt(rgb[2])&255); }
|
||||
else { blink1.fadeToRGB(node.fade, parseInt(rgb[0])&255, parseInt(rgb[1])&255, parseInt(rgb[2])&255); }
|
||||
}
|
||||
else {
|
||||
// you can add fancy colours by name here if you want...
|
||||
node.warn("Blink1 : invalid msg : "+msg.payload);
|
||||
}
|
||||
}
|
||||
else {
|
||||
node.warn("No Blink1 found");
|
||||
}
|
||||
});
|
||||
var blink1 = new Blink1.Blink1();
|
||||
}
|
||||
catch(e) {
|
||||
node.error("No Blink1 found");
|
||||
}
|
||||
}
|
||||
RED.nodes.registerType("blink1",Blink1Node);
|
@ -14,55 +14,34 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
|
||||
<!-- First, the content of the edit dialog is defined. -->
|
||||
|
||||
<script type="text/x-red" data-template-name="digiRGB">
|
||||
<!-- data-template-name identifies the node type this is for -->
|
||||
|
||||
<!-- Each of the following divs creates a field in the edit dialog. -->
|
||||
<!-- Generally, there should be an input for each property of the node. -->
|
||||
<!-- The for and id attributes identify the corresponding property -->
|
||||
<!-- (with the 'node-input-' prefix). -->
|
||||
<!-- The available icon classes are defined in Twitter Bootstrap -->
|
||||
|
||||
<!-- By convention, most nodes have a 'name' property. The following div -->
|
||||
<!-- provides the necessary field. -->
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
<input type="text" id="node-input-name" placeholder="DigiSpark">
|
||||
</div>
|
||||
<div class="form-tips">Expects a msg.payload with three part csv string of r,g,b.</div>
|
||||
</script>
|
||||
|
||||
|
||||
<!-- Next, some simple help text is provided for the node. -->
|
||||
<script type="text/x-red" data-help-name="digiRGB">
|
||||
<!-- data-help-name identifies the node type this help is for -->
|
||||
<!-- This content appears in the Info sidebar when a node is selected -->
|
||||
<!-- The first <p> is used as the pop-up tool tip when hovering over a -->
|
||||
<!-- node in the palette. -->
|
||||
<p>Simple output node to drive digispark RGB</p>
|
||||
<p>Requires msg.payload to be of the form 'r,g,b'</p>
|
||||
<p>Simple output node to drive digispark RGB</p>
|
||||
<p>Requires <b>msg.payload</b> to be of the form 'r,g,b'</p>
|
||||
</script>
|
||||
|
||||
<!-- Finally, the node type is registered along with all of its properties -->
|
||||
<!-- The example below shows a small subset of the properties that can be set-->
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('digiRGB',{
|
||||
category: 'output', // the palette category
|
||||
category: 'output',
|
||||
color:"GoldenRod",
|
||||
defaults: { // defines the editable properties of the node
|
||||
name: {value:"digiSparkRGB"} // along with default values.
|
||||
defaults: {
|
||||
name: {value:""}
|
||||
},
|
||||
inputs:1, // set the number of inputs - only 0 or 1
|
||||
outputs:0, // set the number of outputs - 0 to n
|
||||
icon: "light.png", // set the icon (held in public/icons)
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "light.png",
|
||||
align: "right",
|
||||
label: function() { // sets the default label contents
|
||||
return this.name||this.topic||"sample";
|
||||
label: function() {
|
||||
return this.name||"digiSparkRGB";
|
||||
},
|
||||
labelStyle: function() { // sets the class to apply to the label
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
|
@ -14,70 +14,56 @@
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
// Sample Node-RED node file
|
||||
|
||||
// Require main module
|
||||
var RED = require("../../red/red");
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
var HID = require('node-hid');
|
||||
var device;
|
||||
var node;
|
||||
|
||||
// The main node definition - most things happen in here
|
||||
function DigiRGBNode(n) {
|
||||
// Create a RED node
|
||||
RED.nodes.createNode(this,n);
|
||||
node=this;
|
||||
|
||||
|
||||
var devices = HID.devices(0x16c0,0x05df);
|
||||
for (var i=0; i< devices.length; i++) {
|
||||
if (devices[i].product == 'DigiUSB') {
|
||||
path = devices[i].path;
|
||||
node.log("found: " + path);
|
||||
try {
|
||||
device = new HID.HID(devices[i].path);
|
||||
break;
|
||||
} catch (e) {
|
||||
node.log(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var p1 = /^\#[A-Fa-f0-9]{6}$/
|
||||
var p2 = /[0-9]+,[0-9]+,[0-9]+/
|
||||
|
||||
if (device) {
|
||||
this.on("input", function(msg) {
|
||||
if (msg != null) {
|
||||
if (p1.test(msg.payload)) {
|
||||
var r = parseInt(msg.payload.slice(1,3),16);
|
||||
var g = parseInt(msg.payload.slice(3,5),16);
|
||||
var b = parseInt(msg.payload.slice(5),16);
|
||||
device.sendFeatureReport([115,r,g,b]);
|
||||
} else if (p2.test(msg.payload)) {
|
||||
var args = msg.payload.split(',');
|
||||
if (args.length == 3) {
|
||||
device.sendFeatureReport([115,parseInt(args[0]),parseInt(args[1]),parseInt(args[2])]);
|
||||
if (devices[i].product == 'DigiUSB') {
|
||||
path = devices[i].path;
|
||||
node.log("found: " + path);
|
||||
try {
|
||||
device = new HID.HID(devices[i].path);
|
||||
break;
|
||||
} catch (e) {
|
||||
node.log(e)
|
||||
}
|
||||
} else {
|
||||
node.warn("incompatable input - " + msg.payload);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
node.warn("no digispark RGB found");
|
||||
}
|
||||
}
|
||||
|
||||
// Register the node by name. This must be called before overriding any of the
|
||||
// Node functions.
|
||||
RED.nodes.registerType("digiRGB",DigiRGBNode);
|
||||
|
||||
|
||||
DigiRGBNode.prototype.close = function() {
|
||||
// Called when the node is shutdown - eg on redeploy.
|
||||
// Allows ports to be closed, connections dropped etc.
|
||||
// eg: this.client.disconnect();
|
||||
if (device) {
|
||||
device.close();
|
||||
}
|
||||
|
||||
var p1 = /^\#[A-Fa-f0-9]{6}$/
|
||||
var p2 = /[0-9]+,[0-9]+,[0-9]+/
|
||||
|
||||
if (device) {
|
||||
this.on("input", function(msg) {
|
||||
if (msg != null) {
|
||||
if (p1.test(msg.payload)) {
|
||||
var r = parseInt(msg.payload.slice(1,3),16);
|
||||
var g = parseInt(msg.payload.slice(3,5),16);
|
||||
var b = parseInt(msg.payload.slice(5),16);
|
||||
device.sendFeatureReport([115,r,g,b]);
|
||||
} else if (p2.test(msg.payload)) {
|
||||
var args = msg.payload.split(',');
|
||||
if (args.length == 3) {
|
||||
device.sendFeatureReport([115,parseInt(args[0]),parseInt(args[1]),parseInt(args[2])]);
|
||||
}
|
||||
} else {
|
||||
node.warn("incompatable input - " + msg.payload);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
node.warn("no digispark RGB found");
|
||||
}
|
||||
|
||||
this.on('close', function() {
|
||||
if (device) { device.close(); }
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("digiRGB",DigiRGBNode);
|
||||
|
@ -19,52 +19,52 @@
|
||||
**/
|
||||
|
||||
//might need to modify accordingly
|
||||
var RED = require("../../red/red");
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
|
||||
//import noble
|
||||
var noble = require('noble');
|
||||
|
||||
// The main node definition - most things happen in here
|
||||
function BleScan(n) {
|
||||
// Create a RED node
|
||||
RED.nodes.createNode(this,n);
|
||||
// Create a RED node
|
||||
RED.nodes.createNode(this,n);
|
||||
|
||||
var msg = {};
|
||||
var ble_name;
|
||||
var node = this;
|
||||
|
||||
var ble_name;
|
||||
var node = this;
|
||||
|
||||
//get name and uuid from user
|
||||
this.ble_name = n.ble_name;
|
||||
this.ble_uuid = n.ble_uuid;
|
||||
|
||||
this.on("input", function(msg){
|
||||
noble.startScanning();
|
||||
noble.startScanning();
|
||||
});
|
||||
noble.on('scanStart', function(msg) {
|
||||
var msg = {};
|
||||
msg.topic = node.topic;
|
||||
msg.payload = "Scanning initiated..." //debugging
|
||||
//console.log('scanning initiated...');
|
||||
node.send(msg);
|
||||
var msg = {};
|
||||
msg.topic = node.topic;
|
||||
msg.payload = "Scanning initiated..." //debugging
|
||||
//console.log('scanning initiated...');
|
||||
node.send(msg);
|
||||
});
|
||||
|
||||
noble.on('discover', function(peripheral) {
|
||||
|
||||
var msg = {};
|
||||
msg.topic = node.topic;
|
||||
msg.payload = "not found";
|
||||
|
||||
//check for the device name and the UUID (first one from the UUID list)
|
||||
if(peripheral.advertisement.localName==node.ble_name && peripheral.advertisement.serviceUuids[0]==node.ble_uuid) {
|
||||
msg.payload=peripheral.advertisement.localName;
|
||||
noble.stopScanning(); }
|
||||
node.send(msg);
|
||||
var msg = {};
|
||||
msg.topic = node.topic;
|
||||
msg.payload = "not found";
|
||||
|
||||
//check for the device name and the UUID (first one from the UUID list)
|
||||
if(peripheral.advertisement.localName==node.ble_name && peripheral.advertisement.serviceUuids[0]==node.ble_uuid) {
|
||||
msg.payload=peripheral.advertisement.localName;
|
||||
noble.stopScanning(); }
|
||||
node.send(msg);
|
||||
});
|
||||
|
||||
this.on("close", function() {
|
||||
try { noble.stopScanning(); }
|
||||
catch (err) { console.log(err); }
|
||||
});
|
||||
this.on("close", function() {
|
||||
try { noble.stopScanning(); }
|
||||
catch (err) { console.log(err); }
|
||||
});
|
||||
}
|
||||
|
||||
// Register the node by name. This must be called before overriding any of the
|
||||
|
90
hardware/wemo/60-wemo.html
Normal file
@ -0,0 +1,90 @@
|
||||
<!--
|
||||
Copyright 2013 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.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="wemo out">
|
||||
<div class="form-row">
|
||||
<label for="node-input-ipaddr"><i class="icon-globe"></i> IP Address</label>
|
||||
<input type="text" id="node-input-ipaddr" placeholder="192.168.1.100">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
<div class="form-tips">Expects a msg.payload with either 1/0, on/off, or true/false</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="wemo out">
|
||||
<p>Wemo output node. Expects a <b>msg.payload</b> with either 1/0, on/off or true/false.</p>
|
||||
<p>It doesn't yet do any ip address discovery of the wemo devices.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('wemo out',{
|
||||
category: 'advanced-output',
|
||||
color:"GoldenRod",
|
||||
defaults: {
|
||||
ipaddr: {value:"",required:true},
|
||||
name: {value:""}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "light.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
return this.name||"wemo";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-template-name="wemo in">
|
||||
<div class="form-row">
|
||||
<label for="node-input-ipaddr"><i class="icon-globe"></i> IP Address</label>
|
||||
<input type="text" id="node-input-ipaddr" placeholder="192.168.1.100">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
<div class="form-tips">Creates a msg.payload with either 1, 0, nc or na.</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="wemo in">
|
||||
<p>Wemo input node. Creates a <b>msg.payload</b> with either 1, 0, nc (no change), or na (not available).</p>
|
||||
<p>It doesn't yet do any ip address discovery of the wemo devices.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('wemo in',{
|
||||
category: 'advanced-input',
|
||||
color:"GoldenRod",
|
||||
defaults: {
|
||||
ipaddr: {value:"",required:true},
|
||||
name: {value:""}
|
||||
},
|
||||
inputs:0,
|
||||
outputs:1,
|
||||
icon: "light.png",
|
||||
label: function() {
|
||||
return this.name||"wemo";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
60
hardware/wemo/60-wemo.js
Normal file
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Copyright 2013 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.
|
||||
**/
|
||||
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
var WeMo = new require('wemo');
|
||||
|
||||
function WeMoOut(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.ipaddr = n.ipaddr;
|
||||
this.wemoSwitch = new WeMo(n.ipaddr);
|
||||
var node = this;
|
||||
|
||||
this.on("input", function(msg) {
|
||||
if (msg != null) {
|
||||
var state = 0;
|
||||
if ( msg.payload == 1 || msg.payload == true || msg.payload == "on" ) { var state = 1; }
|
||||
node.wemoSwitch.setBinaryState(state, function(err, result) {
|
||||
if (err) node.warn(err);
|
||||
//else { node.log(result); }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("wemo out",WeMoOut);
|
||||
|
||||
function WeMoIn(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.ipaddr = n.ipaddr;
|
||||
this.wemoSwitch = new WeMo(n.ipaddr);
|
||||
this.wemoSwitch.state = 0;
|
||||
var node = this;
|
||||
|
||||
var tick = setInterval(function() {
|
||||
wemoSwitch.getBinaryState(function(err, result) {
|
||||
if (err) node.warn(err);
|
||||
if (parseInt(result) != wemoSwitch.state) {
|
||||
wemoSwitch.state = parseInt(result);
|
||||
node.send({payload:wemoSwitch.state,topic:"wemo/"+node.ipaddr});
|
||||
}
|
||||
});
|
||||
}, 2000);
|
||||
|
||||
this.on("close", function() {
|
||||
clearInterval(tick);
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("wemo in",WeMoOut);
|
@ -15,18 +15,18 @@
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="ping">
|
||||
<div class="form-row">
|
||||
<label for="node-input-host"><i class="icon-tasks"></i> Target</label>
|
||||
<input type="text" id="node-input-host" placeholder="www.google.com">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-timer"><i class="icon-tasks"></i> Ping (S)</label>
|
||||
<input type="text" id="node-input-timer" placeholder="20">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-host"><i class="icon-tasks"></i> Target</label>
|
||||
<input type="text" id="node-input-host" placeholder="www.google.com">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-timer"><i class="icon-tasks"></i> Ping (S)</label>
|
||||
<input type="text" id="node-input-timer" placeholder="20">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<!-- Next, some simple help text is provided for the node. -->
|
||||
|
@ -13,45 +13,43 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
var RED = require("../../red/red");
|
||||
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
var spawn = require('child_process').spawn;
|
||||
var plat = require('os').platform();
|
||||
|
||||
function PingNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.host = n.host;
|
||||
this.timer = n.timer * 1000;
|
||||
var node = this;
|
||||
RED.nodes.createNode(this,n);
|
||||
this.host = n.host;
|
||||
this.timer = n.timer * 1000;
|
||||
var node = this;
|
||||
|
||||
node.tout = setInterval(function() {
|
||||
var ex;
|
||||
if (plat == "linux") 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") ex = spawn('ping', ['-n', '-t 5', '-c 1', node.host]);
|
||||
else node.error("Sorry - your platform - "+plat+" - is not recognised.");
|
||||
var res="";
|
||||
node.tout = setInterval(function() {
|
||||
var ex;
|
||||
if (plat == "linux") 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") ex = spawn('ping', ['-n', '-t 5', '-c 1', node.host]);
|
||||
else node.error("Sorry - your platform - "+plat+" - is not recognised.");
|
||||
var res="";
|
||||
ex.stdout.on('data', function (data) {
|
||||
//console.log('[ping] stdout: ' + data.toString());
|
||||
var regex = /time=(.*)ms/;
|
||||
var m = regex.exec(data.toString())||[""];
|
||||
res = Number(m[1]);
|
||||
});
|
||||
ex.stderr.on('data', function (data) {
|
||||
//console.log('[ping] stderr: ' + data);
|
||||
});
|
||||
ex.on('close', function (code) {
|
||||
//console.log('[ping] result: ' + code);
|
||||
var msg = { payload: false, topic:node.host };
|
||||
if (code == 0) msg = { payload: res, topic:node.host };
|
||||
node.send(msg);
|
||||
});
|
||||
}, node.timer);
|
||||
|
||||
ex.stdout.on('data', function (data) {
|
||||
//console.log('[ping] stdout: ' + data.toString());
|
||||
var regex = /time=(.*)ms/;
|
||||
var m = regex.exec(data.toString())||[""];
|
||||
res = Number(m[1]);
|
||||
});
|
||||
ex.stderr.on('data', function (data) {
|
||||
//console.log('[ping] stderr: ' + data);
|
||||
});
|
||||
ex.on('close', function (code) {
|
||||
//console.log('[ping] result: ' + code);
|
||||
var msg = { payload: false, topic:node.host };
|
||||
if (code == 0) msg = { payload: res, topic:node.host };
|
||||
node.send(msg);
|
||||
});
|
||||
|
||||
}, node.timer);
|
||||
this.on("close", function() {
|
||||
clearInterval(this.tout);
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType("ping",PingNode);
|
||||
|
||||
PingNode.prototype.close = function() {
|
||||
clearInterval(this.tout);
|
||||
}
|
||||
|
102
io/rawserial/26-rawserial.html
Normal file
@ -0,0 +1,102 @@
|
||||
<!--
|
||||
Copyright 2013 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.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="rawserial in">
|
||||
<div class="form-row">
|
||||
<label for="node-input-port"><i class="icon-random"></i> Port</label>
|
||||
<input type="text" id="node-input-port" placeholder="COM1">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-split"><i class="icon-edit"></i> Split on</label>
|
||||
<input type="text" id="node-input-split" placeholder="\n">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="rawserial in">
|
||||
<p>Uses a simple read of the serial port as a file to input data.</p>
|
||||
<p>You MUST set the baud rate etc <i>externally</i> before starting Node-RED. For example.</p>
|
||||
<p>Windows<pre>mode COM1:9600,n,8,1</pre>
|
||||
<p>Linux<pre>stty -F /dev/ttyUSB0 9600</pre>
|
||||
<p>Note: This node does not implement pooling of connections so only one instance of each port may be used - so in OR out but NOT both.</p>
|
||||
<p>Should only really be used if you can't get npm serialport installed properly.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('rawserial in',{
|
||||
category: 'advanced-input',
|
||||
color:"BurlyWood",
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
split: {value:""},
|
||||
port: {value:"", required:true}
|
||||
},
|
||||
inputs:0,
|
||||
outputs:1,
|
||||
icon: "serial.png",
|
||||
label: function() {
|
||||
return this.name||this.port||"Raw Serial";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-template-name="rawserial out">
|
||||
<div class="form-row">
|
||||
<label for="node-input-port"><i class="icon-random"></i> Port</label>
|
||||
<input type="text" id="node-input-port" placeholder="COM1">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="rawserial out">
|
||||
<p>Uses a simple file write to output <b>msg.payload</b> to the serial port.</p>
|
||||
<p>You MUST set the baud rate etc <i>externally</i> before starting Node-RED. For example.</p>
|
||||
<p>Windows<pre>mode COM1:9600,n,8,1</pre>
|
||||
<p>Linux<pre>stty -F /dev/ttyUSB0 9600</pre>
|
||||
<p>Note: This node does not implement pooling of connections so only one instance of each port may be used - so in OR out but NOT both.</p>
|
||||
<p>Should only really be used if you can't get npm serialport installed properly.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('rawserial out',{
|
||||
category: 'advanced-input',
|
||||
color:"BurlyWood",
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
split: {value:""},
|
||||
port: {value:"", required:true}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "serial.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
return this.name||this.port||"Raw Serial";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
112
io/rawserial/26-rawserial.js
Normal file
@ -0,0 +1,112 @@
|
||||
/**
|
||||
* Copyright 2013 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.
|
||||
**/
|
||||
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
var settings = RED.settings;
|
||||
var util = require("util");
|
||||
var fs = require('fs');
|
||||
var plat = require('os').platform();
|
||||
var pre = "\\\\.\\";
|
||||
|
||||
if (! plat.match(/^win/)) {
|
||||
util.log("[26-rawserial.js] Advise: Only really needed for Windows boxes without serialport npm module installed.");
|
||||
pre = "";
|
||||
}
|
||||
|
||||
function RawSerialInNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.port = n.port;
|
||||
this.split = n.split||null;
|
||||
if (this.split == '\\n') this.split = "\n";
|
||||
if (this.split == '\\r') this.split = "\r";
|
||||
var node = this;
|
||||
|
||||
var setupSerial = function() {
|
||||
node.inp = fs.createReadStream(pre+node.port);
|
||||
node.inp.setEncoding('utf8');
|
||||
var line = "";
|
||||
node.inp.on('data', function (data) {
|
||||
if (node.split != null) {
|
||||
if (data == node.split) {
|
||||
node.send({payload:line});
|
||||
line = "";
|
||||
}
|
||||
else { line += data; }
|
||||
}
|
||||
else { node.send({payload:data}); }
|
||||
});
|
||||
//node.inp.on('end', function (error) {console.log("End", error);});
|
||||
node.inp.on('close', function (error) {
|
||||
util.log("[rawserial] "+node.port+" closed");
|
||||
node.tout = setTimeout(function() {
|
||||
setupSerial();
|
||||
},settings.serialReconnectTime);
|
||||
});
|
||||
node.inp.on('error', function(error) {
|
||||
if (error.code == "ENOENT") { util.log("[rawserial] port "+node.port+" not found"); }
|
||||
else { util.log("[rawserial] "+node.port+" error "+error); }
|
||||
node.tout = setTimeout(function() {
|
||||
setupSerial();
|
||||
},settings.serialReconnectTime);
|
||||
});
|
||||
}
|
||||
setupSerial();
|
||||
|
||||
node.on('close', function() {
|
||||
if (node.tout) { clearTimeout(node.tout); }
|
||||
if (node.inp) { node.inp.pause(); }
|
||||
});
|
||||
|
||||
}
|
||||
RED.nodes.registerType("rawserial in",RawSerialInNode);
|
||||
|
||||
|
||||
function RawSerialOutNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.port = n.port;
|
||||
var node = this;
|
||||
|
||||
var setupSerial = function() {
|
||||
node.oup = fs.createWriteStream(pre+node.port,{ flags:'w', encoding:'utf8', mode:0666 });
|
||||
node.on("input", function(msg) {
|
||||
if (msg.payload != null) {
|
||||
node.oup.write(msg.payload);
|
||||
}
|
||||
});
|
||||
node.oup.on('open', function (error) { util.log("[rawserial] opened "+node.port); });
|
||||
node.oup.on('end', function (error) { console.log("End",error); });
|
||||
node.oup.on('close', function (error) {
|
||||
util.log("[rawserial] "+node.port+" closed");
|
||||
node.tout = setTimeout(function() {
|
||||
setupSerial();
|
||||
},settings.serialReconnectTime);
|
||||
});
|
||||
node.oup.on('error', function(error) {
|
||||
if (error.code == "EACCES") { util.log("[rawserial] can't access port "+node.port); }
|
||||
else if (error.code == "EIO") { util.log("[rawserial] can't write to port "+node.port); }
|
||||
else { util.log("[rawserial] "+node.port+" error "+error); }
|
||||
node.tout = setTimeout(function() {
|
||||
setupSerial();
|
||||
},settings.serialReconnectTime);
|
||||
});
|
||||
}
|
||||
setupSerial();
|
||||
|
||||
node.on('close', function() {
|
||||
if (node.tout) { clearTimeout(node.tout); }
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("rawserial out",RawSerialOutNode);
|
54
io/wol/39-wol.html
Normal file
@ -0,0 +1,54 @@
|
||||
<!--
|
||||
Copyright 2013 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.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="wake on lan">
|
||||
<div class="form-row">
|
||||
<label for="node-input-mac"><i class="icon-globe"></i> MAC Address</label>
|
||||
<input type="text" id="node-input-mac" placeholder="DE:AD:BE:EF:FE:ED">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
<div class="form-tips">Tip: leave blank if you want to use <b>msg.mac</b></div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="wake on lan">
|
||||
<p>Sends a Wake-On-LAN magic packet to the mac address specified.</p>
|
||||
<p>You may instead set <b>msg.mac</b> to dynamically set the target device mac to wake up.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('wake on lan',{
|
||||
category: 'advanced-output',
|
||||
color:"#999966",
|
||||
defaults: {
|
||||
mac: {value:""},
|
||||
name: {value:""}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "light.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
if (this.mac != "") { return "WOL: "+this.mac; }
|
||||
else { return this.name||"wake on lan"; }
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
41
io/wol/39-wol.js
Normal file
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright 2013 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.
|
||||
**/
|
||||
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
var wol = require('wake_on_lan');
|
||||
var chk = /^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$/;
|
||||
|
||||
function WOLnode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.mac = n.mac
|
||||
var node = this;
|
||||
|
||||
this.on("input", function(msg) {
|
||||
if (msg != null) {
|
||||
var mac = this.mac || msg.mac || null;
|
||||
if (mac != null) {
|
||||
if (chk.test(mac)) {
|
||||
wol.wake(mac, function(error) {
|
||||
if (error) { node.warn(error); }
|
||||
});
|
||||
}
|
||||
else { node.warn("WOL: bad mac address "+mac); }
|
||||
}
|
||||
else { node.warn("WOL: no mac address specified"); }
|
||||
}
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("wake on lan",WOLnode);
|
BIN
io/wol/icons/onoff.png
Normal file
After Width: | Height: | Size: 993 B |
80
social/music/69-mpd.html
Normal file
@ -0,0 +1,80 @@
|
||||
<!--
|
||||
Copyright 2013 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.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="mpd out">
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
<div class="form-tips">Expects a msg.payload with a valid mpc command.</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="mpd out">
|
||||
<p>MPD music control output node.</p>
|
||||
<p>Expects <b>msg.payload</b> to be a valid mpc command. Currently only simple commands that expect no reply are supported.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('mpd out',{
|
||||
category: 'advanced-output',
|
||||
color:"#ffcc66",
|
||||
defaults: {
|
||||
name: {value:""}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "music.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
return this.name||"mpd";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-template-name="mpd in">
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
<div class="form-tips">Creates a msg.payload object with Artist, Album, Title, Genre and Date.</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="mpd in">
|
||||
<p>MPD music control input node.</p>
|
||||
<p>Creates a <b>msg.payload</b> object with Artist, Album, Track, Genre and Date.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('mpd in',{
|
||||
category: 'advanced-input',
|
||||
color:"#ffcc66",
|
||||
defaults: {
|
||||
name: {value:""}
|
||||
},
|
||||
inputs:0,
|
||||
outputs:1,
|
||||
icon: "music.png",
|
||||
label: function() {
|
||||
return this.name||"mpd";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
84
social/music/69-mpd.js
Normal file
@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright 2013 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.
|
||||
**/
|
||||
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
var komponist = require('komponist');
|
||||
|
||||
var mpc = "";
|
||||
komponist.createConnection(6600, 'localhost', function(err, client) {
|
||||
if (err) node.error("MPD: Failed to connect to MPD server");
|
||||
mpc = client;
|
||||
});
|
||||
|
||||
function MPDOut(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
var node = this;
|
||||
node.mpc = mpc;
|
||||
|
||||
this.on("input", function(msg) {
|
||||
if (msg != null) {
|
||||
console.log(msg);
|
||||
try {
|
||||
//node.mpc.command(msg.payload);
|
||||
node.mpc.command(msg.payload, msg.param, function(err, results) {
|
||||
if (err) { console.log("MPD: Error:",err); }
|
||||
//else { console.log(results); }
|
||||
});
|
||||
} catch (err) { console.log("MPD: Error:",err); }
|
||||
}
|
||||
});
|
||||
|
||||
node.mpc.on('error', function(err) {
|
||||
console.log("MPD: Error:",err);
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("mpd out",MPDOut);
|
||||
|
||||
function MPDIn(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
var node = this;
|
||||
node.mpc = mpc;
|
||||
var oldMsg = "";
|
||||
|
||||
getSong();
|
||||
|
||||
function getSong() {
|
||||
node.mpc.currentsong(function(err, info) {
|
||||
if (err) console.log(err);
|
||||
else {
|
||||
var msg = {payload:{},topic:"music"};
|
||||
msg.payload.Artist = info.Artist;
|
||||
msg.payload.Album = info.Album;
|
||||
msg.payload.Title = info.Title;
|
||||
msg.payload.Genre = info.Genre;
|
||||
msg.payload.Date = info.Date;
|
||||
if (JSON.stringify(msg) != oldMsg) {
|
||||
node.send(msg);
|
||||
oldMsg = JSON.stringify(msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
node.mpc.on('changed', function(system) {
|
||||
getSong();
|
||||
});
|
||||
|
||||
this.on("close", function() {
|
||||
// node.mpc.command("stop");
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("mpd in",MPDIn);
|
BIN
social/music/icons/music.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
55
social/notify/57-notify.html
Normal file
@ -0,0 +1,55 @@
|
||||
<!--
|
||||
Copyright 2013 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.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="notify">
|
||||
<div class="form-row">
|
||||
<label for="node-input-title"><i class="icon-flag"></i> Title</label>
|
||||
<input type="text" id="node-input-title" placeholder="Node-RED">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="notify">
|
||||
<p>Uses Growl to provide a desktop popup containing the <b>msg.payload</b>. Only useful on the local machine.</p>
|
||||
<p>Optionally uses <b>msg.topic</b> 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 WON'T work.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('notify',{
|
||||
category: 'output',
|
||||
defaults: {
|
||||
title: {value:""},
|
||||
name: {value:""}
|
||||
},
|
||||
color:"#a7c9a0",
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "alert.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
return this.name||this.title||"notify";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
39
social/notify/57-notify.js
Normal file
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright 2013 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.
|
||||
**/
|
||||
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
var growl = require('growl');
|
||||
var imagefile = process.env.NODE_RED_HOME+"/public/mqtt-node-red.png";
|
||||
|
||||
function NotifyNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.title = n.title;
|
||||
var node = this;
|
||||
this.on("input",function(msg) {
|
||||
var titl = this.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 });
|
||||
}
|
||||
else {
|
||||
growl(msg.payload, { image: imagefile });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType("notify",NotifyNode);
|
63
social/prowl/57-prowl.html
Normal file
@ -0,0 +1,63 @@
|
||||
<!--
|
||||
Copyright 2013 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.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="prowl">
|
||||
<div class="form-row">
|
||||
<label for="node-input-title"><i class="icon-tag"></i> Title</label>
|
||||
<input type="text" id="node-input-title" placeholder="Node-RED">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-priority"><i class="icon-tag"></i> Priority</label>
|
||||
<input type="text" id="node-input-priority" placeholder="0">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="prowl">
|
||||
<p>Uses Prowl to push the <b>msg.payload</b> to an Apple device that has the prowl app installed.</p>
|
||||
<p>Optionally uses <b>msg.topic</b> to set the title. You can also set <b>msg.priority</b> to confgure the urgency from -2 (low), through 0 (normal) to 2 (urgent).</p>
|
||||
<p>You MUST configure your prowl API key into either the settings.js file like this</p>
|
||||
<p><pre>prowl: { prowlkey:'My-API-KEY' },</pre></p>
|
||||
<p>Or into a pushkey.js file in the directory <b>above</b> node-red.</p>
|
||||
<p><pre>module.exports = { prowlkey:'My-API-KEY' }</pre></p>
|
||||
<p>Uses Prowl so see <i><a href="https://www.prowlapp.com" target="_new">this link</a></i> for more details.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('prowl',{
|
||||
category: 'output',
|
||||
defaults: {
|
||||
title: {value:""},
|
||||
priority: {value:0,required:true,validate:RED.validators.number()},
|
||||
name: {value:""}
|
||||
},
|
||||
color:"#a7c9a0",
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "prowl.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
return this.name||this.title||"prowl";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
67
social/prowl/57-prowl.js
Normal file
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Copyright 2013 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.
|
||||
**/
|
||||
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
var Prowl = require('node-prowl');
|
||||
var util = require('util');
|
||||
|
||||
// Either add a line like this to settings.js
|
||||
// prowl: {prowlkey:'My-API-KEY'},
|
||||
// or create pushkey.js in dir ABOVE node-red, it just needs to be like
|
||||
// module.exports = {prowlkey:'My-API-KEY'}
|
||||
|
||||
try {
|
||||
var pushkey = require(process.env.NODE_RED_HOME+"/settings").prowl || require(process.env.NODE_RED_HOME+"/../pushkey.js");
|
||||
}
|
||||
catch(err) {
|
||||
util.log("[57-prowl.js] Error: Failed to load Prowl credentials");
|
||||
}
|
||||
|
||||
if (pushkey) {
|
||||
var prowl = new Prowl(pushkey.prowlkey);
|
||||
}
|
||||
|
||||
function ProwlNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.title = n.title;
|
||||
this.priority = parseInt(n.priority);
|
||||
if (this.priority > 2) this.priority = 2;
|
||||
if (this.priority < -2) this.priority = -2;
|
||||
var node = this;
|
||||
this.on("input",function(msg) {
|
||||
var titl = this.title||msg.topic||"Node-RED";
|
||||
var pri = msg.priority||this.priority;
|
||||
if (typeof(msg.payload) == 'object') {
|
||||
msg.payload = JSON.stringify(msg.payload);
|
||||
}
|
||||
if (pushkey) {
|
||||
try {
|
||||
prowl.push(msg.payload, titl, { priority: pri }, function(err, remaining) {
|
||||
if (err) node.error(err);
|
||||
node.log( remaining + ' calls to Prowl api during current hour.' );
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
node.error(err);
|
||||
}
|
||||
}
|
||||
else {
|
||||
node.warn("Prowl credentials not set/found. See node info.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType("prowl",ProwlNode);
|
BIN
social/prowl/icons/prowl.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
57
social/pushbullet/57-pushbullet.html
Normal file
@ -0,0 +1,57 @@
|
||||
<!--
|
||||
Copyright 2013 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.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="pushbullet">
|
||||
<div class="form-row">
|
||||
<label for="node-input-title"><i class="icon-flag"></i> Title</label>
|
||||
<input type="text" id="node-input-title" placeholder="Node-RED">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="pushbullet">
|
||||
<p>Uses PushBullet to push the <b>msg.payload</b> to an Android device that has PushBullet app installed.</p>
|
||||
<p>Optionally uses <b>msg.topic</b> to set the title, if not already set in the properties.</p>
|
||||
<p>You MUST configure both your API key and the target device ID. Either into settings.js like this</p>
|
||||
<p><pre>pushbullet: { pushbullet:'My-API-KEY', deviceid:'12345' },</pre></p>
|
||||
<p>Or as a pushkey.js file in the directory <b>above</b> node-red.<p>
|
||||
<p><pre>module.exports = { pushbullet:'My-API-KEY', deviceid:'12345' }</pre></p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('pushbullet',{
|
||||
category: 'output',
|
||||
defaults: {
|
||||
title: {value:""},
|
||||
name: {value:""}
|
||||
},
|
||||
color:"#a7c9a0",
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "bullet.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
return this.name||this.title||"pushbullet";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
64
social/pushbullet/57-pushbullet.js
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright 2013 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.
|
||||
**/
|
||||
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
var PushBullet = require('pushbullet');
|
||||
var util = require('util');
|
||||
|
||||
// Either add a line like this to settings.js
|
||||
// pushbullet: {pushbullet:'My-API-KEY', deviceid:'12345'},
|
||||
// or create pushkey.js in dir ABOVE node-red, it just needs to be like
|
||||
// module.exports = {pushbullet:'My-API-KEY', deviceid:'12345'}
|
||||
|
||||
try {
|
||||
var pushkey = RED.settings.pushbullet || require(process.env.NODE_RED_HOME+"/../pushkey.js");
|
||||
}
|
||||
catch(err) {
|
||||
util.log("[57-pushbullet.js] Error: Failed to load PushBullet credentials");
|
||||
}
|
||||
|
||||
if (pushkey) {
|
||||
var pusher = new PushBullet(pushkey.pushbullet);
|
||||
var deviceId = pushkey.deviceid;
|
||||
}
|
||||
|
||||
function PushbulletNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.title = n.title;
|
||||
var node = this;
|
||||
this.on("input",function(msg) {
|
||||
var titl = this.title||msg.topic||"Node-RED";
|
||||
if (typeof(msg.payload) == 'object') {
|
||||
msg.payload = JSON.stringify(msg.payload);
|
||||
}
|
||||
if (pushkey) {
|
||||
try {
|
||||
pusher.note(deviceId, titl, msg.payload, function(err, response) {
|
||||
if (err) node.error(err);
|
||||
console.log(response);
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
node.error(err);
|
||||
}
|
||||
}
|
||||
else {
|
||||
node.warn("Pushbullet credentials not set/found. See node info.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType("pushbullet",PushbulletNode);
|
BIN
social/pushbullet/icons/bullet.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
58
social/twilio/56-twilio.html
Normal file
@ -0,0 +1,58 @@
|
||||
<!--
|
||||
Copyright 2013 Andrew D Lindsay @AndrewDLindsay
|
||||
http://blog.thiseldo.co.uk
|
||||
|
||||
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.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="twilio">
|
||||
<div class="form-row">
|
||||
<label for="node-input-title"><i class="icon-flag"></i> Title</label>
|
||||
<input type="text" id="node-input-title" placeholder="Node-RED">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="twilio out">
|
||||
<p>Uses Twilio to send the <b>msg.payload</b> as a SMS to the configured number.</p>
|
||||
<p>Uses <b>msg.topic</b> to set the phone number, if not already set in the properties.</p>
|
||||
<p>You MUST configure both your Account SID and the Auth Token. Either into settings.js like this</p>
|
||||
<p><pre>twilio: { account:'My-ACCOUNT-SID', authtoken:'TWILIO-TOKEN', from:'FROM-NUMBER' },</pre></p>
|
||||
<p>Or as a twiliokey.js file in the directory <b>above</b> node-red.<p>
|
||||
<p><pre>module.exports = { account:'My-ACCOUNT-SID', authtoken:'TWILIO-TOKEN',from:'FROM-NUMBER' }</pre></p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('twilio out',{
|
||||
category: 'output',
|
||||
defaults: {
|
||||
title: {value:""},
|
||||
name: {value:""}
|
||||
},
|
||||
color:"#ed1c24",
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "twilio.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
return this.name||this.title||"twilio out";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
64
social/twilio/56-twilio.js
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright 2013 Andrew D Lindsay @AndrewDLindsay
|
||||
* http://blog.thiseldo.co.uk
|
||||
*
|
||||
* 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 RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
var util = require('util');
|
||||
|
||||
// Either add a line like this to settings.js
|
||||
// twilio: { account:'My-ACCOUNT-SID', authtoken:'TWILIO-TOKEN',from:'FROM-NUMBER' },
|
||||
// Or as a twiliokey.js file in the directory ABOVE node-red.
|
||||
// module.exports = { account:'My-ACCOUNT-SID', authtoken:'TWILIO-TOKEN',from:'FROM-NUMBER' }
|
||||
|
||||
try {
|
||||
var twiliokey = RED.settings.twilio || require(process.env.NODE_RED_HOME+"/../twiliokey.js");
|
||||
}
|
||||
catch(err) {
|
||||
util.log("[56-twilio.js] Error: Failed to load Twilio credentials");
|
||||
}
|
||||
|
||||
if (twiliokey) {
|
||||
var twilioClient = require('twilio')(twiliokey.account, twiliokey.authtoken);
|
||||
var fromNumber = twiliokey.from;
|
||||
}
|
||||
|
||||
function TwilioOutNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.title = n.title;
|
||||
var node = this;
|
||||
this.on("input",function(msg) {
|
||||
if (typeof(msg.payload) == 'object') {
|
||||
msg.payload = JSON.stringify(msg.payload);
|
||||
}
|
||||
if (twiliokey) {
|
||||
try {
|
||||
// Send SMS
|
||||
twilioClient.sendMessage( {to: msg.topic, from: fromNumber, body: msg.payload}, function(err, response) {
|
||||
if (err) node.error(err);
|
||||
//console.log(response);
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
node.error(err);
|
||||
}
|
||||
}
|
||||
else {
|
||||
node.warn("Twilio credentials not set/found. See node info.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType("twilio out",TwilioOutNode);
|
BIN
social/twilio/icons/twilio.png
Normal file
After Width: | Height: | Size: 717 B |
86
social/xmpp/92-xmpp.html
Normal file
@ -0,0 +1,86 @@
|
||||
<!--
|
||||
Copyright 2013 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.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="xmpp">
|
||||
<div class="form-row">
|
||||
<label for="node-input-server"><i class="icon-bookmark"></i> Server</label>
|
||||
<input type="text" id="node-input-server" placeholder="talk.google.com" style="width: 40%;" >
|
||||
<label for="node-input-port" style="margin-left: 10px; width: 35px; "> Port</label>
|
||||
<input type="text" id="node-input-port" placeholder="Port" style="width:45px">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label> </label>
|
||||
<input type="checkbox" id="node-input-sendObject" placeholder="" style="display: inline-block; width: auto; vertical-align: top;">
|
||||
<label for="node-input-sendObject" style="width: 70%;">Send complete msg object ?</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-to"><i class="icon-envelope"></i> To</label>
|
||||
<input type="text" id="node-input-to" placeholder="joe@gmail.com">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label> </label>
|
||||
<input type="checkbox" id="node-input-join" placeholder="" style="display: inline-block; width: auto; vertical-align: top;">
|
||||
<label for="node-input-join" style="width: 70%;">Is a Chat Room ?</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-nick"><i class="icon-user"></i> Nickname</label>
|
||||
<input type="text" id="node-input-nick" placeholder="Joe">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
<div class="form-tips">The <b>To</b> field is optional. If not set uses the <b>msg.topic</b> property of the message.</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="xmpp">
|
||||
<p>Connects to an XMPP server to send and receive messages.</p>
|
||||
<p>Incoming messages will appear as <b>msg.payload</b> on the first output, while <b>msg.topic</b> will contain who it is from.</p>
|
||||
<p>The second output will user presence and status in <b>msg.payload</b>.</p>
|
||||
<p>The <b>To</b> field is optional. If not set uses the <b>msg.topic</b> property of the message.</p>
|
||||
<p>If you are joining a room then the <b>To</b> field must be filled in.</p>
|
||||
<p>Uses the simple-xmpp module - you may also need to pre-configure your xmpp settings as per below.</p>
|
||||
<p>Either add to your settings.js file...</p>
|
||||
<p><pre>xmpp : { jid : "yourid", password: "password" },</pre></p>
|
||||
<p>Or create a file xmppkeys.js containing</p>
|
||||
<p><pre>module.exports = { jid: "yourid", password: "password" }</pre></p>
|
||||
<p>This <b>must</b> be located in the directory above node-red.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('xmpp',{
|
||||
category: 'advanced-function',
|
||||
color:"Silver",
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
server: { value:"",required:true},
|
||||
port: {value:5222,required:true},
|
||||
to: {value:""},
|
||||
join: {value:false},
|
||||
sendObject: {value:false},
|
||||
nick: {value:""}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:2,
|
||||
icon: "xmpp.png",
|
||||
label: function() {
|
||||
return this.name||this.server||"xmpp";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return (this.name||!this.server)?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
122
social/xmpp/92-xmpp.js
Normal file
@ -0,0 +1,122 @@
|
||||
/**
|
||||
* Copyright 2013 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.
|
||||
**/
|
||||
|
||||
var orig=console.warn;
|
||||
console.warn=(function() { // suppress warning from stringprep when not needed)
|
||||
var orig=console.warn;
|
||||
return function() {
|
||||
//orig.apply(console, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
var xmpp = require('simple-xmpp');
|
||||
console.warn = orig;
|
||||
|
||||
try {
|
||||
var xmppkey = require(process.env.NODE_RED_HOME+"/settings").xmpp || require(process.env.NODE_RED_HOME+"/../xmppkeys.js");
|
||||
} catch(err) {
|
||||
throw new Error("Failed to load XMPP credentials");
|
||||
}
|
||||
|
||||
function XmppNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.server = n.server;
|
||||
this.port = n.port;
|
||||
this.join = n.join || false;
|
||||
this.nick = n.nick || "Node-RED";
|
||||
this.sendAll = n.sendObject;
|
||||
this.to = n.to || "";
|
||||
var node = this;
|
||||
|
||||
setTimeout(function() {
|
||||
xmpp.connect({
|
||||
jid : xmppkey.jid,
|
||||
password : xmppkey.password,
|
||||
host : this.server,
|
||||
port : this.port,
|
||||
skipPresence : true,
|
||||
reconnect : false
|
||||
});
|
||||
}, 5000);
|
||||
|
||||
xmpp.on('online', function() {
|
||||
node.log('connected to '+node.server);
|
||||
xmpp.setPresence('online', node.nick+' online');
|
||||
if (node.join) {
|
||||
xmpp.join(node.to+'/'+node.nick);
|
||||
}
|
||||
});
|
||||
|
||||
xmpp.on('chat', function(from, message) {
|
||||
var msg = { topic:from, payload:message };
|
||||
node.send([msg,null]);
|
||||
});
|
||||
|
||||
xmpp.on('groupchat', function(conference, from, message, stamp) {
|
||||
var msg = { topic:from, payload:message, room:conference };
|
||||
if (from != node.nick) { node.send([msg,null]); }
|
||||
});
|
||||
|
||||
//xmpp.on('chatstate', function(from, state) {
|
||||
//console.log('%s is currently %s', from, state);
|
||||
//var msg = { topic:from, payload:state };
|
||||
//node.send([null,msg]);
|
||||
//});
|
||||
|
||||
xmpp.on('buddy', function(jid, state, statusText) {
|
||||
node.log(jid+" is "+state+" : "+statusText);
|
||||
var msg = { topic:jid, payload: { presence:state, status:statusText} };
|
||||
node.send([null,msg]);
|
||||
});
|
||||
|
||||
xmpp.on('error', function(err) {
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
xmpp.on('close', function(err) {
|
||||
node.log('connection closed');
|
||||
});
|
||||
|
||||
xmpp.on('subscribe', function(from) {
|
||||
xmpp.acceptSubscription(from);
|
||||
});
|
||||
|
||||
this.on("input", function(msg) {
|
||||
var to = msg.topic;
|
||||
if (node.to != "") { to = node.to; }
|
||||
if (node.sendAll) {
|
||||
xmpp.send(to, JSON.stringify(msg), node.join);
|
||||
}
|
||||
else {
|
||||
xmpp.send(to, msg.payload, node.join);
|
||||
}
|
||||
});
|
||||
|
||||
this.on("close", function() {
|
||||
xmpp.setPresence('offline');
|
||||
try {
|
||||
xmpp.disconnect();
|
||||
// TODO - DCJ NOTE... this is not good. It leaves the connection up over a restart - which will end up with bad things happening...
|
||||
// (but requires the underlying xmpp lib to be fixed, which does have an open bug request on fixing the close method - and a work around.
|
||||
// see - https://github.com/simple-xmpp/node-simple-xmpp/issues/12 for the fix
|
||||
} catch(e) {
|
||||
this.warn("Due to an underlying bug in the xmpp library this does not disconnect old sessions. This is bad... A restart would be better.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType("xmpp",XmppNode);
|
BIN
social/xmpp/icons/xmpp.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
122
storage/leveldb/67-leveldb.html
Normal file
@ -0,0 +1,122 @@
|
||||
<!--
|
||||
Copyright 2013 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.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="leveldbase">
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-db"><i class="icon-briefcase"></i> Database</label>
|
||||
<input type="text" id="node-config-input-db" placeholder="database path/name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('leveldbase',{
|
||||
category: 'config',
|
||||
defaults: {
|
||||
db: {value:"",required:true}
|
||||
},
|
||||
label: function() {
|
||||
return this.db;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-template-name="leveldb in">
|
||||
<div class="form-row node-input-level">
|
||||
<label for="node-input-level"><i class="icon-briefcase"></i> Database</label>
|
||||
<input type="text" id="node-input-level">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="leveldb in">
|
||||
<p>Uses <a href="https://code.google.com/p/leveldb/" target="_new"><i>LevelDB</i></a> for a simple key value pair database.</p>
|
||||
<p>Use this node to <b>get</b>, or retrieve the data already saved in the database.</p>
|
||||
<p><b>msg.topic</b> must hold the <i>key</i> for the database, and the result is returned in <b>msg.payload</b>.</p>
|
||||
<p>If nothing is found for the key then <i>null</i> is returned,</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('leveldb in',{
|
||||
category: 'storage-input',
|
||||
color:"#dbb84d",
|
||||
defaults: {
|
||||
level: {type:"leveldbase",required:true},
|
||||
name: {value:""}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
icon: "leveldb.png",
|
||||
label: function() {
|
||||
var levelNode = RED.nodes.node(this.level);
|
||||
return this.name||(levelNode?levelNode.label():"leveldb");
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/x-red" data-template-name="leveldb out">
|
||||
<div class="form-row node-input-level">
|
||||
<label for="node-input-level"><i class="icon-briefcase"></i> Database</label>
|
||||
<input type="text" id="node-input-level">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-operation"><i class="icon-wrench"></i> Operation</label>
|
||||
<select type="text" id="node-input-operation" style="display: inline-block; vertical-align: top;">
|
||||
<option value="store">Store</option>
|
||||
<option value="delete">Delete</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/x-red" data-help-name="leveldb out">
|
||||
<p>Uses <a href="https://code.google.com/p/leveldb/" target="_new"><i>LevelDB</i></a> for a simple key value pair database.</p>
|
||||
<p>Use this node to either <b>put</b> (store) the <b>msg.payload</b> to the named database file, using <b>msg.topic</b> as the key.</p>
|
||||
<p>To <b>delete</b> information select delete in the properties dialogue and again use <b>msg.topic</b> as the key.</b>.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('leveldb out',{
|
||||
category: 'storage-output',
|
||||
color:"#dbb84d",
|
||||
defaults: {
|
||||
level: {type:"leveldbase",required:true},
|
||||
operation: {value:"store"},
|
||||
name: {value:""}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "leveldb.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
var levelNode = RED.nodes.node(this.level);
|
||||
return this.name||(levelNode?levelNode.label():"leveldb");
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
94
storage/leveldb/67-leveldb.js
Normal file
@ -0,0 +1,94 @@
|
||||
/**
|
||||
* Copyright 2013 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.
|
||||
**/
|
||||
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
var lvldb = require('level');
|
||||
|
||||
function LevelNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.dbname = n.db;
|
||||
var node = this;
|
||||
lvldb(this.dbname, function(err, db) {
|
||||
if (err) node.error(err);
|
||||
node.db = db;
|
||||
});
|
||||
this.on('close', function() {
|
||||
if (node.db) { node.db.close(); }
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("leveldbase",LevelNode);
|
||||
|
||||
|
||||
function LevelDBNodeIn(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.level = n.level;
|
||||
this.levelConfig = RED.nodes.getNode(this.level);
|
||||
|
||||
if (this.levelConfig) {
|
||||
var node = this;
|
||||
node.on("input", function(msg) {
|
||||
if (typeof msg.topic === 'string') {
|
||||
node.levelConfig.db.get(msg.topic, function(err, value) {
|
||||
if (err) {
|
||||
//node.warn(err);
|
||||
// for some reason they treat nothing found as an error...
|
||||
msg.payload = null; // so we should return null
|
||||
}
|
||||
else { msg.payload = value; }
|
||||
node.send(msg);
|
||||
});
|
||||
}
|
||||
else {
|
||||
if (typeof msg.topic !== 'string') node.error("msg.topic (the key is not defined");
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.error("LevelDB database name not configured");
|
||||
}
|
||||
}
|
||||
RED.nodes.registerType("leveldb in",LevelDBNodeIn);
|
||||
|
||||
|
||||
function LevelDBNodeOut(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.level = n.level;
|
||||
this.operation = n.operation;
|
||||
this.levelConfig = RED.nodes.getNode(this.level);
|
||||
|
||||
if (this.levelConfig) {
|
||||
var node = this;
|
||||
node.on("input", function(msg) {
|
||||
if (typeof msg.topic === 'string') {
|
||||
if (node.operation === "delete") {
|
||||
node.levelConfig.db.del(msg.topic);
|
||||
}
|
||||
else {
|
||||
node.levelConfig.db.put(msg.topic, msg.payload, function(err) {
|
||||
if (err) node.error(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (typeof msg.topic !== 'string') node.error("msg.topic (the key is not defined");
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.error("LevelDB database name not configured");
|
||||
}
|
||||
}
|
||||
RED.nodes.registerType("leveldb out",LevelDBNodeOut);
|
134
storage/mysql/68-mysql.html
Normal file
@ -0,0 +1,134 @@
|
||||
<!--
|
||||
Copyright 2013 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.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="MySQLdatabase">
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-host"><i class="icon-briefcase"></i> Host</label>
|
||||
<input type="text" id="node-config-input-host" placeholder="localhost">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-port"><i class="icon-briefcase"></i> Port</label>
|
||||
<input type="text" id="node-config-input-port" placeholder="3306">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-user"><i class="icon-briefcase"></i> User</label>
|
||||
<input type="text" id="node-config-input-user" placeholder="JoeDemo">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-pass"><i class="icon-briefcase"></i> Password</label>
|
||||
<input type="password" id="node-config-input-pass" placeholder="mySecret">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-db"><i class="icon-briefcase"></i> Database</label>
|
||||
<input type="text" id="node-config-input-db" placeholder="myDatabase">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('MySQLdatabase',{
|
||||
category: 'config',
|
||||
defaults: {
|
||||
host: {value:"127.0.0.1",required:true},
|
||||
port: {value:"3306",required:true},
|
||||
//user: {value:"",required:true},
|
||||
//pass: {value:"",required:true},
|
||||
db: {value:"",required:true}
|
||||
},
|
||||
label: function() {
|
||||
return this.db;
|
||||
},
|
||||
oneditprepare: function() {
|
||||
$.getJSON('MySQLdatabase/'+this.id,function(data) {
|
||||
if (data.user) {
|
||||
$('#node-config-input-user').val(data.user);
|
||||
}
|
||||
if (data.hasPassword) {
|
||||
$('#node-config-input-pass').val('__PWRD__');
|
||||
} else {
|
||||
$('#node-config-input-pass').val('');
|
||||
}
|
||||
|
||||
});
|
||||
},
|
||||
oneditsave: function() {
|
||||
var newUser = $('#node-config-input-user').val();
|
||||
var newPass = $('#node-config-input-pass').val();
|
||||
var credentials = {};
|
||||
credentials.user = newUser;
|
||||
if (newPass != '__PWRD__') {
|
||||
credentials.password = newPass;
|
||||
}
|
||||
$.ajax({
|
||||
url: 'MySQLdatabase/'+this.id,
|
||||
type: 'POST',
|
||||
data: credentials,
|
||||
success:function(result){}
|
||||
});
|
||||
},
|
||||
ondelete: function() {
|
||||
$.ajax({
|
||||
url: 'MySQLdatabase/'+this.id,
|
||||
type: 'DELETE',
|
||||
success: function(result) {}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/x-red" data-template-name="mysql">
|
||||
<div class="form-row">
|
||||
<label for="node-input-mydb"><i class="icon-briefcase"></i> Database</label>
|
||||
<input type="text" id="node-input-mydb">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="mysql">
|
||||
<p>Allows basic access to a MySQL database.</p>
|
||||
<p>This node uses the <b>query</b> operation against the configured database. This does allow both INSERTS and DELETES.
|
||||
By it's very nature it allows SQL injection... so <i>be careful out there...</i></p>
|
||||
<p><b>msg.topic</b> must hold the <i>query</i> for the database, and the result is returned in <b>msg.payload</b>.</p>
|
||||
<p>Typically the returned payload will be an array of the result rows.</p>
|
||||
<p>If nothing is found for the key then <i>null</i> is returned,</p>
|
||||
<p>The reconnect timeout in milliseconds can be changed by adding a line to <b>settings.js</b>
|
||||
<pre>mysqlReconnectTime: 30000,</pre></p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('mysql',{
|
||||
category: 'storage-input',
|
||||
color:"#e97b00",
|
||||
defaults: {
|
||||
mydb: {type:"MySQLdatabase",required:true},
|
||||
name: {value:""}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
icon: "db.png",
|
||||
label: function() {
|
||||
var levelNode = RED.nodes.node(this.mydb);
|
||||
return this.name||(levelNode?levelNode.label():"mysql");
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
195
storage/mysql/68-mysql.js
Normal file
@ -0,0 +1,195 @@
|
||||
/**
|
||||
* Copyright 2013 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.
|
||||
**/
|
||||
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
var reconnect = RED.settings.mysqlReconnectTime || 30000;
|
||||
var mysqldb = require('mysql');
|
||||
var querystring = require('querystring');
|
||||
|
||||
RED.app.get('/MySQLdatabase/:id',function(req,res) {
|
||||
var credentials = RED.nodes.getCredentials(req.params.id);
|
||||
if (credentials) {
|
||||
res.send(JSON.stringify({user:credentials.user,hasPassword:(credentials.password&&credentials.password!="")}));
|
||||
} else {
|
||||
res.send(JSON.stringify({}));
|
||||
}
|
||||
});
|
||||
|
||||
RED.app.delete('/MySQLdatabase/:id',function(req,res) {
|
||||
RED.nodes.deleteCredentials(req.params.id);
|
||||
res.send(200);
|
||||
});
|
||||
|
||||
RED.app.post('/MySQLdatabase/:id',function(req,res) {
|
||||
var body = "";
|
||||
req.on('data', function(chunk) {
|
||||
body+=chunk;
|
||||
});
|
||||
req.on('end', function(){
|
||||
var newCreds = querystring.parse(body);
|
||||
var credentials = RED.nodes.getCredentials(req.params.id)||{};
|
||||
if (newCreds.user == null || newCreds.user == "") {
|
||||
delete credentials.user;
|
||||
} else {
|
||||
credentials.user = newCreds.user;
|
||||
}
|
||||
if (newCreds.password == "") {
|
||||
delete credentials.password;
|
||||
} else {
|
||||
credentials.password = newCreds.password||credentials.password;
|
||||
}
|
||||
RED.nodes.addCredentials(req.params.id,credentials);
|
||||
res.send(200);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function MySQLNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.host = n.host;
|
||||
this.port = n.port;
|
||||
|
||||
this.connected = false;
|
||||
this.connecting = false;
|
||||
|
||||
if (n.user) {
|
||||
var credentials = {};
|
||||
credentials.user = n.user;
|
||||
credentials.password = n.pass;
|
||||
RED.nodes.addCredentials(n.id,credentials);
|
||||
this.user = n.user;
|
||||
this.password = n.pass;
|
||||
} else {
|
||||
var credentials = RED.nodes.getCredentials(n.id);
|
||||
if (credentials) {
|
||||
this.user = credentials.user;
|
||||
this.password = credentials.password;
|
||||
}
|
||||
}
|
||||
|
||||
this.dbname = n.db;
|
||||
var node = this;
|
||||
|
||||
function doConnect() {
|
||||
node.connecting = true;
|
||||
node.connection = mysqldb.createConnection({
|
||||
host : node.host,
|
||||
port : node.port,
|
||||
user : node.user,
|
||||
password : node.password,
|
||||
database : node.dbname,
|
||||
insecureAuth: true
|
||||
});
|
||||
|
||||
node.connection.connect(function(err) {
|
||||
node.connecting = false;
|
||||
if (err) {
|
||||
node.warn(err);
|
||||
node.tick = setTimeout(doConnect, reconnect);
|
||||
} else {
|
||||
node.connected = true;
|
||||
}
|
||||
});
|
||||
|
||||
node.connection.on('error', function(err) {
|
||||
node.connected = false;
|
||||
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
|
||||
doConnect(); // silently reconnect...
|
||||
} else {
|
||||
node.error(err);
|
||||
doConnect();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.connect = function() {
|
||||
if (!this.connected && !this.connecting) {
|
||||
doConnect();
|
||||
}
|
||||
}
|
||||
|
||||
this.on('close', function () {
|
||||
if (this.tick) { clearTimeout(this.tick); }
|
||||
if (this.connection) {
|
||||
node.connection.end(function(err) {
|
||||
if (err) node.error(err);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("MySQLdatabase",MySQLNode);
|
||||
|
||||
|
||||
function MysqlDBNodeIn(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.mydb = n.mydb;
|
||||
this.mydbConfig = RED.nodes.getNode(this.mydb);
|
||||
|
||||
if (this.mydbConfig) {
|
||||
this.mydbConfig.connect();
|
||||
var node = this;
|
||||
node.on("input", function(msg) {
|
||||
if (typeof msg.topic === 'string') {
|
||||
//console.log("query:",msg.topic);
|
||||
node.mydbConfig.connection.query(msg.topic, function(err, rows) {
|
||||
if (err) { node.warn(err); }
|
||||
else {
|
||||
msg.payload = rows;
|
||||
node.send(msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
if (typeof msg.topic !== 'string') node.error("msg.topic : the query is not defined as a string");
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.error("MySQL database not configured");
|
||||
}
|
||||
}
|
||||
RED.nodes.registerType("mysql",MysqlDBNodeIn);
|
||||
|
||||
|
||||
//function MysqlDBNodeOut(n) {
|
||||
//RED.nodes.createNode(this,n);
|
||||
//this.level = n.level;
|
||||
//this.operation = n.operation;
|
||||
//this.levelConfig = RED.nodes.getNode(this.level);
|
||||
|
||||
//if (this.levelConfig) {
|
||||
//var node = this;
|
||||
//node.on("input", function(msg) {
|
||||
//if (typeof msg.topic === 'string') {
|
||||
//if (node.operation === "delete") {
|
||||
//node.levelConfig.db.del(msg.topic);
|
||||
//}
|
||||
//else {
|
||||
//node.levelConfig.db.put(msg.topic, msg.payload, function(err) {
|
||||
//if (err) node.error(err);
|
||||
//});
|
||||
//}
|
||||
//}
|
||||
//else {
|
||||
//if (typeof msg.topic !== 'string') node.error("msg.topic : the key is not defined");
|
||||
//}
|
||||
//});
|
||||
//}
|
||||
//else {
|
||||
//this.error("MySQL database not configured");
|
||||
//}
|
||||
//}
|
||||
//RED.nodes.registerType("mysql out",MysqlDBNodeOut);
|
@ -13,7 +13,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
var RED = require("../../red/red");
|
||||
|
||||
var RED = require(process.env.NODE_RED_HOME+"/red/red");
|
||||
var SunCalc = require('suncalc');
|
||||
|
||||
function SunNode(n) {
|
||||
|
BIN
time/icons/sun.png
Normal file
After Width: | Height: | Size: 383 B |