mirror of
https://github.com/node-red/node-red-nodes.git
synced 2023-10-10 13:36:58 +02:00
Merge branch 'master' of https://github.com/maxwellhadley/node-red-nodes
Conflicts: hardware/BBB/README.md
This commit is contained in:
commit
982a68d8eb
@ -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...*
|
||||
|
||||
**69-ddbout** - Support output to Amazon DynamoDB.
|
||||
|
||||
### 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,
|
||||
|
@ -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
|
||||
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'.
|
||||
|
||||
Useful for energy monitoring, e.g. electricty meter pulse outputs.
|
||||
|
||||
The 'instantaneous' pulse rate is derived from either the time between the last two
|
||||
|
@ -51,7 +51,7 @@ function sensorTagNode(n) {
|
||||
sensorTag.enableIrTemperature(function(){});
|
||||
sensorTag.on('irTemperatureChange',
|
||||
function(objectTemperature, ambientTemperature){
|
||||
var msg = {'topic': node.topic + '/tempature'};
|
||||
var msg = {'topic': node.topic + '/temperature'};
|
||||
msg.payload = {'object': objectTemperature.toFixed(1),
|
||||
'ambient':ambientTemperature.toFixed(1)
|
||||
};
|
||||
|
120
io/emoncms/88-emoncms.html
Normal file
120
io/emoncms/88-emoncms.html
Normal 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
111
io/emoncms/88-emoncms.js
Normal 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);
|
BIN
io/emoncms/icons/emoncms-logo.png
Normal file
BIN
io/emoncms/icons/emoncms-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
io/emoncms/icons/emoncms.png
Normal file
BIN
io/emoncms/icons/emoncms.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 933 B |
@ -29,14 +29,12 @@
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<!-- Next, some simple help text is provided for the node. -->
|
||||
<script type="text/x-red" data-help-name="ping">
|
||||
<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>Default ping is every 20 seconds but can be configured.</p>
|
||||
</script>
|
||||
|
||||
<!-- Finally, the node type is registered along with all of its properties -->
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('ping',{
|
||||
category: 'advanced-input',
|
||||
|
@ -30,12 +30,12 @@ function PingNode(n) {
|
||||
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 = "";
|
||||
var res = false;
|
||||
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]);
|
||||
var regex = /from.*time.(.*)ms/;
|
||||
var m = regex.exec(data.toString())||"";
|
||||
if (m != '') { res = Number(m[1]); }
|
||||
});
|
||||
ex.stderr.on('data', function (data) {
|
||||
//console.log('[ping] stderr: ' + data);
|
||||
|
@ -28,7 +28,7 @@ exec("which mpd",function(err,stdout,stderr) {
|
||||
|
||||
exec("netstat -an | grep LISTEN | grep 6600",function(err,stdout,stderr) {
|
||||
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;
|
||||
}
|
||||
komponist.createConnection(6600, 'localhost', function(err, client) {
|
||||
|
@ -47,6 +47,7 @@ function ProwlNode(n) {
|
||||
if (typeof(msg.payload) == 'object') {
|
||||
msg.payload = JSON.stringify(msg.payload);
|
||||
}
|
||||
else { msg.payload = msg.payload.toString(); }
|
||||
if (pushkey) {
|
||||
try {
|
||||
prowl.push(msg.payload, titl, { priority: pri }, function(err, remaining) {
|
||||
|
@ -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>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><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><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 type="text/javascript">
|
||||
|
@ -44,8 +44,9 @@ function PushbulletNode(n) {
|
||||
if (typeof(msg.payload) == 'object') {
|
||||
msg.payload = JSON.stringify(msg.payload);
|
||||
}
|
||||
if (pushkey) {
|
||||
if (pushkey.pushbullet && pushkey.deviceid) {
|
||||
try {
|
||||
if (!isNaN(deviceId)) { deviceId = Number(deviceId); }
|
||||
pusher.note(deviceId, titl, msg.payload, function(err, response) {
|
||||
if (err) node.error(err);
|
||||
console.log(response);
|
||||
|
@ -15,15 +15,16 @@
|
||||
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">
|
||||
<label for="node-input-title"><i class="icon-flag"></i> Title</label>
|
||||
<input type="text" id="node-input-title" placeholder="Node-RED">
|
||||
<label for="node-input-number"><i class="icon-envelope"></i> SMS to</label>
|
||||
<input type="text" id="node-input-number" placeholder="01234 5678901">
|
||||
</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 Number blank to use <b>msg.topic</b> to set the number.</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="twilio out">
|
||||
@ -39,7 +40,7 @@
|
||||
RED.nodes.registerType('twilio out',{
|
||||
category: 'output',
|
||||
defaults: {
|
||||
title: {value:""},
|
||||
number: {value:""},
|
||||
name: {value:""}
|
||||
},
|
||||
color:"#ed1c24",
|
||||
@ -48,7 +49,7 @@
|
||||
icon: "twilio.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
return this.name||this.title||"twilio out";
|
||||
return this.name||this.title||"twilio";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
|
@ -37,7 +37,7 @@ if (twiliokey) {
|
||||
|
||||
function TwilioOutNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.title = n.title;
|
||||
this.number = n.number;
|
||||
var node = this;
|
||||
this.on("input",function(msg) {
|
||||
if (typeof(msg.payload) == 'object') {
|
||||
@ -46,7 +46,8 @@ function TwilioOutNode(n) {
|
||||
if (twiliokey) {
|
||||
try {
|
||||
// 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);
|
||||
//console.log(response);
|
||||
});
|
||||
@ -60,5 +61,4 @@ function TwilioOutNode(n) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType("twilio out",TwilioOutNode);
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 717 B After Width: | Height: | Size: 553 B |
58
storage/ddb/69-ddbout.html
Normal file
58
storage/ddb/69-ddbout.html
Normal 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
44
storage/ddb/69-ddbout.js
Normal 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
68
storage/ddb/aws.html
Normal 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
65
storage/ddb/aws.js
Normal 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);
|
||||
});
|
||||
});
|
146
storage/postgres/110-postgres.html
Normal file
146
storage/postgres/110-postgres.html
Normal 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> </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>
|
123
storage/postgres/110-postgres.js
Normal file
123
storage/postgres/110-postgres.js
Normal 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);
|
BIN
storage/postgres/icons/postgres.png
Normal file
BIN
storage/postgres/icons/postgres.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 625 B |
Loading…
Reference in New Issue
Block a user