Add rawserial, mpd, mysql and swearfilter nodes.

This commit is contained in:
Dave C-J 2013-11-03 21:29:20 +00:00
parent 7c3b1d7ff4
commit 5e67f41114
9 changed files with 707 additions and 0 deletions

View 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>
</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>

View File

@ -0,0 +1,28 @@
/**
* 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("../../red/red");
var badwords = require('badwords');
function BadwordsNode(n) {
RED.nodes.createNode(this,n);
var node = this;
this.on("input", function(msg) {
if (badwords.ok(msg.payload)) { node.send(msg); }
});
}
RED.nodes.registerType("badwords",BadwordsNode);

View 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>

View 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("../../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);

80
social/music/69-mpd.html Normal file
View 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
View 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 { node.error(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);

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

147
storage/mysql/68-mysql.html Normal file
View File

@ -0,0 +1,147 @@
<!--
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="text" 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;
}
});
</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>
</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>
<!--
<script type="text/x-red" data-template-name="mysql 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="mysql out">
<p>Allows access to a MySQL 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('mysql out',{
category: 'storage-output',
color:"#e97b00",
defaults: {
level: {type:"MySQLdatabase",required:true},
operation: {value:"store"},
name: {value:""}
},
inputs:1,
outputs:0,
icon: "db.png",
align: "right",
label: function() {
var levelNode = RED.nodes.node(this.level);
return this.name||(levelNode?levelNode.label():"mysql");
},
labelStyle: function() {
return this.name?"node_label_italic":"";
}
});
</script>
-->

108
storage/mysql/68-mysql.js Normal file
View File

@ -0,0 +1,108 @@
/**
* 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 mysqldb = require('mysql');
function MySQLNode(n) {
RED.nodes.createNode(this,n);
this.host = n.host;
this.port = n.port;
this.user = n.user;
this.password = n.pass;
this.dbname = n.db;
var node = this;
node.connection = mysqldb.createConnection({
host : node.host,
port : node.port,
user : node.user,
password : node.password,
database : node.dbname
});
node.connection.connect(function(err) {
if (err) node.error(err);
});
node.on('close', function () {
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) {
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);