1
0
mirror of https://github.com/node-red/node-red-nodes.git synced 2023-10-10 13:36:58 +02:00
Conflicts:
	hardware/BBB/README.md
This commit is contained in:
Maxwell Hadley 2014-03-03 20:39:09 +00:00
commit 982a68d8eb
23 changed files with 849 additions and 111 deletions

View File

@ -96,6 +96,8 @@ Uses a simple read of the serial port as a file to input data. You **must** set
**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...* **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...*
**69-ddbout** - Support output to Amazon DynamoDB.
### Time ### 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, **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,

View File

@ -63,7 +63,6 @@ of the pulse, or by both edges. Two outputs are provided:
Separate scaling factors are applied to each output. Output messages are generated Separate scaling factors are applied to each output. Output messages are generated
at regular intervals, controlled by an internal timer. The count can be cleared at regular intervals, controlled by an internal timer. The count can be cleared
or set to an arbitrary value by an input message who's topic contains 'load'. or set to an arbitrary value by an input message who's topic contains 'load'.
Useful for energy monitoring, e.g. electricty meter pulse outputs. Useful for energy monitoring, e.g. electricty meter pulse outputs.
The 'instantaneous' pulse rate is derived from either the time between the last two The 'instantaneous' pulse rate is derived from either the time between the last two

View File

@ -51,7 +51,7 @@ function sensorTagNode(n) {
sensorTag.enableIrTemperature(function(){}); sensorTag.enableIrTemperature(function(){});
sensorTag.on('irTemperatureChange', sensorTag.on('irTemperatureChange',
function(objectTemperature, ambientTemperature){ function(objectTemperature, ambientTemperature){
var msg = {'topic': node.topic + '/tempature'}; var msg = {'topic': node.topic + '/temperature'};
msg.payload = {'object': objectTemperature.toFixed(1), msg.payload = {'object': objectTemperature.toFixed(1),
'ambient':ambientTemperature.toFixed(1) 'ambient':ambientTemperature.toFixed(1)
}; };

120
io/emoncms/88-emoncms.html Normal file
View File

@ -0,0 +1,120 @@
<!--
Copyright 2013 Henrik Olsson henols@gmail.com
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="emoncms">
<div class="form-row">
<label for="node-input-emonServer"><i class="icon-globe"></i> Emoncms server</label>
<input type="text" id="node-input-emonServer">
</div>
<div class="form-row">
<label for="node-input-topic"><i class="icon-tasks"></i> Topic</label>
<input type="text" id="node-input-topic" placeholder="">
</div>
<div class="form-row">
<label for="node-input-nodegroup"><i class="icon-tag"></i> Node Group</label>
<input type="text" id="node-input-nodegroup" placeholder="">
</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="Emoncms">
</div>
<div class="form-tips">Topic is not mandatory, if Topic is left blank <b>msg.topic</b> will used. Topic overrides <b>msg.topic</b></br>
Node Group (numeric) is not mandatory, if Node Group is left blank <b>msg.nodegrpup</b> will used. Node Group overrides <b>msg.nodegroup</b></div>
</script>
<script type="text/x-red" data-help-name="emoncms">
<p>Performs post to Emoncms.</p>
<p>Topic is not mandatory, if Topic is left blank <b>msg.topic</b> will used. Topic overrides <b>msg.topic</b></p>
<p>Node Group (numeric) is not mandatory, if Node Group is left blank <b>msg.nodegrpup</b> will used. Node overrides <b>msg.nodegrpup</b></p>
</script>
<script type="text/javascript">
RED.nodes.registerType('emoncms',{
category: 'output',
color:"rgb(91, 192, 222)",
defaults: {
name: {value:"Emoncms"},
emonServer: {type:"emoncms-server", required:true},
topic: {value:""},
nodegroup: {value:""}
},
inputs:1,
outputs:0,
icon: "emoncms.png",
align: "right",
label: function() {
return this.name||this.baseurl;
},
labelStyle: function() {
return this.name?"node_label_italic":"";
}
});
</script>
<script type="text/x-red" data-template-name="emoncms-server">
<div class="form-row">
<label for="node-config-input-server"><i class="icon-globe"></i> Base URL</label>
<input type="text" id="node-config-input-server">
</div>
<div class="form-row">
<label for="node-config-input-apikey"><i class="icon-tasks"></i> API key</label>
<input type="text" id="node-config-input-apikey">
</div>
<div class="form-row">
<label for="node-config-input-name"><i class="icon-tag"></i> Name</label>
<input type="text" id="node-config-input-name">
</div>
<div class="form-tips">The <b>Base URL</b> is the URL to the Emoncms root directory.</div>
</script>
<script type="text/javascript">
RED.nodes.registerType('emoncms-server',{
category: 'config',
defaults: {
server: {value:"http://localhost",required:true},
// apikey: {value:"",required:true},
name: {value:""}
},
label: function() {
return this.name||this.server;
},
oneditprepare: function() {
$.getJSON('emoncms-server/'+this.id,function(data) {
if (data.apikey) {
$('#node-config-input-apikey').val(data.apikey);
}
});
},
oneditsave: function() {
var newApikey = $('#node-config-input-apikey').val();
var credentials = {};
credentials.apikey = newApikey;
$.ajax({
url: 'emoncms-server/'+this.id,
type: 'POST',
data: credentials,
success:function(result){}
});
},
ondelete: function() {
$.ajax({
url: 'emoncms-server/'+this.id,
type: 'DELETE',
success: function(result) {}
});
}
});
</script>

111
io/emoncms/88-emoncms.js Normal file
View File

@ -0,0 +1,111 @@
/**
* Copyright 2013 Henrik Olsson henols@gmail.com
*
* 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");
//The Server Definition - this opens (and closes) the connection
function EmoncmsServerNode(n) {
RED.nodes.createNode(this,n);
this.server = n.server;
this.name = n.name;
var credentials = RED.nodes.getCredentials(n.id);
if (credentials) {
this.apikey = credentials.apikey;
}
}
RED.nodes.registerType("emoncms-server",EmoncmsServerNode);
var querystring = require('querystring');
RED.app.get('/emoncms-server/:id',function(req,res) {
var credentials = RED.nodes.getCredentials(req.params.id);
if (credentials) {
res.send(JSON.stringify({apikey:credentials.apikey}));
} else {
res.send(JSON.stringify({}));
}
});
RED.app.delete('/emoncms-server/:id',function(req,res) {
RED.nodes.deleteCredentials(req.params.id);
res.send(200);
});
RED.app.post('/emoncms-server/: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.apikey == null || newCreds.apikey == "") {
delete credentials.apikey;
} else {
credentials.apikey = newCreds.apikey;
}
RED.nodes.addCredentials(req.params.id,credentials);
res.send(200);
});
});
function Emoncms(n) {
RED.nodes.createNode(this,n);
this.emonServer = n.emonServer;
var sc = RED.nodes.getNode(this.emonServer);
this.baseurl = sc.server;
this.apikey = sc.apikey;
this.topic = n.topic ||"";
this.nodegroup = n.nodegroup || "";
var node = this;
if (this.baseurl.substring(0,5) === "https") { var http = require("https"); }
else { var http = require("http"); }
this.on("input", function(msg) {
var topic = this.topic || msg.topic;
var nodegroup = this.nodegroup || msg.nodegroup;
this.url = this.baseurl + '/input/post.json?json={' + topic + ':' + msg.payload+'}&apikey='+this.apikey;
if(nodegroup != ""){
this.url += '&node='+nodegroup;
}
node.log("[emoncms] "+this.url);
http.get(this.url, function(res) {
node.log("Http response: " + res.statusCode);
msg.rc = res.statusCode;
msg.payload = "";
if ((msg.rc != 200) && (msg.rc != 404)) {
node.send(msg);
}
res.setEncoding('utf8');
res.on('data', function(chunk) {
msg.payload += chunk;
});
res.on('end', function() {
node.send(msg);
});
}).on('error', function(e) {
// node.error(e);
msg.rc = 503;
msg.payload = e;
node.send(msg);
});
});
}
RED.nodes.registerType("emoncms",Emoncms);

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 933 B

View File

@ -29,14 +29,12 @@
</div> </div>
</script> </script>
<!-- Next, some simple help text is provided for the node. -->
<script type="text/x-red" data-help-name="ping"> <script type="text/x-red" data-help-name="ping">
<p>Pings a machine and returns the trip time in mS.</p> <p>Pings a machine and returns the trip time in mS.</p>
<p>Returns <b>false</b> if no response received within 3 seconds, or if the host is unresolveable.</p> <p>Returns <b>false</b> if no response received within 3 seconds, or if the host is unresolveable.</p>
<p>Default ping is every 20 seconds but can be configured.</p> <p>Default ping is every 20 seconds but can be configured.</p>
</script> </script>
<!-- Finally, the node type is registered along with all of its properties -->
<script type="text/javascript"> <script type="text/javascript">
RED.nodes.registerType('ping',{ RED.nodes.registerType('ping',{
category: 'advanced-input', category: 'advanced-input',

View File

@ -30,12 +30,12 @@ function PingNode(n) {
else if (plat.match(/^win/)) ex = spawn('ping', ['-n', '1', '-w', '5000', 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 if (plat == "darwin") ex = spawn('ping', ['-n', '-t', '5', '-c', '1', node.host]);
else node.error("Sorry - your platform - "+plat+" - is not recognised."); else node.error("Sorry - your platform - "+plat+" - is not recognised.");
var res = ""; var res = false;
ex.stdout.on('data', function (data) { ex.stdout.on('data', function (data) {
//console.log('[ping] stdout: ' + data.toString()); //console.log('[ping] stdout: ' + data.toString());
var regex = /time.(.*)ms/; var regex = /from.*time.(.*)ms/;
var m = regex.exec(data.toString())||[""]; var m = regex.exec(data.toString())||"";
res = Number(m[1]); if (m != '') { res = Number(m[1]); }
}); });
ex.stderr.on('data', function (data) { ex.stderr.on('data', function (data) {
//console.log('[ping] stderr: ' + data); //console.log('[ping] stderr: ' + data);

View File

@ -28,7 +28,7 @@ exec("which mpd",function(err,stdout,stderr) {
exec("netstat -an | grep LISTEN | grep 6600",function(err,stdout,stderr) { exec("netstat -an | grep LISTEN | grep 6600",function(err,stdout,stderr) {
if (stdout.indexOf('6600') == -1) { if (stdout.indexOf('6600') == -1) {
util.log('[69-mpd.js] Error: MPD daemon not listening on port 6600. Please start MPD.'); util.log('[69-mpd.js] Warning: MPD daemon not listening on port 6600. Please start MPD.');
return; return;
} }
komponist.createConnection(6600, 'localhost', function(err, client) { komponist.createConnection(6600, 'localhost', function(err, client) {

View File

@ -47,6 +47,7 @@ function ProwlNode(n) {
if (typeof(msg.payload) == 'object') { if (typeof(msg.payload) == 'object') {
msg.payload = JSON.stringify(msg.payload); msg.payload = JSON.stringify(msg.payload);
} }
else { msg.payload = msg.payload.toString(); }
if (pushkey) { if (pushkey) {
try { try {
prowl.push(msg.payload, titl, { priority: pri }, function(err, remaining) { prowl.push(msg.payload, titl, { priority: pri }, function(err, remaining) {

View File

@ -29,9 +29,10 @@
<p>Uses PushBullet to push the <b>msg.payload</b> to an Android device that has PushBullet app installed.</p> <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>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>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><pre>pushbullet: { pushbullet:'My-API-KEY', deviceid:'xyzzyWabc' },</pre></p>
<p>Or as a pushkey.js file in the directory <b>above</b> node-red.<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> <p><pre>module.exports = { pushbullet:'My-API-KEY', deviceid:'xyzzyWabc' }</pre></p>
<p>The deviceid can be found by hovering over you required device on the <a href="https://www.pushbullet.com/">PushBullet website</a>.</p>
</script> </script>
<script type="text/javascript"> <script type="text/javascript">

View File

@ -44,8 +44,9 @@ function PushbulletNode(n) {
if (typeof(msg.payload) == 'object') { if (typeof(msg.payload) == 'object') {
msg.payload = JSON.stringify(msg.payload); msg.payload = JSON.stringify(msg.payload);
} }
if (pushkey) { if (pushkey.pushbullet && pushkey.deviceid) {
try { try {
if (!isNaN(deviceId)) { deviceId = Number(deviceId); }
pusher.note(deviceId, titl, msg.payload, function(err, response) { pusher.note(deviceId, titl, msg.payload, function(err, response) {
if (err) node.error(err); if (err) node.error(err);
console.log(response); console.log(response);

View File

@ -15,15 +15,16 @@
limitations under the License. limitations under the License.
--> -->
<script type="text/x-red" data-template-name="twilio"> <script type="text/x-red" data-template-name="twilio out">
<div class="form-row"> <div class="form-row">
<label for="node-input-title"><i class="icon-flag"></i> Title</label> <label for="node-input-number"><i class="icon-envelope"></i> SMS to</label>
<input type="text" id="node-input-title" placeholder="Node-RED"> <input type="text" id="node-input-number" placeholder="01234 5678901">
</div> </div>
<div class="form-row"> <div class="form-row">
<label for="node-input-name"><i class="icon-tag"></i> Name</label> <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="Name">
</div> </div>
<div class="form-tips">Tip - leave Number blank to use <b>msg.topic</b> to set the number.</div>
</script> </script>
<script type="text/x-red" data-help-name="twilio out"> <script type="text/x-red" data-help-name="twilio out">
@ -39,7 +40,7 @@
RED.nodes.registerType('twilio out',{ RED.nodes.registerType('twilio out',{
category: 'output', category: 'output',
defaults: { defaults: {
title: {value:""}, number: {value:""},
name: {value:""} name: {value:""}
}, },
color:"#ed1c24", color:"#ed1c24",
@ -48,7 +49,7 @@
icon: "twilio.png", icon: "twilio.png",
align: "right", align: "right",
label: function() { label: function() {
return this.name||this.title||"twilio out"; return this.name||this.title||"twilio";
}, },
labelStyle: function() { labelStyle: function() {
return this.name?"node_label_italic":""; return this.name?"node_label_italic":"";

View File

@ -37,7 +37,7 @@ if (twiliokey) {
function TwilioOutNode(n) { function TwilioOutNode(n) {
RED.nodes.createNode(this,n); RED.nodes.createNode(this,n);
this.title = n.title; this.number = n.number;
var node = this; var node = this;
this.on("input",function(msg) { this.on("input",function(msg) {
if (typeof(msg.payload) == 'object') { if (typeof(msg.payload) == 'object') {
@ -46,7 +46,8 @@ function TwilioOutNode(n) {
if (twiliokey) { if (twiliokey) {
try { try {
// Send SMS // Send SMS
twilioClient.sendMessage( {to: msg.topic, from: fromNumber, body: msg.payload}, function(err, response) { var tonum = node.number || msg.topic;
twilioClient.sendMessage( {to: tonum, from: fromNumber, body: msg.payload}, function(err, response) {
if (err) node.error(err); if (err) node.error(err);
//console.log(response); //console.log(response);
}); });
@ -60,5 +61,4 @@ function TwilioOutNode(n) {
} }
}); });
} }
RED.nodes.registerType("twilio out",TwilioOutNode); RED.nodes.registerType("twilio out",TwilioOutNode);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 717 B

After

Width:  |  Height:  |  Size: 553 B

View File

@ -0,0 +1,58 @@
<!--
Copyright 2013 Wolfgang Nagele
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="ddb out">
<div class="form-row">
<label for="node-input-credentials"><i class="icon-tag"></i> Credentials</label>
<input type="text" id="node-input-credentials">
</div>
<div class="form-row">
<label for="node-input-region"><i class="icon-th"></i> Region</label>
<input type="text" id="node-input-region">
</div>
<div class="form-row">
<label for="node-input-table"><i class="icon-tasks"></i> Table</label>
<input type="text" id="node-input-table" placeholder="Table">
</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="ddb out">
<p>A Amazon DynamoDB output node.</p>
</script>
<script type="text/javascript">
RED.nodes.registerType("ddb out", {
category: "storage-output",
color: "#ffaaaa",
defaults: {
credentials: { type: "aws credentials", required: true },
region: { value: "us-east-1", required: true },
table: { value: "", required: true },
name: { value: "" }
},
inputs: 1,
outputs: 0,
icon: "db.png",
align: "right",
label: function() {
return this.name || this.table + " (" + this.region + ")";
}
});
</script>

44
storage/ddb/69-ddbout.js Normal file
View File

@ -0,0 +1,44 @@
/**
* Copyright 2013 Wolfgang Nagele
*
* 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");
var aws = require("aws-sdk");
var attrWrapper = require("dynamodb-data-types").AttributeValue;
function DDBOutNode(n) {
RED.nodes.createNode(this, n);
this.credentials = RED.nodes.getNode(n.credentials);
this.region = n.region || "us-east-1";
this.table = n.table;
aws.config.update({ accessKeyId: this.credentials.accessKey,
secretAccessKey: this.credentials.secretAccessKey,
region: this.region });
var ddb = new aws.DynamoDB();
this.on("input", function(msg) {
if (msg != null) {
ddb.putItem({ "TableName": this.table,
"Item": attrWrapper.wrap(msg.payload) },
function(err, data) {
err && util.log(err);
});
}
});
}
RED.nodes.registerType("ddb out", DDBOutNode);

68
storage/ddb/aws.html Normal file
View File

@ -0,0 +1,68 @@
<!--
Copyright 2013 Wolfgang Nagele
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="aws credentials">
<div class="form-row">
<label for="node-config-input-accessKey"><i class="icon-briefcase"></i> Access Key</label>
<input type="text" id="node-config-input-accessKey" placeholder="Access Key">
</div>
<div class="form-row">
<label for="node-config-input-secretAccessKey"><i class="icon-briefcase"></i> Secret Access Key</label>
<input type="text" id="node-config-input-secretAccessKey" placeholder="Secret Access Key">
</div>
</script>
<script type="text/javascript">
RED.nodes.registerType("aws credentials", {
category: "config",
label: function() {
return this.accessKey;
},
defaults: {
accessKey: { value: "", required: true }
},
oneditprepare: function() {
$.getJSON("aws-credentials/" + this.id, function(data) {
if (data.accessKey) {
$("#node-config-input-accessKey").val(data.accessKey);
}
if (data.secretAccessKey) {
$("#node-config-input-secretAccessKey").val(data.secretAccessKey);
}
});
},
oneditsave: function() {
var newAccessKey = $("#node-config-input-accessKey").val();
var newSecretAccessKey = $("#node-config-input-secretAccessKey").val();
var credentials = {};
credentials.accessKey = newAccessKey;
credentials.secretAccessKey = newSecretAccessKey;
$.ajax({
url: "aws-credentials/" + this.id,
type: "POST",
data: credentials,
success: function(result) {}
});
},
ondelete: function() {
$.ajax({
url: "aws-credentials/" + this.id,
type: "DELETE",
success: function(result) {}
});
}
});
</script>

65
storage/ddb/aws.js Normal file
View File

@ -0,0 +1,65 @@
/**
* Copyright 2013 Wolfgang Nagele
*
* 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 querystring = require('querystring');
function AWSCredentialsNode(n) {
RED.nodes.createNode(this, n);
var credentials = RED.nodes.getCredentials(n.id);
if (credentials) {
this.accessKey = credentials.accessKey;
this.secretAccessKey = credentials.secretAccessKey;
}
}
RED.nodes.registerType("aws credentials", AWSCredentialsNode);
RED.app.get('/aws-credentials/:id', function(req, res) {
var credentials = RED.nodes.getCredentials(req.params.id);
if (credentials) {
res.send(JSON.stringify({ accessKey: credentials.accessKey, secretAccessKey: credentials.secretAccessKey }));
} else {
res.send(JSON.stringify({}));
}
});
RED.app.delete('/aws-credentials/:id', function(req, res) {
RED.nodes.deleteCredentials(req.params.id);
res.send(200);
});
RED.app.post('/aws-credentials/: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.accessKey == null || newCreds.accessKey == "") {
delete credentials.accessKey;
} else {
credentials.accessKey = newCreds.accessKey || credentials.accessKey;
}
if (newCreds.secretAccessKey == null || newCreds.secretAccessKey == "") {
delete credentials.secretAccessKey;
} else {
credentials.secretAccessKey = newCreds.secretAccessKey || credentials.secretAccessKey;
}
RED.nodes.addCredentials(req.params.id, credentials);
res.send(200);
});
});

View File

@ -0,0 +1,146 @@
<!--
Copyright 2013 Kris Daniels.
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="postgresdb">
<div class="form-row">
<label for="node-config-input-hostname"><i class="icon-bookmark"></i> Host</label>
<input class="input-append-left" type="text" id="node-config-input-hostname" placeholder="localhost" style="width: 40%;" >
<label for="node-config-input-port" style="margin-left: 10px; width: 35px; "> Port</label>
<input type="text" id="node-config-input-port" placeholder="5432" style="width:45px">
</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="test">
</div>
<div class="form-row">
<label for="node-config-input-name"><i class="icon-user"></i> Username</label>
<input type="text" id="node-config-input-user" placeholder="postgres">
<label for="node-config-input-password"><i class="icon-lock"></i> Password</label>
<input type="password" id="node-config-input-password" placeholder="postgres">
</div>
</script>
<script type="text/javascript">
RED.nodes.registerType('postgresdb',{
category: 'config',
color:"rgb(218, 196, 180)",
defaults: {
hostname: { value:"localhost",required:true},
port: { value: 5432,required:true},
db: { value:"postgres",required:true}
},
label: function() {
return this.name||this.hostname+":"+this.port+"/"+this.db;
},
oneditprepare: function() {
$.getJSON('postgresdb/'+this.id,function(data) {
if (data.user) {
$('#node-config-input-user').val(data.user);
}
if (data.hasPassword) {
$('#node-config-input-password').val('__PWRD__');
} else {
$('#node-config-input-password').val('');
}
});
},
oneditsave: function() {
var newUser = $('#node-config-input-user').val();
var newPass = $('#node-config-input-password').val();
var credentials = {};
credentials.user = newUser;
if (newPass != '__PWRD__') {
credentials.password = newPass;
}
$.ajax({
url: 'postgresdb/'+this.id,
type: 'POST',
data: credentials,
success:function(result){}
});
},
ondelete: function() {
$.ajax({
url: 'postgresdb/'+this.id,
type: 'DELETE',
success: function(result) {}
});
}
});
</script>
<script type="text/x-red" data-template-name="postgres">
<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-postgresdb"><i class="icon-tag"></i> Server</label>
<input type="text" id="node-input-postgresdb">
</div>
<div class="form-row">
<label>&nbsp;</label>
<input type="checkbox" id="node-input-output" placeholder="once" style="display: inline-block; width: auto; vertical-align: top;">
<label for="node-input-output" style="width: 70%;">Receive query output ?</label>
</div>
</script>
<script type="text/x-red" data-help-name="postgres">
<p>A PostgreSql I/O node. </p>
<p>Executes the query specified in msg.payload with optional query parameters in msg.queryParameters</p>
<p>The queryParameters in the query must be specified as $propertyname</p>
<p>See the node-postgres-named package for more info</p>
<p>When receiving data from the query, the msg.payload on the output will be a json array of the returned records</p>
</script>
<script type="text/javascript">
RED.nodes.registerType('postgres',{
category: 'storage-output',
color:"rgb(148, 226, 252)",
defaults: {
postgresdb: { type:"postgresdb",required:true},
name: {value:""},
output: {value:false},
outputs: {value:0}
},
inputs: 1,
outputs: 0,
icon: "postgres.png",
align: "right",
label: function() {
return this.name||(this.sqlquery?this.sqlquery:"postgres");
},
labelStyle: function() {
return this.name?"node_label_italic":"";
},
oneditprepare: function() {
$( "#node-input-output" ).prop( "checked", this.output );
$("#node-input-name").focus();
},
oneditsave: function() {
var hasOutput = $( "#node-input-output" ).prop( "checked" );
this.outputs = hasOutput ? 1:0;
}
});
</script>

View File

@ -0,0 +1,123 @@
/**
* Copyright 2013 Kris Daniels.
*
* 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 pg=require('pg');
var named=require('node-postgres-named');
var querystring = require('querystring');
RED.app.get('/postgresdb/: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('/postgresdb/:id',function(req,res) {
RED.nodes.deleteCredentials(req.params.id);
res.send(200);
});
RED.app.post('/postgresdb/: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 PostgresDatabaseNode(n) {
RED.nodes.createNode(this,n);
this.hostname = n.hostname;
this.port = n.port;
this.db = n.db;
var credentials = RED.nodes.getCredentials(n.id);
if (credentials) {
this.user = credentials.user;
this.password = credentials.password;
}
}
RED.nodes.registerType("postgresdb",PostgresDatabaseNode);
function PostgresNode(n) {
RED.nodes.createNode(this,n);
this.topic = n.topic;
this.postgresdb = n.postgresdb;
this.postgresConfig = RED.nodes.getNode(this.postgresdb);
this.sqlquery = n.sqlquery;
this.output = n.output;
var node = this;
if(this.postgresConfig)
{
var conString = 'postgres://'+this.postgresConfig.user +':' + this.postgresConfig.password + '@' + this.postgresConfig.hostname + ':' + this.postgresConfig.port + '/' + this.postgresConfig.db;
node.clientdb = new pg.Client(conString);
named.patch(node.clientdb);
node.clientdb.connect(function(err){
if(err) { node.error(err); }
else {
node.on('input',
function(msg){
if(!msg.queryParameters) msg.queryParameters={};
node.clientdb.query(msg.payload,
msg.queryParameters,
function (err, results) {
if(err) { node.error(err); }
else {
if(node.output)
{
msg.payload = results.rows;
node.send(msg);
}
}
});
});
}
});
} else {
this.error("missing postgres configuration");
}
this.on("close", function() {
if(node.clientdb) node.clientdb.end();
});
}
RED.nodes.registerType("postgres",PostgresNode);

Binary file not shown.

After

Width:  |  Height:  |  Size: 625 B