├── lib
└── .gitignore
├── .nodemonignore
├── .gitignore
├── public
├── favicon.ico
├── icons
│ ├── db.png
│ ├── rpi.png
│ ├── alert.png
│ ├── debug.png
│ ├── feed.png
│ ├── file.png
│ ├── hash.png
│ ├── light.png
│ ├── prowl.png
│ ├── redis.png
│ ├── watch.png
│ ├── xmpp.png
│ ├── arduino.png
│ ├── arrow-in.png
│ ├── bonjour.png
│ ├── bridge.png
│ ├── bullet.png
│ ├── envelope.png
│ ├── function.png
│ ├── inject.png
│ ├── leveldb.png
│ ├── mongodb.png
│ ├── serial.png
│ ├── template.png
│ ├── twitter.png
│ ├── node-error.png
│ ├── bridge-dash.png
│ └── white-globe.png
├── node-red.png
├── pw_maze_white.png
├── bootstrap
│ └── img
│ │ ├── glyphicons-halflings.png
│ │ └── glyphicons-halflings-white.png
├── jquery
│ └── css
│ │ └── smoothness
│ │ └── images
│ │ ├── animated-overlay.gif
│ │ ├── ui-icons_222222_256x240.png
│ │ ├── ui-icons_2e83ff_256x240.png
│ │ ├── ui-icons_454545_256x240.png
│ │ ├── ui-icons_888888_256x240.png
│ │ ├── ui-icons_cd0a0a_256x240.png
│ │ ├── ui-bg_flat_0_aaaaaa_40x100.png
│ │ ├── ui-bg_flat_75_ffffff_40x100.png
│ │ ├── ui-bg_glass_55_fbf9ee_1x400.png
│ │ ├── ui-bg_glass_65_ffffff_1x400.png
│ │ ├── ui-bg_glass_75_dadada_1x400.png
│ │ ├── ui-bg_glass_75_e6e6e6_1x400.png
│ │ ├── ui-bg_glass_95_fef1ec_1x400.png
│ │ └── ui-bg_highlight-soft_75_cccccc_1x100.png
└── red
│ ├── validators.js
│ ├── ui
│ ├── state.js
│ ├── keyboard.js
│ ├── notifications.js
│ ├── palette.js
│ └── sidebar.js
│ ├── history.js
│ └── main.js
├── package.json
├── red
├── events.js
├── ui.js
├── red.js
└── server.js
├── nodes
├── core
│ ├── 90-comment.js
│ ├── 80-template.js
│ ├── 75-exec.js
│ ├── 80-function.js
│ ├── 75-exec.html
│ ├── 20-inject.js
│ ├── 90-comment.html
│ ├── 58-debug.js
│ ├── 80-template.html
│ └── 80-function.html
├── analysis
│ ├── 72-sentiment.js
│ ├── 72-wordpos.js
│ ├── 73-parsexml.js
│ ├── 72-wordpos.html
│ ├── 72-sentiment.html
│ └── 73-parsexml.html
├── social
│ ├── 57-notify.js
│ ├── 61-email.js
│ ├── 57-pushbullet.js
│ ├── 57-prowl.js
│ ├── 61-email.html
│ ├── 32-feedparse.html
│ ├── 57-notify.html
│ ├── 61-imap.html
│ ├── 57-pushbullet.html
│ ├── 57-prowl.html
│ ├── 91-irc.js
│ ├── 32-feedparse.js
│ ├── 61-imap.js
│ ├── 92-xmpp.js
│ └── 92-xmpp.html
├── io
│ ├── 23-watch.js
│ ├── 21-httpin.js
│ ├── 90-httpget.js
│ ├── 23-watch.html
│ ├── 30-socketout.js
│ ├── 90-httpget.html
│ ├── 30-socketout.html
│ ├── 10-mqtt.js
│ ├── 30-socketin.html
│ ├── 21-httpin.html
│ ├── 31-tcpout.html
│ ├── 32-multicast.js
│ ├── 31-tcpout.js
│ └── 30-socketin.js
├── storage
│ ├── 28-tail.js
│ ├── 50-file.js
│ ├── 28-tail.html
│ ├── 67-leveldb.js
│ ├── 50-file.html
│ ├── 65-redisout.js
│ ├── 67-leveldb.html
│ └── 66-mongodb.js
├── deprecated
│ ├── 35-rpi-gpio-out.js
│ ├── 35-rpi-gpio-out.html
│ ├── 35-rpi-gpio-in.js
│ └── 35-rpi-gpio-in.html
├── 99-sample.js.demo
├── hardware
│ ├── 78-ledborg.js
│ ├── 76-blinkstick.js
│ ├── 77-blink1.html
│ ├── 76-blinkstick.html
│ ├── 78-ledborg.html
│ ├── 77-blink1.js
│ └── 36-rpi-gpio.js
└── 99-sample.html.demo
├── INSTALL.md
├── red.js
├── settings.js
└── README.md
/lib/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 |
--------------------------------------------------------------------------------
/.nodemonignore:
--------------------------------------------------------------------------------
1 | .git/*
2 | *.json
3 | lib/*
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | credentials.json
3 | flows*.json
4 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/favicon.ico
--------------------------------------------------------------------------------
/public/icons/db.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/db.png
--------------------------------------------------------------------------------
/public/icons/rpi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/rpi.png
--------------------------------------------------------------------------------
/public/node-red.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/node-red.png
--------------------------------------------------------------------------------
/public/icons/alert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/alert.png
--------------------------------------------------------------------------------
/public/icons/debug.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/debug.png
--------------------------------------------------------------------------------
/public/icons/feed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/feed.png
--------------------------------------------------------------------------------
/public/icons/file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/file.png
--------------------------------------------------------------------------------
/public/icons/hash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/hash.png
--------------------------------------------------------------------------------
/public/icons/light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/light.png
--------------------------------------------------------------------------------
/public/icons/prowl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/prowl.png
--------------------------------------------------------------------------------
/public/icons/redis.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/redis.png
--------------------------------------------------------------------------------
/public/icons/watch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/watch.png
--------------------------------------------------------------------------------
/public/icons/xmpp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/xmpp.png
--------------------------------------------------------------------------------
/public/icons/arduino.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/arduino.png
--------------------------------------------------------------------------------
/public/icons/arrow-in.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/arrow-in.png
--------------------------------------------------------------------------------
/public/icons/bonjour.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/bonjour.png
--------------------------------------------------------------------------------
/public/icons/bridge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/bridge.png
--------------------------------------------------------------------------------
/public/icons/bullet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/bullet.png
--------------------------------------------------------------------------------
/public/icons/envelope.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/envelope.png
--------------------------------------------------------------------------------
/public/icons/function.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/function.png
--------------------------------------------------------------------------------
/public/icons/inject.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/inject.png
--------------------------------------------------------------------------------
/public/icons/leveldb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/leveldb.png
--------------------------------------------------------------------------------
/public/icons/mongodb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/mongodb.png
--------------------------------------------------------------------------------
/public/icons/serial.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/serial.png
--------------------------------------------------------------------------------
/public/icons/template.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/template.png
--------------------------------------------------------------------------------
/public/icons/twitter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/twitter.png
--------------------------------------------------------------------------------
/public/pw_maze_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/pw_maze_white.png
--------------------------------------------------------------------------------
/public/icons/node-error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/node-error.png
--------------------------------------------------------------------------------
/public/icons/bridge-dash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/bridge-dash.png
--------------------------------------------------------------------------------
/public/icons/white-globe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/icons/white-globe.png
--------------------------------------------------------------------------------
/public/bootstrap/img/glyphicons-halflings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/bootstrap/img/glyphicons-halflings.png
--------------------------------------------------------------------------------
/public/bootstrap/img/glyphicons-halflings-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/bootstrap/img/glyphicons-halflings-white.png
--------------------------------------------------------------------------------
/public/jquery/css/smoothness/images/animated-overlay.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/jquery/css/smoothness/images/animated-overlay.gif
--------------------------------------------------------------------------------
/public/jquery/css/smoothness/images/ui-icons_222222_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/jquery/css/smoothness/images/ui-icons_222222_256x240.png
--------------------------------------------------------------------------------
/public/jquery/css/smoothness/images/ui-icons_2e83ff_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/jquery/css/smoothness/images/ui-icons_2e83ff_256x240.png
--------------------------------------------------------------------------------
/public/jquery/css/smoothness/images/ui-icons_454545_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/jquery/css/smoothness/images/ui-icons_454545_256x240.png
--------------------------------------------------------------------------------
/public/jquery/css/smoothness/images/ui-icons_888888_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/jquery/css/smoothness/images/ui-icons_888888_256x240.png
--------------------------------------------------------------------------------
/public/jquery/css/smoothness/images/ui-icons_cd0a0a_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/jquery/css/smoothness/images/ui-icons_cd0a0a_256x240.png
--------------------------------------------------------------------------------
/public/jquery/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/jquery/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png
--------------------------------------------------------------------------------
/public/jquery/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/jquery/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png
--------------------------------------------------------------------------------
/public/jquery/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/jquery/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png
--------------------------------------------------------------------------------
/public/jquery/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/jquery/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png
--------------------------------------------------------------------------------
/public/jquery/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/jquery/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png
--------------------------------------------------------------------------------
/public/jquery/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/jquery/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png
--------------------------------------------------------------------------------
/public/jquery/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/jquery/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png
--------------------------------------------------------------------------------
/public/jquery/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cougar/node-red/master/public/jquery/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "node-red",
3 | "version": "0.1.0",
4 | "description": "A visual tool for wiring the Internet of Things",
5 | "homepage": "http://nodered.org",
6 | "scripts": {
7 | "start": "node red.js"
8 | },
9 | "main": "red/red.js",
10 | "author": "Nick O'Leary",
11 | "contributors": [ {"name": "Dave Conway-Jones"} ],
12 | "keywords": ["editor", "messaging", "iot", "m2m", "pi", "arduino", "beaglebone", "ibm"],
13 | "license": "Apache",
14 | "dependencies": {
15 | "express": "3.x",
16 | "mqtt": "*",
17 | "ws": "*",
18 | "mustache": "*",
19 | "cron":"*"
20 | },
21 | "engines": { "node": ">=0.8" },
22 | "repository": {"type":"git","url":"https://github.com/node-red/node-red.git"}
23 | }
24 |
--------------------------------------------------------------------------------
/red/events.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var events = require("events");
18 |
19 | module.exports = new events.EventEmitter();
20 |
--------------------------------------------------------------------------------
/nodes/core/90-comment.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 |
19 | function CommentNode(n) {
20 | RED.nodes.createNode(this,n);
21 | }
22 |
23 | RED.nodes.registerType("comment",CommentNode);
24 |
--------------------------------------------------------------------------------
/public/red/validators.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 | RED.validators = {
17 | number: function(){return function(v) { return v!=='' && !isNaN(v);}},
18 | regex: function(re){return function(v) { return re.test(v);}}
19 | };
20 |
--------------------------------------------------------------------------------
/public/red/ui/state.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 | RED.state = {
17 | MOVING: 1,
18 | JOINING: 2,
19 | MOVING_ACTIVE: 3,
20 | ADDING: 4,
21 | EDITING: 5,
22 | EXPORT: 6,
23 | IMPORT: 7,
24 | IMPORT_DRAGGING: 8
25 | }
26 |
--------------------------------------------------------------------------------
/nodes/analysis/72-sentiment.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var sentiment = require('sentiment');
19 |
20 | function SentimentNode(n) {
21 | RED.nodes.createNode(this,n);
22 |
23 | this.on("input", function(msg) {
24 | var node = this;
25 | sentiment(msg.payload, function (err, result) {
26 | msg.sentiment = result;
27 | node.send(msg);
28 | });
29 | });
30 | }
31 |
32 | RED.nodes.registerType("sentiment",SentimentNode);
33 |
--------------------------------------------------------------------------------
/nodes/analysis/72-wordpos.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var util = require("util");
19 | var WordPos = require('wordpos');
20 |
21 | var wordpos = new WordPos();
22 |
23 | function WordPOSNode(n) {
24 | RED.nodes.createNode(this,n);
25 | this.on("input", function(msg) {
26 | var node = this;
27 | wordpos.getPOS(msg.payload, function (result) {
28 | msg.pos = result;
29 | node.send(msg);
30 | });
31 | });
32 | }
33 |
34 | RED.nodes.registerType("wordpos",WordPOSNode);
35 |
--------------------------------------------------------------------------------
/red/ui.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 | var express = require('express');
17 | var util = require('util');
18 | var crypto = require('crypto');
19 | var fs = require("fs");
20 | var app = express();
21 |
22 | function setupUI(settings) {
23 |
24 | // Need to ensure the url ends with a '/' so the static serving works
25 | // with relative paths
26 | app.get("/",function(req,res) {
27 | if (req.originalUrl.slice(-1) != "/") {
28 | res.redirect(req.originalUrl+"/");
29 | } else {
30 | req.next();
31 | }
32 | });
33 |
34 | app.use("/",express.static(__dirname + '/../public'));
35 |
36 | return app;
37 | }
38 |
39 | module.exports = setupUI;
40 |
41 |
--------------------------------------------------------------------------------
/nodes/social/57-notify.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var growl = require('growl');
19 | var imagefile = __dirname+"/../../public/mqtt-node-red.png";
20 |
21 | function NotifyNode(n) {
22 | RED.nodes.createNode(this,n);
23 | this.title = n.title;
24 | var node = this;
25 | this.on("input",function(msg) {
26 | var titl = this.title||msg.topic;
27 | if (typeof(msg.payload) == 'object') {
28 | msg.payload = JSON.stringify(msg.payload);
29 | }
30 | if (typeof(titl) != 'undefined') {
31 | growl(msg.payload, { title: titl, image: imagefile });
32 | }
33 | else {
34 | growl(msg.payload, { image: imagefile });
35 | }
36 | });
37 | }
38 |
39 | RED.nodes.registerType("notify",NotifyNode);
40 |
--------------------------------------------------------------------------------
/nodes/core/80-template.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 |
19 | var mustache = require("mustache");
20 | var util = require("util");
21 | var fs = require('fs');
22 |
23 | function TemplateNode(n) {
24 | RED.nodes.createNode(this,n);
25 | this.name = n.name;
26 | this.template = n.template;
27 | this.on("input", function(msg) {
28 | if (msg != null) {
29 | try {
30 | msg.payload = mustache.render(this.template,msg)
31 | this.send(msg);
32 | } catch(err) {
33 | this.error(err.message);
34 | }
35 | }
36 | });
37 | }
38 |
39 | RED.nodes.registerType("template",TemplateNode);
40 |
41 | RED.library.register("templates");
42 |
--------------------------------------------------------------------------------
/nodes/io/23-watch.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var notify = require("fs.notify");
19 |
20 | function WatchNode(n) {
21 | RED.nodes.createNode(this,n);
22 |
23 | this.files = n.files.split(",");
24 | for (var f in this.files) {
25 | this.files[f] = this.files[f].trim();
26 | }
27 | var node = this;
28 | var notifications = new notify(this.files);
29 | notifications.on('change', function (file) {
30 | node.log('file changed '+file);
31 | var msg = { payload: file, topic: JSON.stringify(node.files) };
32 | node.send(msg);
33 | });
34 |
35 | this._close = function() {
36 | notifications.close();
37 | }
38 | }
39 |
40 | RED.nodes.registerType("watch",WatchNode);
41 |
42 | WatchNode.prototype.close = function() {
43 | this._close();
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/nodes/storage/28-tail.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var fs = require("fs");
19 | var spawn = require('child_process').spawn;
20 |
21 | function TailNode(n) {
22 | RED.nodes.createNode(this,n);
23 |
24 | this.filename = n.filename;
25 | this.split = n.split;
26 | var node = this;
27 |
28 | var tail = spawn("tail", ["-f", this.filename]);
29 | tail.stdout.on("data", function (data) {
30 | var msg = {topic:node.filename};
31 | if (node.split) {
32 | var strings = data.toString().split("\n");
33 | for (s in strings) {
34 | if (strings[s] != "") {
35 | msg.payload = strings[s];
36 | node.send(msg);
37 | }
38 | }
39 | }
40 | else {
41 | msg.payload = data.toString();
42 | node.send(msg);
43 | }
44 | });
45 | }
46 |
47 | RED.nodes.registerType("tail",TailNode);
48 |
--------------------------------------------------------------------------------
/nodes/analysis/73-parsexml.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var util = require("util");
19 | var parseString = require('xml2js').parseString;
20 | var gotEyes = false;
21 | try {
22 | var eyes = require("eyes");
23 | gotEyes = true;
24 | } catch(e) {
25 | util.log("[73-parsexml.js] Warning: Module 'eyes' not installed");
26 | }
27 |
28 | function Xml2jsNode(n) {
29 | RED.nodes.createNode(this,n);
30 | this.useEyes = n.useEyes;
31 | var node = this;
32 |
33 | this.on("input", function(msg) {
34 | parseString(msg.payload, function (err, result) {
35 | msg.payload = result;
36 | node.send(msg);
37 | if (node.useEyes == true) {
38 | if (gotEyes == true) { eyes.inspect(msg); }
39 | else { node.log(JSON.stringify(msg)); }
40 | }
41 | });
42 | });
43 | }
44 |
45 | RED.nodes.registerType("xml2js",Xml2jsNode);
46 |
--------------------------------------------------------------------------------
/red/red.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var events = require("./events");
18 | var server = require("./server");
19 | var nodes = require("./nodes");
20 | var library = require("./library");
21 | var settings = null;
22 |
23 |
24 | var events = require("events");
25 |
26 | var RED = {
27 |
28 | init: function(httpServer,userSettings) {
29 | settings = userSettings;
30 | server.init(httpServer,settings);
31 | library.init();
32 | return server.app;
33 | },
34 |
35 | start: server.start,
36 |
37 | nodes: nodes,
38 | library: library,
39 | events: events
40 | };
41 |
42 | RED.__defineGetter__("app", function() { return server.app });
43 | RED.__defineGetter__("server", function() { return server.server });
44 | RED.__defineGetter__("settings", function() { return settings });
45 |
46 | module.exports = RED;
47 |
--------------------------------------------------------------------------------
/nodes/deprecated/35-rpi-gpio-out.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var gpio = require("pi-gpio");
19 |
20 | function GPIOOutNode(n) {
21 | RED.nodes.createNode(this,n);
22 |
23 | this.pin = n.pin;
24 |
25 | var node = this;
26 |
27 | if (this.pin) {
28 | gpio.open(this.pin,"output",function(err) {
29 | if (err) {
30 | node.error(err);
31 | } else {
32 | node.on("input",function(msg) {
33 | gpio.write(node.pin,msg.payload,function(err) {
34 | if (err) node.error(err);
35 | });
36 | });
37 | }
38 | });
39 | } else {
40 | this.error("Invalid GPIO pin: "+this.pin);
41 | }
42 | }
43 |
44 | RED.nodes.registerType("rpi-gpio out",GPIOOutNode);
45 |
46 | GPIOOutNode.prototype.close = function() {
47 | gpio.close(this.pin);
48 | }
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/nodes/io/21-httpin.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var util = require("util");
19 |
20 | function HTTPIn(n) {
21 | RED.nodes.createNode(this,n);
22 | this.url = n.url;
23 | this.method = n.method;
24 |
25 | var node = this;
26 | this.callback = function(req,res) {
27 | node.send({req:req,res:res});
28 | }
29 | if (this.method == "get") {
30 | RED.app.get(this.url,this.callback);
31 | } else if (this.method == "post") {
32 | RED.app.post(this.url,this.callback);
33 | } else if (this.method == "put") {
34 | RED.app.put(this.url,this.callback);
35 | } else if (this.method == "delete") {
36 | RED.app.delete(this.url,this.callback);
37 | }
38 | }
39 |
40 | RED.nodes.registerType("http in",HTTPIn);
41 |
42 | HTTPIn.prototype.close = function() {
43 | var routes = RED.app.routes[this.method];
44 | for (var i in routes) {
45 | if (routes[i].path == this.url) {
46 | routes.splice(i,1);
47 | break;
48 | }
49 | }
50 | }
51 |
52 |
--------------------------------------------------------------------------------
/nodes/storage/50-file.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var fs = require("fs");
19 |
20 | function FileNode(n) {
21 | RED.nodes.createNode(this,n);
22 |
23 | this.filename = n.filename;
24 | this.appendNewline = n.appendNewline;
25 | this.overwriteFile = n.overwriteFile;
26 | var node = this;
27 | this.on("input",function(msg) {
28 | var data = msg.payload;
29 | if (this.appendNewline) {
30 | data += "\n";
31 | }
32 | if (this.overwriteFile) {
33 | fs.writeFile(this.filename, data, function (err) {
34 | if (err) node.warn('Failed to write to file : '+err);
35 | //console.log('Message written to file',this.filename);
36 | });
37 | }
38 | else {
39 | fs.appendFile(this.filename, data, function (err) {
40 | if (err) node.warn('Failed to append to file : '+err);
41 | //console.log('Message appended to file',this.filename);
42 | });
43 | }
44 | });
45 | }
46 |
47 | RED.nodes.registerType("file",FileNode);
48 |
--------------------------------------------------------------------------------
/nodes/social/61-email.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var nodemailer = require("nodemailer");
19 | var emailkey = require("../../../emailkeys.js");
20 |
21 | var smtpTransport = nodemailer.createTransport("SMTP",{
22 | service: emailkey.service,
23 | auth: {
24 | user: emailkey.user,
25 | pass: emailkey.pass
26 | }
27 | });
28 |
29 | function EmailNode(n) {
30 | RED.nodes.createNode(this,n);
31 | this.topic = n.topic;
32 | this.name = n.name;
33 | var node = this;
34 | this.on("input", function(msg) {
35 | //node.log("email :",this.id,this.topic," received",msg.payload);
36 | if (msg != null) {
37 |
38 | smtpTransport.sendMail({
39 | from: emailkey.user, // sender address
40 | to: node.name, // comma separated list of receivers
41 | subject: msg.topic, // Subject line
42 | text: msg.payload // plaintext body
43 | }, function(error, response) {
44 | if (error) {
45 | node.error(error);
46 | } else {
47 | node.log("Message sent: " + response.message);
48 | }
49 | });
50 |
51 | }
52 | });
53 | }
54 |
55 | RED.nodes.registerType("email",EmailNode);
56 |
--------------------------------------------------------------------------------
/nodes/io/90-httpget.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 |
19 | function HttpGet(n) {
20 | RED.nodes.createNode(this,n);
21 | this.baseurl = n.baseurl || "";
22 | this.append = n.append || "";
23 | var node = this;
24 | if (this.baseurl.substring(0,5) === "https") { var http = require("https"); }
25 | else { var http = require("http"); }
26 | this.on("input", function(msg) {
27 | msg._payload = msg.payload;
28 | //util.log("[httpget] "+this.baseurl+msg.payload+this.append);
29 | http.get(this.baseurl+msg.payload+this.append, function(res) {
30 | node.log("Http response: " + res.statusCode);
31 | msg.rc = res.statusCode;
32 | msg.payload = "";
33 | if ((msg.rc != 200) && (msg.rc != 404)) {
34 | node.send(msg);
35 | }
36 | res.setEncoding('utf8');
37 | res.on('data', function(chunk) {
38 | msg.payload += chunk;
39 | });
40 | res.on('end', function() {
41 | node.send(msg);
42 | });
43 | }).on('error', function(e) {
44 | //node.error(e);
45 | msg.rc = 503;
46 | msg.payload = e;
47 | node.send(msg);
48 | });
49 | });
50 | }
51 |
52 | RED.nodes.registerType("httpget",HttpGet);
53 |
--------------------------------------------------------------------------------
/public/red/ui/keyboard.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 | RED.keyboard = function() {
17 |
18 | var active = true;
19 | var handlers = {};
20 |
21 | d3.select(window).on("keydown",function() {
22 | if (!active) { return; }
23 | var handler = handlers[d3.event.keyCode];
24 | if (handler) {
25 | if (!handler.modifiers ||
26 | ((!handler.modifiers.shift || d3.event.shiftKey)&&
27 | (!handler.modifiers.ctrl || d3.event.ctrlKey))) {
28 | handler.callback();
29 | }
30 | }
31 | });
32 |
33 | function addHandler(key,modifiers,callback) {
34 | var mod = modifiers;
35 | var cb = callback;
36 | if (typeof modifiers == "function") {
37 | mod = {};
38 | cb = modifiers;
39 | }
40 | handlers[key] = {modifiers:mod, callback:cb};
41 | }
42 | function removeHandler(key) {
43 | delete handlers[key];
44 | }
45 |
46 | return {
47 | add: addHandler,
48 | remove: removeHandler,
49 | disable: function(){ active = false;},
50 | enable: function(){ active = true; }
51 | }
52 |
53 | }();
54 |
--------------------------------------------------------------------------------
/nodes/social/57-pushbullet.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var PushBullet = require('pushbullet');
19 |
20 | // pushkey.js just needs to be like (with the quotes)
21 | // module.exports = {pushbullet:'My-API-KEY', deviceid:'12345'}
22 |
23 | try {
24 | var pushkey = require("../../settings").pushbullet || require("../../../pushkey.js");
25 | } catch(err) {
26 | throw new Error("Failed to load PushBullet credentials");
27 | }
28 |
29 | var pusher = new PushBullet(pushkey.pushbullet);
30 | var deviceId = pushkey.deviceid;
31 |
32 | function PushbulletNode(n) {
33 | RED.nodes.createNode(this,n);
34 | this.title = n.title;
35 | this.device
36 | var node = this;
37 | this.on("input",function(msg) {
38 | var titl = this.title||msg.topic||"Node-RED";
39 | if (typeof(msg.payload) == 'object') {
40 | msg.payload = JSON.stringify(msg.payload);
41 | }
42 | try {
43 | pusher.note(deviceId, titl, msg.payload, function(err, response) {
44 | if ( err ) node.error(err);
45 | node.log( JSON.stringify(response) );
46 | });
47 | }
48 | catch (err) {
49 | node.error(err);
50 | }
51 | });
52 | }
53 |
54 | RED.nodes.registerType("pushbullet",PushbulletNode);
55 |
--------------------------------------------------------------------------------
/INSTALL.md:
--------------------------------------------------------------------------------
1 | Node-RED Install
2 | ================
3 |
4 | ## Install node.js
5 |
6 | You can get the latest version from .
7 |
8 | Or, you may want to use a version from your operating system's package manager:
9 |
10 |
11 | ## Get Node-RED
12 |
13 | Clone the repository from GitHub:
14 |
15 | $ git clone git@github.com:node-red/node-red.git
16 |
17 | ## Install the pre-requisite modules
18 |
19 | From the top-level directory of Node-RED, run:
20 |
21 | $ npm install
22 |
23 | This will install the core pre-requisite modules.
24 |
25 | ## Run Node-RED
26 |
27 | From the top-level directory, run:
28 |
29 | $ node red.js
30 |
31 | You can then access Node-RED at .
32 |
33 | Online documentation is available at .
34 |
35 | ## Installing individual node dependencies
36 |
37 | When Node-RED starts, it attempts to load the nodes from the `nodes/` directory.
38 | Each will have its own set of dependencies that will need to be installed before
39 | the node is available in the palette.
40 |
41 | To help identify the dependencies, Node-RED logs any modules it fails to find
42 | for a particular node. You don't have to install these unless you want or need
43 | that node to appear.
44 |
45 | Alternatively, a node's `.js` file can be examined to identify the modules it
46 | explicitly requires. For example, the Twitter node is defined in
47 | `nodes/social/27-twitter.js` and contains:
48 |
49 | var RED = require("../../red/red");
50 | var ntwitter = require('ntwitter');
51 | var OAuth= require('oauth').OAuth;
52 |
53 | Of these, `ntwitter` and `oauth` are neither built-in modules nor ones provided
54 | by Node-RED itself. They can subsequently be installed by running:
55 |
56 | $ npm install ntwitter oauth
57 |
58 |
--------------------------------------------------------------------------------
/nodes/99-sample.js.demo:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | // Sample Node-RED node file
18 |
19 | // Require main module
20 | var RED = require("../../red/red");
21 |
22 | // The main node definition - most things happen in here
23 | function SampleNode(n) {
24 | // Create a RED node
25 | RED.nodes.createNode(this,n);
26 |
27 | // Store local copies of the node configuration (as defined in the .html)
28 | this.topic = n.topic;
29 |
30 | // Do whatever you need to do in here - declare callbacks etc
31 | // Note: this sample doesn't do anything much - it will only send
32 | // this message once at startup...
33 | // Look at other real nodes for some better ideas of what to do....
34 | var msg = {};
35 | msg.topic = node.topic;
36 | msg.payload = "Hello world !"
37 |
38 | // send out the message to the rest of the workspace.
39 | this.send(msg);
40 | }
41 |
42 | // Register the node by name. This must be called before overriding any of the
43 | // Node functions.
44 | RED.nodes.registerType("sample",SampleNode);
45 |
46 |
47 | SampleNode.prototype.close = function() {
48 | // Called when the node is shutdown - eg on redeploy.
49 | // Allows ports to be closed, connections dropped etc.
50 | // eg: this.client.disconnect();
51 | }
52 |
--------------------------------------------------------------------------------
/nodes/hardware/78-ledborg.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var util = require('util');
19 | var fs = require('fs');
20 |
21 | // check if /dev/ledborg exists - if not then don't even show the node.
22 | if (!fs.existsSync("/dev/ledborg")) {
23 | util.log("[78-ledborg.js] Error: PiBorg hardware : LedBorg not found");
24 | return;
25 | }
26 |
27 | function LedBorgNode(n) {
28 | RED.nodes.createNode(this,n);
29 | var p1 = /[0-2][0-2][0-2]/
30 | var p2 = /^\#[A-Fa-f0-9]{6}$/
31 | var node = this;
32 |
33 | this.on("input", function(msg) {
34 | if (p1.test(msg.payload)) {
35 | fs.writeFile('/dev/ledborg', msg.payload, function (err) {
36 | if (err) node.warn(msg.payload+" : No LedBorg found");
37 | });
38 | }
39 | if (p2.test(msg.payload)) {
40 | var r = Math.floor(parseInt(msg.payload.slice(1,3),16)/88).toString();
41 | var g = Math.floor(parseInt(msg.payload.slice(3,5),16)/88).toString();
42 | var b = Math.floor(parseInt(msg.payload.slice(5),16)/88).toString();
43 | fs.writeFile('/dev/ledborg', r+g+b, function (err) {
44 | if (err) node.warn(r+g+b+" : No LedBorg found");
45 | });
46 | }
47 | else {
48 | node.warn("Invalid LedBorg colour code");
49 | }
50 | });
51 | }
52 |
53 | RED.nodes.registerType("ledborg",LedBorgNode);
54 |
--------------------------------------------------------------------------------
/nodes/social/57-prowl.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var Prowl = require('node-prowl');
19 |
20 | // pushkey.js just needs to be like (with the quotes)
21 | // module.exports = {prowl:'My-API-KEY'}
22 |
23 | try {
24 | var pushkey = require("../../settings").prowl || require("../../../pushkey.js");
25 | } catch(err) {
26 | throw new Error("Failed to load Prowl credentials");
27 | }
28 |
29 | var prowl = new Prowl(pushkey.prowl);
30 |
31 | function ProwlNode(n) {
32 | RED.nodes.createNode(this,n);
33 | this.title = n.title;
34 | this.priority = n.priority * 1;
35 | if (this.priority > 2) this.priority = 2;
36 | if (this.priority < -2) this.priority = -2;
37 | var node = this;
38 | this.on("input",function(msg) {
39 | var titl = this.title||msg.topic||"Node-RED";
40 | var pri = msg.priority||this.priority;
41 | if (typeof(msg.payload) == 'object') {
42 | msg.payload = JSON.stringify(msg.payload);
43 | }
44 | try {
45 | prowl.push(msg.payload, titl, { priority: pri }, function( err, remaining ){
46 | if ( err ) node.error(err);
47 | node.log( remaining + ' calls to Prowl api during current hour.' );
48 | });
49 | }
50 | catch (err) {
51 | node.error(err);
52 | }
53 | });
54 | }
55 |
56 | RED.nodes.registerType("prowl",ProwlNode);
57 |
--------------------------------------------------------------------------------
/nodes/hardware/76-blinkstick.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var blinkstick = require("blinkstick");
19 |
20 | Object.size = function(obj) {
21 | var size = 0, key;
22 | for (key in obj) { if (obj.hasOwnProperty(key)) size++; }
23 | return size;
24 | };
25 |
26 | function BlinkStick(n) {
27 | RED.nodes.createNode(this,n);
28 | var p1 = /^\#[A-Fa-f0-9]{6}$/
29 | var p2 = /[0-9]+,[0-9]+,[0-9]+/
30 | this.led = blinkstick.findFirst(); // maybe try findAll() (one day)
31 | var node = this;
32 |
33 | this.on("input", function(msg) {
34 | if (msg != null) {
35 | if (Object.size(node.led) !== 0) {
36 | try {
37 | if (p2.test(msg.payload)) {
38 | var rgb = msg.payload.split(",");
39 | node.led.setColor(parseInt(rgb[0])&255, parseInt(rgb[1])&255, parseInt(rgb[2])&255);
40 | }
41 | else {
42 | node.led.setColor(msg.payload);
43 | }
44 | }
45 | catch (err) {
46 | node.warn("BlinkStick missing ?");
47 | node.led = blinkstick.findFirst();
48 | }
49 | }
50 | else {
51 | //node.warn("No BlinkStick found");
52 | node.led = blinkstick.findFirst();
53 | }
54 | }
55 | });
56 | if (Object.size(node.led) === 0) {
57 | node.error("No BlinkStick found");
58 | }
59 |
60 | }
61 |
62 | RED.nodes.registerType("blinkstick",BlinkStick);
63 |
--------------------------------------------------------------------------------
/nodes/analysis/72-wordpos.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
25 |
26 |
38 |
39 |
58 |
--------------------------------------------------------------------------------
/nodes/hardware/77-blink1.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
28 |
29 |
32 |
33 |
53 |
--------------------------------------------------------------------------------
/red.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 | var http = require('http');
17 | var https = require('https');
18 | var util = require("util");
19 | var express = require("express");
20 | var crypto = require("crypto");
21 | var settings = require("./settings");
22 | var RED = require("./red/red.js");
23 |
24 |
25 | var server;
26 | var app = express();
27 |
28 | if (settings.https) {
29 | server = https.createServer(settings.https,function(req,res){app(req,res);});
30 | } else {
31 | server = http.createServer(function(req,res){app(req,res);});
32 | }
33 |
34 | settings.httpRoot = settings.httpRoot||"/";
35 |
36 | if (settings.httpRoot[0] != "/") {
37 | settings.httpRoot = "/"+settings.httpRoot;
38 | }
39 | if (settings.httpRoot.slice(-1) != "/") {
40 | settings.httpRoot = settings.httpRoot + "/";
41 | }
42 | settings.uiPort = settings.uiPort||1880;
43 |
44 | if (settings.httpAuth) {
45 | app.use(settings.httpRoot,
46 | express.basicAuth(function(user, pass) {
47 | return user === settings.httpAuth.user && crypto.createHash('md5').update(pass,'utf8').digest('hex') === settings.httpAuth.pass;
48 | })
49 | );
50 | }
51 |
52 | var red = RED.init(server,settings);
53 | app.use(settings.httpRoot,red);
54 |
55 |
56 | server.listen(settings.uiPort);
57 | RED.start();
58 | util.log('[red] Server now running at http'+(settings.https?'s':'')+'://127.0.0.1:'+settings.uiPort+settings.httpRoot);
59 |
60 |
--------------------------------------------------------------------------------
/nodes/hardware/76-blinkstick.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
24 |
25 |
30 |
31 |
50 |
--------------------------------------------------------------------------------
/settings.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 | module.exports = {
17 | uiPort: 1880,
18 | mqttReconnectTime: 15000,
19 | serialReconnectTime: 15000,
20 | debugMaxLength: 1000,
21 |
22 | // You can protect the user interface with a userid and password by using the following property
23 | // the password must be an md5 hash eg.. 5f4dcc3b5aa765d61d8327deb882cf99 ('password')
24 | //httpAuth: {user:"user",pass:"5f4dcc3b5aa765d61d8327deb882cf99"},
25 |
26 | // By default, the Node-RED UI is available at http://localhost:1880/
27 | // The following property can be used to specifiy a different root path.
28 | //httpRoot: '/admin',
29 |
30 | // The following property can be used to enable HTTPS
31 | // See http://nodejs.org/api/https.html#https_https_createserver_options_requestlistener
32 | // for details on its contents.
33 | //https: {
34 | // key: fs.readFileSync('privatekey.pem'),
35 | // cert: fs.readFileSync('certificate.pem')
36 | //},
37 |
38 | // Anything in this hash is globally available to all functions.
39 | // It is accessed as context.global.
40 | // eg:
41 | // functionGlobalContext: { os:require('os') }
42 | // can be accessed in a function block as:
43 | // context.global.os
44 |
45 | functionGlobalContext: { }
46 | //functionGlobalContext: { bonescript:require('bonescript') }
47 | //functionGlobalContext: { arduino:require('duino') }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/nodes/analysis/72-sentiment.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
25 |
26 |
32 |
33 |
52 |
--------------------------------------------------------------------------------
/nodes/analysis/73-parsexml.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
29 |
30 |
34 |
35 |
54 |
--------------------------------------------------------------------------------
/nodes/hardware/78-ledborg.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
24 |
25 |
31 |
32 |
51 |
--------------------------------------------------------------------------------
/nodes/hardware/77-blink1.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var Blink1 = require("node-blink1");
19 |
20 | function Blink1Node(n) {
21 | RED.nodes.createNode(this,n);
22 | this.fade = n.fade||0;
23 | var node = this;
24 |
25 | try {
26 | var p1 = /^\#[A-Fa-f0-9]{6}$/
27 | var p2 = /[0-9]+,[0-9]+,[0-9]+/
28 | this.on("input", function(msg) {
29 | if (blink1) {
30 | if (p1.test(msg.payload)) {
31 | // if it is a hex colour string
32 | var r = parseInt(msg.payload.slice(1,3),16);
33 | var g = parseInt(msg.payload.slice(3,5),16);
34 | var b = parseInt(msg.payload.slice(5),16);
35 | if (node.fade == 0) { blink1.setRGB( r, g, b ); }
36 | else { blink1.fadeToRGB(node.fade, r, g, b ); }
37 | }
38 | else if (p2.test(msg.payload)) {
39 | // if it is a r,g,b triple
40 | var rgb = msg.payload.split(',');
41 | if (node.fade == 0) { blink1.setRGB(parseInt(rgb[0])&255, parseInt(rgb[1])&255, parseInt(rgb[2])&255); }
42 | else { blink1.fadeToRGB(node.fade, parseInt(rgb[0])&255, parseInt(rgb[1])&255, parseInt(rgb[2])&255); }
43 | }
44 | else {
45 | // you can do fancy colours by name here if you want...
46 | node.warn("Blink1 : invalid msg : "+msg.payload);
47 | }
48 | }
49 | else {
50 | node.warn("No Blink1 found");
51 | }
52 | });
53 | var blink1 = new Blink1.Blink1();
54 | }
55 | catch(e) {
56 | node.error("No Blink1 found");
57 | }
58 | }
59 |
60 | RED.nodes.registerType("blink1",Blink1Node);
61 |
--------------------------------------------------------------------------------
/nodes/social/61-email.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
23 |
24 |
31 |
32 |
51 |
--------------------------------------------------------------------------------
/public/red/ui/notifications.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 | RED.notify = function() {
17 | var currentNotifications = [];
18 | var c = 0;
19 | return function(msg,type,fixed) {
20 | if (currentNotifications.length > 4) {
21 | var ll = currentNotifications.length;
22 | for (var i = 0;ll > 4 && i
16 |
17 |
32 |
33 |
36 |
37 |
58 |
--------------------------------------------------------------------------------
/nodes/io/23-watch.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
27 |
28 |
34 |
35 |
54 |
--------------------------------------------------------------------------------
/nodes/io/30-socketout.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 |
19 | function SocketOut(n) {
20 | RED.nodes.createNode(this,n);
21 | this.host = n.host;
22 | this.port = n.port * 1;
23 | this.name = n.name;
24 | this.trans = n.transport||n.trans||"";
25 | var node = this;
26 | this.on("input", function(msg) {
27 | if (msg != null) {
28 | if (this.trans == "http") {
29 | var http = require("http");
30 | http.get(msg.payload, function(res) {
31 | node.log("http : response : " + res.statusCode);
32 | }).on('error', function(e) {
33 | node.error("http : error : " + e.message);
34 | });
35 | }
36 | if (this.trans == "tcp") {
37 | var net = require('net');
38 | var client = new net.Socket();
39 | client.on('error', function (err) {
40 | node.error('tcp : '+err);
41 | });
42 | client.connect(this.port, this.host, function() {
43 | try { client.end(msg.payload); }
44 | catch (e) { node.error(e); }
45 | });
46 | }
47 | if (this.trans == "udp") {
48 | var dgram = require('dgram');
49 | var sock = dgram.createSocket('udp4'); // only use ipv4 for now
50 | sock.bind(this.port); // have to bind before you can enable broadcast...
51 | sock.setBroadcast(true); // turn on broadcast
52 | var buf = new Buffer(msg.payload);
53 | sock.send(buf, 0, buf.length, this.port, this.host, function(err, bytes) {
54 | if (err) node.error("udp : "+err);
55 | //util.log('[socket out] udp :' +bytes);
56 | sock.close();
57 | });
58 | }
59 | }
60 | });
61 | var node = this;
62 | }
63 |
64 | RED.nodes.registerType("socket out",SocketOut);
65 |
--------------------------------------------------------------------------------
/nodes/deprecated/35-rpi-gpio-out.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
36 |
37 |
60 |
--------------------------------------------------------------------------------
/nodes/social/57-notify.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
27 |
28 |
34 |
35 |
56 |
--------------------------------------------------------------------------------
/nodes/social/61-imap.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
27 |
28 |
35 |
36 |
55 |
--------------------------------------------------------------------------------
/nodes/storage/28-tail.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
33 |
34 |
38 |
39 |
59 |
--------------------------------------------------------------------------------
/nodes/core/75-exec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 |
19 | var spawn = require('child_process').spawn;
20 | var exec = require('child_process').exec;
21 |
22 | function ExecNode(n) {
23 | RED.nodes.createNode(this,n);
24 | this.cmd = n.command;
25 | this.append = n.append || "";
26 | this.useSpawn = n.useSpawn;
27 |
28 | var node = this;
29 | this.on("input", function(msg) {
30 | if (msg != null) {
31 |
32 | if (this.useSpawn == true) {
33 | // make the extra args into an array
34 | // then prepend with the msg.payload
35 | var arg = node.append.split(",");
36 | if (msg.payload != " ") { arg.unshift(msg.payload); }
37 | console.log(arg);
38 | var ex = spawn(node.cmd,arg);
39 | ex.stdout.on('data', function (data) {
40 | //console.log('[exec] stdout: ' + data);
41 | msg.payload = data;
42 | node.send([msg,null,null]);
43 | });
44 | ex.stderr.on('data', function (data) {
45 | //console.log('[exec] stderr: ' + data);
46 | msg.payload = data;
47 | node.send([null,msg,null]);
48 | });
49 | ex.on('close', function (code) {
50 | //console.log('[exec] result: ' + code);
51 | msg.payload = code;
52 | node.send([null,null,msg]);
53 | });
54 | }
55 |
56 | else {
57 | var cl = node.cmd+" "+msg.payload+" "+node.append;
58 | node.log(cl);
59 | var child = exec(cl, function (error, stdout, stderr) {
60 | msg.payload = stdout;
61 | var msg2 = {payload:stderr};
62 | //console.log('[exec] stdout: ' + stdout);
63 | //console.log('[exec] stderr: ' + stderr);
64 | if (error !== null) {
65 | var msg3 = {payload:error};
66 | //console.log('[exec] error: ' + error);
67 | }
68 | node.send([msg,msg2,msg3]);
69 | });
70 | }
71 | }
72 |
73 | });
74 | }
75 |
76 | RED.nodes.registerType("exec",ExecNode);
77 |
--------------------------------------------------------------------------------
/nodes/social/57-pushbullet.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
31 |
32 |
38 |
39 |
61 |
--------------------------------------------------------------------------------
/nodes/deprecated/35-rpi-gpio-in.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var gpio = require("pi-gpio");
19 |
20 | function GPIOInNode(n) {
21 | RED.nodes.createNode(this,n);
22 |
23 | this.buttonState = -1;
24 | this.pin = n.pin;
25 | this.resistor = n.resistor;
26 |
27 | var node = this;
28 |
29 | if (this.pin) {
30 | var setupPin = function(err) {
31 | if (err) {
32 | node.error(err);
33 | } else {
34 | node._interval = setInterval(function(){
35 | gpio.read(node.pin, function(err, value) {
36 | if(err){
37 | node.error(err);
38 | } else{
39 | if(node.buttonState !== value){
40 | var previousState = node.buttonState;
41 | node.buttonState = value;
42 | if (previousState !== -1) {
43 | var msg = {payload:node.buttonState};
44 | node.send(msg);
45 | }
46 | }
47 | }
48 | });
49 | }, 50);
50 | }
51 | };
52 | if (this.resistor == "no") {
53 | gpio.open(this.pin,"input",setupPin());
54 | } else {
55 | // Assume enabled externally via gpio-admin
56 | setupPin();
57 | }
58 | } else {
59 | this.error("Invalid GPIO pin: "+this.pin);
60 | }
61 | }
62 |
63 | RED.nodes.registerType("rpi-gpio in",GPIOInNode);
64 |
65 | GPIOInNode.prototype.close = function() {
66 | clearInterval(this._interval);
67 | if (this.resistor == "no") {
68 | gpio.close(this.pin);
69 | }
70 | }
71 |
72 |
--------------------------------------------------------------------------------
/nodes/social/57-prowl.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
31 |
32 |
39 |
40 |
62 |
--------------------------------------------------------------------------------
/nodes/social/91-irc.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var irc = require("irc");
19 |
20 | // The Server Definition - this opens (and closes) the connection
21 | function IRCServerNode(n) {
22 | RED.nodes.createNode(this,n);
23 | this.server = n.server;
24 | this.channel = n.channel;
25 | this.nickname = n.nickname;
26 | this.ircclient = new irc.Client(this.server, this.nickname, {
27 | channels: [this.channel]
28 | });
29 | this._close = function() {
30 | this.ircclient.disconnect();
31 | }
32 | }
33 |
34 | RED.nodes.registerType("irc-server",IRCServerNode);
35 |
36 | IRCServerNode.prototype.close = function() {
37 | this._close();
38 | }
39 |
40 |
41 | // The Input Node
42 | function IrcInNode(n) {
43 | RED.nodes.createNode(this,n);
44 | this.ircserver = n.ircserver;
45 | this.serverConfig = RED.nodes.getNode(this.ircserver);
46 | this.ircclient = this.serverConfig.ircclient;
47 | var node = this;
48 |
49 |
50 | this.ircclient.addListener('message', function (from, to, message) {
51 | console.log(from + ' => ' + to + ': ' + message);
52 | var msg = { "topic":from, "to":to, "payload":message };
53 | node.send(msg);
54 | });
55 |
56 | this.ircclient.addListener('error', function(message) {
57 | node.error(JSON.stringify(message));
58 | });
59 |
60 | }
61 | RED.nodes.registerType("irc in",IrcInNode);
62 |
63 | // The Output Node
64 | function IrcOutNode(n) {
65 | RED.nodes.createNode(this,n);
66 | this.sendAll = n.sendObject;
67 | this.ircserver = n.ircserver;
68 | this.serverConfig = RED.nodes.getNode(this.ircserver);
69 | this.ircclient = this.serverConfig.ircclient;
70 | this.channel = this.serverConfig.channel;
71 | var node = this;
72 |
73 | this.on("input", function(msg) {
74 | console.log(msg);
75 | if (node.sendAll) {
76 | node.ircclient.say(node.channel, JSON.stringify(msg));
77 | }
78 | else {
79 | var to = msg.topic || node.channel;
80 | node.ircclient.say(to, msg.payload);
81 | }
82 | });
83 | }
84 | RED.nodes.registerType("irc out",IrcOutNode);
85 |
--------------------------------------------------------------------------------
/nodes/io/90-httpget.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
32 |
33 |
39 |
40 |
60 |
--------------------------------------------------------------------------------
/public/red/history.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 | RED.history = function() {
17 | var undo_history = [];
18 |
19 | return {
20 | //TODO: this function is a placeholder until there is a 'save' event that can be listened to
21 | markAllDirty: function() {
22 | for (var i in undo_history) {
23 | undo_history[i].dirty = true;
24 | }
25 | },
26 | push: function(ev) {
27 | undo_history.push(ev);
28 | },
29 | pop: function() {
30 | var ev = undo_history.pop();
31 | if (ev) {
32 | if (ev.t == 'add') {
33 | for (var i in ev.nodes) {
34 | RED.nodes.remove(ev.nodes[i]);
35 | }
36 | for (var i in ev.links) {
37 | RED.nodes.removeLink(ev.links[i]);
38 | }
39 | } else if (ev.t == "delete") {
40 | for (var i in ev.nodes) {
41 | RED.nodes.add(ev.nodes[i]);
42 | }
43 | for (var i in ev.links) {
44 | RED.nodes.addLink(ev.links[i]);
45 | }
46 | } else if (ev.t == "move") {
47 | for (var i in ev.nodes) {
48 | var n = ev.nodes[i];
49 | n.n.x = n.ox;
50 | n.n.y = n.oy;
51 | n.n.dirty = true;
52 | }
53 | } else if (ev.t == "edit") {
54 | for (var i in ev.changes) {
55 | ev.node[i] = ev.changes[i];
56 | }
57 | RED.editor.updateNodeProperties(ev.node);
58 | for (var i in ev.links) {
59 | RED.nodes.addLink(ev.links[i]);
60 | }
61 | RED.editor.validateNode(ev.node);
62 | ev.node.dirty = true;
63 | }
64 | RED.view.dirty(ev.dirty);
65 | RED.view.redraw();
66 | }
67 | }
68 | }
69 |
70 | }();
71 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Node-RED
2 |
3 | A visual tool for wiring the Internet of Things.
4 |
5 | ## Quick Start
6 |
7 | Check out [INSTALL](INSTALL.md) for full instructions on getting started.
8 |
9 | 1. download the zip and unzip, or git clone
10 | 2. cd node-red
11 | 3. npm install
12 | 4. node red.js
13 | 5. Open
14 |
15 | ## Documentation
16 |
17 | More documentation can be found [here](http://nodered.org/docs).
18 |
19 | ## Browser Support
20 |
21 | The Node-RED editor runs in the browser. We routinely develop and test using
22 | Chrome and Firefox. We have anecdotal evidence that it works in IE9.
23 |
24 | We do not yet support mobile browsers, although that is high on our priority
25 | list.
26 |
27 | ## Contributing
28 |
29 | ### Reporting issues
30 |
31 | Please raise any bug reports or feature requests on the project's issue
32 | tracker. Be sure to search the list to see if your issue has already
33 | been raised.
34 |
35 | ### Creating new nodes
36 |
37 | The plugin nature of Node-RED means anyone can create a new node to extend
38 | its capabilities.
39 |
40 | We want to avoid duplication as that can lead to confusion. Many of our existing
41 | nodes offer a starting point of functionality. If they are missing features,
42 | we would rather extend them than add separate 'advanced' versions. But the key
43 | to that approach is getting the UX right to not lose the simplicity.
44 |
45 | We are also going to be quite selective over what nodes are included in the main
46 | repository - enough to be useful, but not so many that new user is overwhelmed.
47 |
48 | To contribute a new node, please raise a pull-request against the
49 | `node-red-nodes` repository.
50 |
51 | Eventually, the nodes will be npm-installable, but we're not there yet. We'll
52 | also have some sort of registry of nodes to help with discoverability.
53 |
54 | ### Pull-Requests
55 |
56 | In order for us to accept pull-requests, the contributor must first complete
57 | a Contributor License Agreement (CLA). This clarifies the intellectual
58 | property license granted with any contribution. It is for your protection as a
59 | Contributor as well as the protection of IBM and its customers; it does not
60 | change your rights to use your own Contributions for any other purpose.
61 |
62 | Once you have created a pull-request, we'll provide a link to the appropriate
63 | CLA document.
64 |
65 | If you are an IBMer, please contact us directly as the contribution process is
66 | slightly different.
67 |
68 | ## Authors
69 |
70 | Node-RED is a creation of the IBM Emerging Technology Services team.
71 |
72 | * Nick O'Leary [@knolleary](http://twitter.com/knolleary)
73 | * Dave Conway-Jones [@ceejay](http://twitter.com/ceejay)
74 |
75 | ## Copyright and license
76 |
77 | Copyright 2013 IBM Corp. under [the Apache 2.0 license](LICENSE).
78 |
--------------------------------------------------------------------------------
/nodes/storage/67-leveldb.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var lvldb = require('level');
19 |
20 | function LevelNode(n) {
21 | RED.nodes.createNode(this,n);
22 | this.dbname = n.db;
23 | var node = this;
24 | lvldb(this.dbname, function(err, db) {
25 | if (err) node.error(err);
26 | node.db = db;
27 | });
28 | }
29 | RED.nodes.registerType("leveldbase",LevelNode);
30 | LevelNode.prototype.close = function() {
31 | this.db.close();
32 | }
33 |
34 | function LevelDBNodeIn(n) {
35 | RED.nodes.createNode(this,n);
36 | this.level = n.level;
37 | this.levelConfig = RED.nodes.getNode(this.level);
38 |
39 | if (this.levelConfig) {
40 | var node = this;
41 | node.on("input", function(msg) {
42 | if (typeof msg.topic === 'string') {
43 | node.levelConfig.db.get(msg.topic, function(err, value) {
44 | if (err) {
45 | //node.warn(err);
46 | // for some reason they treat nothing found as an error...
47 | msg.payload = null; // so we should return null
48 | }
49 | else { msg.payload = value; }
50 | node.send(msg);
51 | });
52 | }
53 | else {
54 | if (typeof msg.topic !== 'string') node.error("msg.topic (the key is not defined");
55 | }
56 | });
57 | }
58 | else {
59 | this.error("LevelDB database name not configured");
60 | }
61 | }
62 | RED.nodes.registerType("leveldb in",LevelDBNodeIn);
63 |
64 |
65 | function LevelDBNodeOut(n) {
66 | RED.nodes.createNode(this,n);
67 | this.level = n.level;
68 | this.operation = n.operation;
69 | this.levelConfig = RED.nodes.getNode(this.level);
70 |
71 | if (this.levelConfig) {
72 | var node = this;
73 | node.on("input", function(msg) {
74 | if (typeof msg.topic === 'string') {
75 | if (node.operation === "delete") {
76 | node.levelConfig.db.del(msg.topic);
77 | }
78 | else {
79 | node.levelConfig.db.put(msg.topic, msg.payload, function(err) {
80 | if (err) node.error(err);
81 | });
82 | }
83 | }
84 | else {
85 | if (typeof msg.topic !== 'string') node.error("msg.topic (the key is not defined");
86 | }
87 | });
88 | }
89 | else {
90 | this.error("LevelDB database name not configured");
91 | }
92 | }
93 | RED.nodes.registerType("leveldb out",LevelDBNodeOut);
94 |
--------------------------------------------------------------------------------
/nodes/core/80-function.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 |
19 | var util = require("util");
20 | var vm = require("vm");
21 | var fs = require('fs');
22 | var fspath = require('path');
23 |
24 | function FunctionNode(n) {
25 | RED.nodes.createNode(this,n);
26 | this.name = n.name;
27 | this.func = n.func;
28 | var functionText = "var results = (function(msg){"+this.func+"})(msg);";
29 | this.topic = n.topic;
30 | this.context = {global:RED.settings.functionGlobalContext || {}};
31 | try {
32 | this.script = vm.createScript(functionText);
33 | this.on("input", function(msg) {
34 | if (msg != null) {
35 | var sandbox = {msg:msg,console:console,util:util,Buffer:Buffer,context:this.context};
36 | try {
37 | this.script.runInNewContext(sandbox);
38 | var results = sandbox.results;
39 |
40 | if (results == null) {
41 | results = [];
42 | } else if (results.length == null) {
43 | results = [results];
44 | }
45 | if (msg._topic) {
46 | for (var m in results) {
47 | if (results[m]) {
48 | if (util.isArray(results[m])) {
49 | for (var n in results[m]) {
50 | results[m][n]._topic = msg._topic;
51 | }
52 | } else {
53 | results[m]._topic = msg._topic;
54 | }
55 | }
56 | }
57 | }
58 | this.send(results);
59 |
60 | } catch(err) {
61 | this.error(err.message);
62 | }
63 | }
64 | });
65 | } catch(err) {
66 | this.error(err.message);
67 | }
68 | }
69 |
70 | RED.nodes.registerType("function",FunctionNode);
71 | RED.library.register("functions");
72 |
--------------------------------------------------------------------------------
/nodes/io/30-socketout.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
38 |
39 |
44 |
45 |
67 |
--------------------------------------------------------------------------------
/nodes/core/75-exec.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
36 |
37 |
44 |
45 |
64 |
--------------------------------------------------------------------------------
/nodes/deprecated/35-rpi-gpio-in.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
47 |
48 |
70 |
--------------------------------------------------------------------------------
/nodes/social/32-feedparse.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var FeedParser = require("feedparser");
19 | var request = require("request");
20 |
21 | function FeedParseNode(n) {
22 | RED.nodes.createNode(this,n);
23 | this.url = n.url;
24 | this.interval = (parseInt(n.interval)||15)*60000;
25 | var node = this;
26 | this.interval_id = null;
27 | this.seen = {};
28 | if (this.url !== "") {
29 | var getFeed = function() {
30 | request(node.url,function(err) {
31 | if (err) node.error(err);
32 | })
33 | .pipe(new FeedParser({feedurl:node.url}))
34 | .on('error', function(error) {
35 | node.error(error);
36 | })
37 | .on('meta', function (meta) {})
38 | .on('article', function (article) {
39 | if (!(article.guid in node.seen) || ( node.seen[article.guid] != 0 && node.seen[article.guid] != article.date.getTime())) {
40 | node.seen[article.guid] = article.date?article.date.getTime():0;
41 | var msg = {
42 | topic:article.origlink||article.link,
43 | payload: article.description,
44 | article: {
45 | summary:article.summary,
46 | link:article.link,
47 | date: article.date,
48 | pubdate: article.pubdate,
49 | author: article.author,
50 | guid: article.guid,
51 | }
52 | };
53 | node.send(msg);
54 | }
55 | })
56 | .on('end', function () {
57 | });
58 | };
59 | this.interval_id = setInterval(getFeed,node.interval);
60 | getFeed();
61 |
62 | } else {
63 | this.error("Invalid url");
64 | }
65 | }
66 |
67 | RED.nodes.registerType("feedparse",FeedParseNode);
68 |
69 | FeedParseNode.prototype.close = function() {
70 | if (this.interval_id != null) {
71 | clearInterval(this.interval_id);
72 | }
73 | }
74 |
75 |
76 |
--------------------------------------------------------------------------------
/nodes/storage/50-file.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
37 |
38 |
43 |
44 |
67 |
--------------------------------------------------------------------------------
/nodes/io/10-mqtt.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var connectionPool = require("./lib/mqttConnectionPool");
19 | var util = require("util");
20 |
21 | function MQTTBrokerNode(n) {
22 | RED.nodes.createNode(this,n);
23 | this.broker = n.broker;
24 | this.port = n.port;
25 | }
26 | RED.nodes.registerType("mqtt-broker",MQTTBrokerNode);
27 |
28 |
29 | function MQTTInNode(n) {
30 | RED.nodes.createNode(this,n);
31 | this.topic = n.topic;
32 | this.broker = n.broker;
33 | this.brokerConfig = RED.nodes.getNode(this.broker);
34 | if (this.brokerConfig) {
35 | this.client = connectionPool.get(this.brokerConfig.broker,this.brokerConfig.port);
36 | var node = this;
37 | this.client.subscribe(this.topic,2,function(topic,payload,qos,retain) {
38 | var msg = {topic:topic,payload:payload,qos:qos,retain:retain};
39 | if ((node.brokerConfig.broker == "localhost")||(node.brokerConfig.broker == "127.0.0.1")) {
40 | msg._topic = topic;
41 | }
42 | node.send(msg);
43 | });
44 | this.client.connect();
45 | } else {
46 | this.error("missing broker configuration");
47 | }
48 | }
49 |
50 | RED.nodes.registerType("mqtt in",MQTTInNode);
51 |
52 | MQTTInNode.prototype.close = function() {
53 | if (this.client) {
54 | this.client.disconnect();
55 | }
56 | }
57 |
58 |
59 | function MQTTOutNode(n) {
60 | RED.nodes.createNode(this,n);
61 |
62 | this.topic = n.topic;
63 | this.broker = n.broker;
64 |
65 | this.brokerConfig = RED.nodes.getNode(this.broker);
66 |
67 | if (this.brokerConfig) {
68 | this.client = connectionPool.get(this.brokerConfig.broker,this.brokerConfig.port);
69 | this.on("input",function(msg) {
70 | if (msg != null) {
71 | if (this.topic) {
72 | msg.topic = this.topic;
73 | }
74 | this.client.publish(msg);
75 | }
76 | });
77 | this.client.connect();
78 | } else {
79 | this.error("missing broker configuration");
80 | }
81 | }
82 |
83 | RED.nodes.registerType("mqtt out",MQTTOutNode);
84 |
85 | MQTTOutNode.prototype.close = function() {
86 | if (this.client) {
87 | this.client.disconnect();
88 | }
89 | }
90 |
91 |
--------------------------------------------------------------------------------
/nodes/core/20-inject.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | try {
19 | var cron = require("cron");
20 | } catch(err) {
21 | require("util").log("[inject] Warning: cannot find module 'cron'");
22 | }
23 |
24 | function InjectNode(n) {
25 | RED.nodes.createNode(this,n);
26 | this.topic = n.topic;
27 | this.payload = n.payload;
28 | this.repeat = n.repeat;
29 | this.crontab = n.crontab;
30 | this.once = n.once;
31 | var node = this;
32 | this.interval_id = null;
33 | this.cronjob = null;
34 |
35 | if (this.repeat && !isNaN(this.repeat) && this.repeat > 0) {
36 | this.repeat = this.repeat * 1000;
37 | this.log("repeat = "+this.repeat);
38 | this.interval_id = setInterval( function() {
39 | node.emit("input",{});
40 | }, this.repeat );
41 | } else if (this.crontab) {
42 | if (cron) {
43 | this.log("crontab = "+this.crontab);
44 | this.cronjob = new cron.CronJob(this.crontab,
45 | function() {
46 | node.emit("input",{});
47 | },
48 | null,true);
49 | } else {
50 | this.error("'cron' module not found");
51 | }
52 | }
53 |
54 | if (this.once) {
55 | setTimeout( function(){ node.emit("input",{}); }, 50);
56 | }
57 |
58 | this.on("input",function(msg) {
59 | var msg = {topic:this.topic,payload:this.payload};
60 | if (msg.payload == "") { msg.payload = Date.now(); }
61 | this.send(msg);
62 | msg = null;
63 | });
64 | }
65 |
66 | RED.nodes.registerType("inject",InjectNode);
67 |
68 | InjectNode.prototype.close = function() {
69 | if (this.interval_id != null) {
70 | clearInterval(this.interval_id);
71 | this.log("inject: repeat stopped");
72 | } else if (this.cronjob != null) {
73 | this.cronjob.stop();
74 | this.log("inject: cronjob stopped");
75 | delete this.cronjob;
76 | }
77 | }
78 |
79 | RED.app.post("/inject/:id", function(req,res) {
80 | var node = RED.nodes.getNode(req.params.id);
81 | if (node != null) {
82 | try {
83 | node.receive();
84 | res.send(200);
85 | } catch(err) {
86 | res.send(500);
87 | node.error("Inject failed:"+err);
88 | console.log(err.stack);
89 | }
90 | } else {
91 | res.send(404);
92 | }
93 | });
94 |
--------------------------------------------------------------------------------
/nodes/io/30-socketin.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
41 |
42 |
47 |
48 |
70 |
--------------------------------------------------------------------------------
/public/red/ui/palette.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 | RED.palette = function() {
17 |
18 | function addNodeType(nt,def) {
19 |
20 | if (def.category != 'config') {
21 | var d = document.createElement("div");
22 | d.id = "pn_"+nt;
23 | d.type = nt;
24 |
25 | var label = /^(.*?)( in| out)?$/.exec(nt)[1];
26 | d.innerHTML = ''+label+"
";
27 | d.className="palette_node";
28 | if (def.icon) {
29 | d.style.backgroundImage = "url(icons/"+def.icon+")";
30 | if (def.align == "right") {
31 | d.style.backgroundPosition = "95% 50%";
32 | } else if (def.inputs > 0) {
33 | d.style.backgroundPosition = "10% 50%";
34 | }
35 | }
36 |
37 | d.style.backgroundColor = def.color;
38 |
39 | if (def.outputs > 0) {
40 | var port = document.createElement("div");
41 | port.className = "palette_port palette_port_output";
42 | d.appendChild(port);
43 | }
44 |
45 | if (def.inputs > 0) {
46 | var port = document.createElement("div");
47 | port.className = "palette_port";
48 | d.appendChild(port);
49 | }
50 |
51 | // TODO: add categories dynamically?
52 | $("#palette-"+def.category).append(d);
53 |
54 | d.onmousedown = function(e) { e.preventDefault(); }
55 |
56 | $(d).popover({
57 | title:d.type,
58 | placement:"right",
59 | trigger: "hover",
60 | delay: { show: 750, hide: 50 },
61 | html: true,
62 | title: nt,
63 | container:'body',
64 | content: $(($("script[data-help-name|='"+nt+"']").html()||"no information available
").trim())[0]
65 | });
66 |
67 | $(d).draggable({
68 | helper: 'clone',
69 | appendTo: 'body',
70 | revert: true,
71 | revertDuration: 50
72 | });
73 | }
74 | }
75 |
76 | $(".palette-header").click(
77 | function(e) {
78 | $(this).next().slideToggle();
79 | $(this).children("i").toggleClass("expanded");
80 | });
81 |
82 |
83 | return {
84 | add:addNodeType
85 | };
86 | }();
87 |
--------------------------------------------------------------------------------
/nodes/social/61-imap.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var Imap = require('imap');
19 | var inspect = require('util').inspect;
20 | var oldmail = {};
21 |
22 | try {
23 | var emailkey = require("../../settings").email || require("../../../emailkeys.js");
24 | } catch(err) {
25 | throw new Error("Failed to load Email credentials");
26 | }
27 |
28 | var imap = new Imap({
29 | user: emailkey.user,
30 | password: emailkey.pass,
31 | host: emailkey.server||"imap.gmail.com",
32 | port: emailkey.port||"993",
33 | secure: true
34 | });
35 |
36 | function show(obj) {
37 | return inspect(obj, false, Infinity);
38 | }
39 |
40 | function fail(err) {
41 | console.log('[imap] : ' + err);
42 | }
43 |
44 | function openInbox(cb) {
45 | imap.connect(function(err) {
46 | if (err) fail(err);
47 | imap.openBox('INBOX', true, cb);
48 | });
49 | }
50 |
51 | function ImapNode(n) {
52 | RED.nodes.createNode(this,n);
53 | this.name = n.name;
54 | this.repeat = n.repeat * 1000;
55 | var node = this;
56 | this.interval_id = null;
57 |
58 | if (this.repeat && !isNaN(this.repeat) && this.repeat > 0) {
59 | this.log("repeat = "+this.repeat);
60 | this.interval_id = setInterval( function() {
61 | node.emit("input",{});
62 | }, this.repeat );
63 | }
64 |
65 | this.on("input", function(msg) {
66 | openInbox(function(err, mailbox) {
67 | if (err) fail(err);
68 | imap.seq.fetch(mailbox.messages.total + ':*', { struct: false },
69 | { headers: ['from', 'subject'],
70 | body: true,
71 | cb: function(fetch) {
72 | fetch.on('message', function(msg) {
73 | //node.log('Saw message no. ' + msg.seqno);
74 | var pay = {};
75 | var body = '';
76 | msg.on('headers', function(hdrs) {
77 | pay.from = hdrs.from[0];
78 | pay.topic = hdrs.subject[0];
79 | });
80 | msg.on('data', function(chunk) {
81 | body += chunk.toString('utf8');
82 | });
83 | msg.on('end', function() {
84 | pay.payload = body;
85 | if ((pay.topic !== oldmail.topic)|(pay.payload !== oldmail.payload)) {
86 | oldmail = pay;
87 | //node.log("From: "+pay.from);
88 | node.log("Subj: "+pay.topic);
89 | //node.log("Body: "+pay.payload);
90 | node.send(pay);
91 | }
92 | });
93 | });
94 | }
95 | }, function(err) {
96 | if (err) node.log("Err : "+err);
97 | //node.log("Done fetching messages.");
98 | imap.logout();
99 | }
100 | );
101 | });
102 |
103 | });
104 | }
105 |
106 | RED.nodes.registerType("imap",ImapNode);
107 |
108 | ImapNode.prototype.close = function() {
109 | if (this.interval_id != null) {
110 | clearInterval(this.interval_id);
111 | this.log("inject: repeat stopped");
112 | }
113 | }
114 |
115 |
--------------------------------------------------------------------------------
/nodes/core/90-comment.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
29 |
30 |
33 |
34 |
86 |
--------------------------------------------------------------------------------
/nodes/io/21-httpin.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
36 |
37 |
64 |
65 |
86 |
--------------------------------------------------------------------------------
/nodes/storage/65-redisout.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var util = require("util");
19 | var redis = require("redis");
20 |
21 | var hashFieldRE = /^([^=]+)=(.*)$/;
22 |
23 | var redisConnectionPool = function() {
24 | var connections = {};
25 | var obj = {
26 | get: function(host,port) {
27 | var id = host+":"+port;
28 | if (!connections[id]) {
29 | connections[id] = redis.createClient(port,host);
30 | connections[id].on("error",function(err) {
31 | util.log("[redis] "+err);
32 | });
33 | connections[id].on("connect",function() {
34 | util.log("[redis] connected to "+host+":"+port);
35 | });
36 | connections[id]._id = id;
37 | connections[id]._nodeCount = 0;
38 | }
39 | connections[id]._nodeCount += 1;
40 | return connections[id];
41 | },
42 | close: function(connection) {
43 | connection._nodeCount -= 1;
44 | if (connection._nodeCount == 0) {
45 | if (connection) {
46 | clearTimeout(connection.retry_timer);
47 | connection.end();
48 | }
49 | delete connections[connection._id];
50 | }
51 | }
52 | };
53 | return obj;
54 | }();
55 |
56 |
57 | function RedisOutNode(n) {
58 | RED.nodes.createNode(this,n);
59 | this.port = n.port||"6379";
60 | this.hostname = n.hostname||"127.0.0.1";
61 | this.key = n.key;
62 | this.structtype = n.structtype;
63 |
64 | this.client = redisConnectionPool.get(this.hostname,this.port);
65 |
66 | this.on("input", function(msg) {
67 | if (msg != null) {
68 | var k = this.key || msg.topic;
69 | if (k) {
70 | if (this.structtype == "string") {
71 | this.client.set(k,msg.payload);
72 | } else if (this.structtype == "hash") {
73 | var r = hashFieldRE.exec(msg.payload);
74 | if (r) {
75 | this.client.hset(k,r[1],r[2]);
76 | } else {
77 | this.warn("Invalid payload for redis hash");
78 | }
79 | } else if (this.structtype == "set") {
80 | this.client.sadd(k,msg.payload);
81 | } else if (this.structtype == "list") {
82 | this.client.rpush(k,msg.payload);
83 | }
84 | } else {
85 | this.warn("No key or topic set");
86 | }
87 | }
88 | });
89 | }
90 |
91 | RED.nodes.registerType("redis out",RedisOutNode);
92 |
93 | RedisOutNode.prototype.close = function() {
94 | redisConnectionPool.close(this.client);
95 | }
96 |
97 |
--------------------------------------------------------------------------------
/nodes/io/31-tcpout.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
42 |
43 |
51 |
52 |
87 |
--------------------------------------------------------------------------------
/nodes/core/58-debug.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 |
19 | var util = require("util");
20 | var ws = require('ws');
21 | var events = require("events");
22 | var debuglength = RED.settings.debugMaxLength||1000;
23 |
24 | function DebugNode(n) {
25 | RED.nodes.createNode(this,n);
26 | this.name = n.name;
27 | this.complete = n.complete;
28 | this.active = (n.active == null)||n.active;
29 |
30 | this.on("input",function(msg) {
31 | if (this.active) {
32 | if (msg.payload instanceof Buffer) {
33 | msg.payload = "(Buffer) "+msg.payload.toString();
34 | }
35 | if (this.complete == "true") {
36 | DebugNode.send({id:this.id,name:this.name,topic:msg.topic,msg:msg,_path:msg._path});
37 | } else {
38 | if (typeof msg.payload !== "undefined") {
39 | DebugNode.send({id:this.id,name:this.name,topic:msg.topic,msg:msg.payload,_path:msg._path});
40 | }
41 | }
42 | }
43 | });
44 | }
45 |
46 | RED.nodes.registerType("debug",DebugNode);
47 |
48 | DebugNode.send = function(msg) {
49 | if (msg.msg instanceof Error) {
50 | msg.msg = msg.msg.toString();
51 | }
52 | else if (typeof msg.msg === 'object') {
53 | var seen = [];
54 | msg.msg = "(Object) " + JSON.stringify(msg.msg, function(key, value) {
55 | if (typeof value === 'object' && value !== null) {
56 | if (seen.indexOf(value) !== -1) { return "[circular]"; }
57 | seen.push(value);
58 | }
59 | return value;
60 | }," ");
61 | seen = null;
62 | }
63 | else if (typeof msg.msg === "boolean") msg.msg = "(boolean) "+msg.msg.toString();
64 | else if (msg.msg === 0) msg.msg = "0";
65 |
66 | if (msg.msg.length > debuglength) {
67 | msg.msg = msg.msg.substr(0,debuglength) +" ....";
68 | }
69 |
70 | for (var i in DebugNode.activeConnections) {
71 | var ws = DebugNode.activeConnections[i];
72 | try {
73 | var p = JSON.stringify(msg);
74 | ws.send(p);
75 | } catch(err) {
76 | util.log("[debug] ws error : "+err);
77 | }
78 | }
79 | }
80 |
81 | DebugNode.activeConnections = [];
82 | DebugNode.wsServer = new ws.Server({server:RED.server});
83 | DebugNode.wsServer.on('connection',function(ws) {
84 | DebugNode.activeConnections.push(ws);
85 | ws.on('close',function() {
86 | for (var i in DebugNode.activeConnections) {
87 | if (DebugNode.activeConnections[i] === ws) {
88 | DebugNode.activeConnections.splice(i,1);
89 | break;
90 | }
91 | }
92 | });
93 | });
94 |
95 | DebugNode.logHandler = new events.EventEmitter();
96 | DebugNode.logHandler.on("log",function(msg) {
97 | if (msg.level == "warn" || msg.level == "error") {
98 | DebugNode.send(msg);
99 | }
100 | });
101 | RED.nodes.addLogHandler(DebugNode.logHandler);
102 |
103 | RED.app.post("/debug/:id", function(req,res) {
104 | var node = RED.nodes.getNode(req.params.id);
105 | if (node != null) {
106 | if (node.active) {
107 | node.active = false;
108 | res.send(201);
109 | } else {
110 | node.active = true;
111 | res.send(200);
112 | }
113 | } else {
114 | res.send(404);
115 | }
116 | });
117 |
--------------------------------------------------------------------------------
/nodes/core/80-template.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
30 |
31 |
36 |
37 |
92 |
--------------------------------------------------------------------------------
/nodes/social/92-xmpp.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var xmpp = require('simple-xmpp');
19 |
20 | try {
21 | var xmppkey = require("../../settings").xmpp || require("../../../xmppkeys.js");
22 | } catch(err) {
23 | throw new Error("Failed to load XMPP credentials");
24 | }
25 |
26 | function XmppNode(n) {
27 | RED.nodes.createNode(this,n);
28 | this.server = n.server;
29 | this.port = n.port;
30 | this.join = n.join || false;
31 | this.nick = n.nick || "Node-RED";
32 | this.sendAll = n.sendObject;
33 | this.to = n.to || "";
34 | var node = this;
35 |
36 | setTimeout(function() {
37 | xmpp.connect({
38 | jid : xmppkey.jid,
39 | password : xmppkey.password,
40 | host : this.server,
41 | port : this.port,
42 | skipPresence : true,
43 | reconnect : false
44 | });
45 | }, 5000);
46 |
47 | xmpp.on('online', function() {
48 | node.log('connected to '+node.server);
49 | xmpp.setPresence('online', node.nick+' online');
50 | if (node.join) {
51 | xmpp.join(node.to+'/'+node.nick);
52 | }
53 | });
54 |
55 | xmpp.on('chat', function(from, message) {
56 | var msg = { topic:from, payload:message };
57 | node.send([msg,null]);
58 | });
59 |
60 | xmpp.on('groupchat', function(conference, from, message, stamp) {
61 | var msg = { topic:from, payload:message, room:conference };
62 | if (from != node.nick) { node.send([msg,null]); }
63 | });
64 |
65 | //xmpp.on('chatstate', function(from, state) {
66 | //console.log('%s is currently %s', from, state);
67 | //var msg = { topic:from, payload:state };
68 | //node.send([null,msg]);
69 | //});
70 |
71 | xmpp.on('buddy', function(jid, state, statusText) {
72 | node.log(jid+" is "+state+" : "+statusText);
73 | var msg = { topic:jid, payload: { presence:state, status:statusText} };
74 | node.send([null,msg]);
75 | });
76 |
77 | xmpp.on('error', function(err) {
78 | console.error(err);
79 | });
80 |
81 | xmpp.on('close', function(err) {
82 | node.log('connection closed');
83 | });
84 |
85 | xmpp.on('subscribe', function(from) {
86 | xmpp.acceptSubscription(from);
87 | });
88 |
89 | this.on("input", function(msg) {
90 | var to = msg.topic;
91 | if (node.to != "") { to = node.to; }
92 | if (node.sendAll) {
93 | xmpp.send(to, JSON.stringify(msg), node.join);
94 | }
95 | else {
96 | xmpp.send(to, msg.payload, node.join);
97 | }
98 | });
99 |
100 | this._close = function() {
101 | xmpp.setPresence('offline');
102 | //xmpp.conn.end();
103 | // TODO - DCJ NOTE... this is not good. It leaves the connection up over a restart - which will end up with bad things happening...
104 | // (but requires the underlying xmpp lib to be fixed (which does have an open bug request on fixing the close method)).
105 | 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.");
106 | }
107 | }
108 |
109 | RED.nodes.registerType("xmpp",XmppNode);
110 |
111 | XmppNode.prototype.close = function() {
112 | this._close();
113 | }
114 |
--------------------------------------------------------------------------------
/nodes/io/32-multicast.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var dgram = require('dgram');
19 |
20 | // The Input Node
21 | function MCastIn(n) {
22 | RED.nodes.createNode(this,n);
23 | this.group = n.group;
24 | this.port = n.port;
25 | this.host = n.host || null;
26 | this.base64 = n.base64;
27 | this.iface = n.iface || null;
28 | this.multicast = n.multicast;
29 | var node = this;
30 |
31 | var server = dgram.createSocket('udp4');
32 |
33 | server.on("error", function (err) {
34 | console.log("udp listener error:\n" + err.stack);
35 | server.close();
36 | });
37 |
38 | server.on('message', function (message, remote) {
39 | var msg;
40 | if (node.base64) { msg = { payload:message.toString('base64'), fromip:remote.address+':'+remote.port }; }
41 | else { msg = { payload:message, fromip:remote.address+':'+remote.port }; }
42 | node.send(msg);
43 | });
44 |
45 | server.on('listening', function () {
46 | var address = server.address();
47 | node.log('udp listener at ' + address.address + ":" + address.port);
48 | if (node.multicast) {
49 | server.setBroadcast(true)
50 | server.setMulticastTTL(128);
51 | server.addMembership(node.group,node.iface);
52 | node.log("udp multicast group "+node.group);
53 | }
54 | });
55 |
56 | //server.bind(node.port,node.host);
57 | server.bind(node.port,node.host);
58 |
59 | this._close = function() {
60 | server.close();
61 | node.log('udp listener stopped');
62 | }
63 |
64 | }
65 |
66 | MCastIn.prototype.close = function() {
67 | this._close();
68 | }
69 | RED.nodes.registerType("multicast in",MCastIn);
70 |
71 | // The Output Node
72 | function MCastOut(n) {
73 | RED.nodes.createNode(this,n);
74 | this.group = n.group;
75 | this.port = n.port;
76 | this.host = n.host || null;
77 | this.base64 = n.base64;
78 | this.iface = n.iface || null;
79 | this.multicast = n.multicast;
80 | var node = this;
81 |
82 | var sock = dgram.createSocket('udp4'); // only use ipv4 for now
83 | sock.bind(node.port); // have to bind before you can enable broadcast...
84 | sock.setBroadcast(true); // turn on broadcast
85 | sock.setMulticastTTL(128);
86 | sock.addMembership(node.group,node.iface); // Add to the multicast group
87 | node.log('udp multicaster ready on '+node.group+":"+node.port);
88 |
89 | node.on("input", function(msg) {
90 | if (msg.payload != null) {
91 | console.log("MCast:",msg.payload);
92 | var message;
93 | if (node.base64) {
94 | message = new Buffer(msg.payload,'base64');
95 | }
96 | else {
97 | message = new Buffer(msg.payload);
98 | }
99 | sock.send(message, 0, message.length, node.port, node.group, function(err, bytes) {
100 | if (err) node.error("udp : "+err);
101 | //util.log('[socket out] udp :' +bytes);
102 | });
103 | }
104 | });
105 |
106 | this._close = function() {
107 | sock.close();
108 | node.log('udp multicaster stopped');
109 | }
110 |
111 | }
112 |
113 | RED.nodes.registerType("multicast out",MCastOut);
114 |
115 | MCastOut.prototype.close = function() {
116 | this._close();
117 | }
118 |
119 |
--------------------------------------------------------------------------------
/nodes/social/92-xmpp.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
48 |
49 |
56 |
57 |
81 |
--------------------------------------------------------------------------------
/nodes/99-sample.html.demo:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
43 |
44 |
45 |
46 |
56 |
57 |
58 |
59 |
77 |
--------------------------------------------------------------------------------
/public/red/ui/sidebar.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 | RED.sidebar = function() {
17 |
18 | $('#sidebar').tabs();
19 |
20 | $('#btn-sidebar').click(function() {toggleSidebar();});
21 | RED.keyboard.add(/* SPACE */ 32,{ctrl:true},function(){toggleSidebar();d3.event.preventDefault();});
22 |
23 |
24 | var sidebarSeparator = {};
25 | $("#sidebar-separator").draggable({
26 | axis: "x",
27 | start:function(event,ui) {
28 | var winWidth = $(window).width();
29 | sidebarSeparator.start = ui.position.left;
30 | sidebarSeparator.width = $("#sidebar").width();
31 | sidebarSeparator.chartWidth = $("#chart").width();
32 | sidebarSeparator.chartRight = winWidth-$("#chart").width()-$("#chart").offset().left-2;
33 | sidebarSeparator.closing = false;
34 | },
35 | drag: function(event,ui) {
36 | var d = ui.position.left-sidebarSeparator.start;
37 | var newSidebarWidth = sidebarSeparator.width-d;
38 |
39 | if (newSidebarWidth > 180 && sidebarSeparator.chartWidth+d > 200) {
40 | var newChartRight = sidebarSeparator.chartRight-d;
41 | $("#chart").css("right",newChartRight);
42 | $("#chart-zoom-controls").css("right",newChartRight+20);
43 | $("#sidebar").width(newSidebarWidth);
44 | }
45 | if (newSidebarWidth < 150 && !sidebarSeparator.closing) {
46 | $("#sidebar").addClass("closing");
47 | sidebarSeparator.closing = true;
48 | }
49 | if (newSidebarWidth >= 150 && sidebarSeparator.closing) {
50 | sidebarSeparator.closing = false;
51 | $("#sidebar").removeClass("closing");
52 | }
53 |
54 | },
55 | stop:function(event,ui) {
56 | $("#sidebar-separator").css("left","auto");
57 | $("#sidebar-separator").css("right",($("#sidebar").width()+15)+"px");
58 | if (sidebarSeparator.closing) {
59 | $("#sidebar").removeClass("closing");
60 | toggleSidebar();
61 | }
62 | }
63 | });
64 |
65 | function toggleSidebar() {
66 | if ($('#sidebar').tabs( "option", "active" ) === false) {
67 | $('#sidebar').tabs( "option", "active",0);
68 | }
69 | var btnSidebar = $("#btn-sidebar");
70 | btnSidebar.toggleClass("active");
71 |
72 | if (!btnSidebar.hasClass("active")) {
73 | $("#main-container").addClass("sidebar-closed");
74 | } else {
75 | $("#main-container").removeClass("sidebar-closed");
76 | }
77 | }
78 | toggleSidebar();
79 |
80 | function addTab(title,content) {
81 | var tab = document.createElement("li");
82 | tab.innerHTML = ''+title+'';
83 | $("#sidebar-tabs").append(tab);
84 | $("#sidebar-content").append(content);
85 |
86 | $('#sidebar').tabs("refresh");
87 |
88 | }
89 |
90 | return {
91 | addTab: addTab
92 | }
93 |
94 | }();
95 |
--------------------------------------------------------------------------------
/nodes/io/31-tcpout.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var reconnectTime = RED.settings.socketReconnectTime||10000;
19 | var net = require('net');
20 |
21 | function TcpOut(n) {
22 | RED.nodes.createNode(this,n);
23 | this.host = n.host;
24 | this.port = n.port * 1;
25 | this.base64 = n.base64;
26 | this.beserver = n.beserver;
27 | this.name = n.name;
28 | this.closing = false;
29 | var node = this;
30 |
31 | if (!node.beserver||node.beserver=="client") {
32 | var reconnectTimeout;
33 | var client = null;
34 | var connected = false;
35 |
36 | function setupTcpClient() {
37 | node.log("connecting to "+node.host+":"+node.port);
38 | client = net.connect(node.port, node.host, function() {
39 | connected = true;
40 | node.log("connected to "+node.host+":"+node.port);
41 | });
42 |
43 | client.on('error', function (err) {
44 | node.log('error : '+err);
45 | });
46 |
47 | client.on('end', function (err) {
48 | });
49 |
50 | client.on('close', function() {
51 | node.log("connection lost to "+node.host+":"+node.port);
52 | connected = false;
53 | client.destroy();
54 | if (!node.closing) {
55 | reconnectTimeout = setTimeout(setupTcpClient,reconnectTime);
56 | }
57 | });
58 | }
59 | setupTcpClient();
60 |
61 |
62 | node.on("input", function(msg) {
63 | if (connected && msg.payload != null) {
64 | if (Buffer.isBuffer(msg.payload)) {
65 | client.write(msg.payload);
66 | } else if (typeof msg.payload === "string" && node.base64) {
67 | client.write(new Buffer(msg.payload,'base64'));
68 | } else {
69 | client.write(new Buffer(""+msg.payload));
70 | }
71 | }
72 | });
73 |
74 |
75 | this._close = function() {
76 | this.closing = true;
77 | client.end();
78 | clearTimeout(reconnectTimeout);
79 | }
80 | }
81 |
82 | else {
83 | var connectedSockets = [];
84 | var server = net.createServer(function (socket) {
85 | var remoteDetails = socket.remoteAddress+":"+socket.remotePort;
86 | node.log("connection from "+remoteDetails);
87 | connectedSockets.push(socket);
88 | socket.on('close',function() {
89 | node.log("connection closed from "+remoteDetails);
90 | connectedSockets.splice(connectedSockets.indexOf(socket),1);
91 | });
92 | });
93 | node.on("input", function(msg) {
94 | if (msg.payload != null) {
95 | var buffer;
96 | if (Buffer.isBuffer(msg.payload)) {
97 | buffer = msg.payload;
98 | } else if (typeof msg.payload === "string" && node.base64) {
99 | buffer = new Buffer(msg.payload,'base64');
100 | } else {
101 | buffer = new Buffer(""+msg.payload);
102 | }
103 | for (var i = 0; iError: "+resp,"error");
44 | } else {
45 | RED.notify("Error: no response from server","error");
46 | }
47 | console.log(err,resp);
48 | }
49 | });
50 | }
51 | }
52 |
53 | $('#btn-deploy').click(function() { save(); });
54 |
55 | $( "#node-dialog-confirm-deploy" ).dialog({
56 | title: "Confirm deploy",
57 | modal: true,
58 | autoOpen: false,
59 | width: 530,
60 | height: 230,
61 | buttons: [
62 | {
63 | text: "Confirm deploy",
64 | click: function() {
65 | save(true);
66 | $( this ).dialog( "close" );
67 | }
68 | },
69 | {
70 | text: "Cancel",
71 | click: function() {
72 | $( this ).dialog( "close" );
73 | }
74 | }
75 | ]
76 | });
77 |
78 | function loadNodes() {
79 | $.get('nodes', function(data) {
80 | $("body").append(data);
81 | loadFlows();
82 | });
83 | }
84 |
85 | function loadFlows() {
86 | d3.json("flows",function(nodes) {
87 | RED.nodes.import(nodes);
88 | RED.view.dirty(false);
89 | RED.view.redraw();
90 | });
91 | }
92 |
93 | function showHelp() {
94 |
95 | var dialog = $('#node-help');
96 |
97 | //$("#node-help").draggable({
98 | // handle: ".modal-header"
99 | //});
100 |
101 | dialog.on('show',function() {
102 | RED.keyboard.disable();
103 | });
104 | dialog.on('hidden',function() {
105 | RED.keyboard.enable();
106 | });
107 |
108 | dialog.modal();
109 | }
110 |
111 |
112 | $(function() {
113 | RED.keyboard.add(/* ? */ 191,{shift:true},function(){showHelp();d3.event.preventDefault();});
114 | loadNodes();
115 | });
116 |
117 | return {
118 | };
119 | }();
120 |
121 |
--------------------------------------------------------------------------------
/nodes/hardware/36-rpi-gpio.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var util = require("util");
19 | var exec = require('child_process').exec;
20 | var fs = require('fs');
21 |
22 | if (!fs.existsSync("/usr/local/bin/gpio")) {
23 | exec("cat /proc/cpuinfo | grep BCM27",function(err,stdout,stderr) {
24 | if (stdout.indexOf('BCM27') > -1) {
25 | util.log('[36-rpi-gpio.js] Error: Cannot find Wiring-Pi "gpio" command');
26 | }
27 | // else not on a Pi so don't worry anyone with needless messages.
28 | });
29 | return;
30 | }
31 |
32 | // Map physical P1 pins to Gordon's Wiring-Pi Pins (as they should be V1/V2 tolerant)
33 | var pintable = {
34 | // Physical : WiringPi
35 | "7":"7",
36 | "11":"0",
37 | "12":"1",
38 | "13":"2",
39 | "15":"3",
40 | "16":"4",
41 | "18":"5",
42 | "22":"6"
43 | }
44 | var tablepin = {
45 | // WiringPi : Physical
46 | "7":"7",
47 | "0":"11",
48 | "1":"12",
49 | "2":"13",
50 | "3":"15",
51 | "4":"16",
52 | "5":"18",
53 | "6":"22"
54 | }
55 |
56 | function GPIOInNode(n) {
57 | RED.nodes.createNode(this,n);
58 | this.buttonState = -1;
59 | this.pin = pintable[n.pin];
60 | this.intype = n.intype;
61 | var node = this;
62 |
63 | if (this.pin) {
64 | exec("gpio mode "+node.pin+" "+node.intype, function(err,stdout,stderr) {
65 | if (err) node.error(err);
66 | else {
67 | node._interval = setInterval( function() {
68 | exec("gpio read "+node.pin, function(err,stdout,stderr) {
69 | if (err) node.error(err);
70 | else {
71 | if (node.buttonState !== Number(stdout)) {
72 | var previousState = node.buttonState;
73 | node.buttonState = Number(stdout);
74 | if (previousState !== -1) {
75 | var msg = {topic:"pi/"+tablepin[node.pin], payload:node.buttonState};
76 | node.send(msg);
77 | }
78 | }
79 | }
80 | });
81 | }, 250);
82 | }
83 | });
84 | }
85 | else {
86 | this.error("Invalid GPIO pin: "+this.pin);
87 | }
88 | }
89 |
90 | function GPIOOutNode(n) {
91 | RED.nodes.createNode(this,n);
92 | this.pin = pintable[n.pin];
93 | var node = this;
94 |
95 | if (this.pin) {
96 | process.nextTick(function() {
97 | exec("gpio mode "+node.pin+" out", function(err,stdout,stderr) {
98 | if (err) node.error(err);
99 | else {
100 | node.on("input", function(msg) {
101 | if (msg.payload === "true") msg.payload = true;
102 | if (msg.payload === "false") msg.payload = false;
103 | var out = Number(msg.payload);
104 | if ((out == 0)|(out == 1)) {
105 | exec("gpio write "+node.pin+" "+out, function(err,stdout,stderr) {
106 | if (err) node.error(err);
107 | });
108 | }
109 | else node.warn("Invalid input - not 0 or 1");
110 | });
111 | }
112 | });
113 | });
114 | }
115 | else {
116 | this.error("Invalid GPIO pin: "+this.pin);
117 | }
118 | }
119 |
120 | exec("gpio mode 0 in",function(err,stdout,stderr) {
121 | if (err) {
122 | util.log('[36-rpi-gpio.js] Error: "gpio" command failed for some reason.');
123 | }
124 | exec("gpio mode 1 in");
125 | exec("gpio mode 2 in");
126 | exec("gpio mode 3 in");
127 | exec("gpio mode 4 in");
128 | exec("gpio mode 5 in");
129 | exec("gpio mode 6 in");
130 | exec("gpio mode 7 in",function(err,stdout,stderr) {
131 | RED.nodes.registerType("rpi-gpio in",GPIOInNode);
132 | RED.nodes.registerType("rpi-gpio out",GPIOOutNode);
133 |
134 | GPIOInNode.prototype.close = function() {
135 | clearInterval(this._interval);
136 | }
137 |
138 | GPIOOutNode.prototype.close = function() {
139 | exec("gpio mode "+this.pin+" in");
140 | }
141 |
142 | });
143 | });
144 |
--------------------------------------------------------------------------------
/nodes/core/80-function.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
32 |
33 |
39 |
40 |
97 |
--------------------------------------------------------------------------------
/nodes/storage/67-leveldb.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
23 |
24 |
35 |
36 |
46 |
47 |
53 |
54 |
74 |
75 |
76 |
93 |
94 |
95 |
100 |
101 |
123 |
--------------------------------------------------------------------------------
/nodes/storage/66-mongodb.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 | var mongo = require('mongodb');
19 |
20 | function MongoNode(n) {
21 | RED.nodes.createNode(this,n);
22 | this.hostname = n.hostname;
23 | this.port = n.port;
24 | this.db = n.db;
25 | this.name = n.name;
26 | }
27 | RED.nodes.registerType("mongodb",MongoNode);
28 |
29 |
30 | function MongoOutNode(n) {
31 | RED.nodes.createNode(this,n);
32 | this.collection = n.collection;
33 | this.mongodb = n.mongodb;
34 | this.payonly = n.payonly || false;
35 | this.operation = n.operation;
36 | this.mongoConfig = RED.nodes.getNode(this.mongodb);
37 |
38 | if (this.mongoConfig) {
39 | var node = this;
40 | this.clientDb = new mongo.Db(node.mongoConfig.db, new mongo.Server(node.mongoConfig.hostname, node.mongoConfig.port, {}), {w: 1});
41 | this.clientDb.open(function(err,cli) {
42 | if (err) { node.error(err); }
43 | else {
44 | node.clientDb.collection(node.collection,function(err,coll) {
45 | if (err) { node.error(err); }
46 | else {
47 | node.on("input",function(msg) {
48 | if (node.operation == "store") {
49 | delete msg._topic;
50 | if (node.payonly) coll.save(msg.payload,function(err,item){ if (err){node.error(err);} });
51 | else coll.save(msg,function(err,item){if (err){node.error(err);}});
52 | }
53 | if (node.operation == "delete") {
54 | console.log(msg.payload);
55 | coll.remove(msg.payload, {w:1}, function(err, items){ if (err) node.error(err); });
56 | }
57 | });
58 | }
59 | });
60 | }
61 | });
62 | } else {
63 | this.error("missing mongodb configuration");
64 | }
65 | }
66 |
67 | RED.nodes.registerType("mongodb out",MongoOutNode);
68 |
69 | MongoOutNode.prototype.close = function() {
70 | if (this.clientDb) {
71 | this.clientDb.close();
72 | }
73 | }
74 |
75 | function MongoInNode(n) {
76 | RED.nodes.createNode(this,n);
77 | this.collection = n.collection;
78 | this.mongodb = n.mongodb;
79 | this.mongoConfig = RED.nodes.getNode(this.mongodb);
80 |
81 | if (this.mongoConfig) {
82 | var node = this;
83 | this.clientDb = new mongo.Db(node.mongoConfig.db, new mongo.Server(node.mongoConfig.hostname, node.mongoConfig.port, {}), {w: 1});
84 | this.clientDb.open(function(err,cli) {
85 | if (err) { node.error(err); }
86 | else {
87 | node.clientDb.collection(node.collection,function(err,coll) {
88 | if (err) { node.error(err); }
89 | else {
90 | node.on("input",function(msg) {
91 | msg.projection = msg.projection || {};
92 | coll.find(msg.payload,msg.projection).sort(msg.sort).limit(msg.limit).toArray(function(err, items) {
93 | if (err) { node.error(err); }
94 | msg.payload = items;
95 | delete msg.projection;
96 | delete msg.sort;
97 | delete msg.limit;
98 | node.send(msg);
99 | });
100 | });
101 | }
102 | });
103 | }
104 | });
105 | } else {
106 | this.error("missing mongodb configuration");
107 | }
108 | }
109 |
110 | RED.nodes.registerType("mongodb in",MongoInNode);
111 |
112 | MongoInNode.prototype.close = function() {
113 | if (this.clientDb) {
114 | this.clientDb.close();
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/nodes/io/30-socketin.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2013 IBM Corp.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var RED = require("../../red/red");
18 |
19 | function SocketIn(n) {
20 | RED.nodes.createNode(this,n);
21 | this.port = n.port;
22 | this.topic = n.topic;
23 | this.trans = (n.transport||n.trans||"").toLowerCase();
24 | var node = this;
25 | if (this.trans == "http") {
26 | var http = require('http');
27 | var server = http.createServer(function (req, res) {
28 | //node.log("http "+req.url);
29 | var msg = {topic:node.topic,payload:req.url.slice(1)};
30 | node.send(msg);
31 | res.writeHead(304, {'Content-Type': 'text/plain'});
32 | res.end('\n');
33 | }).listen(node.port);
34 | server.on('error', function (e) {
35 | if (e.code == 'EADDRINUSE') {
36 | setTimeout(node.error('TCP port is already in use - please reconfigure socket.'),250);
37 | }
38 | else { console.log(e); }
39 | server = null;
40 | });
41 | node.log('http listener at http://127.0.0.1:'+node.port+'/');
42 |
43 | this._close = function() {
44 | if (server) server.close();
45 | node.log('http listener stopped');
46 | }
47 | }
48 |
49 | if (this.trans == "tcp") {
50 | var net = require('net');
51 | var server = net.createServer(function (socket) {
52 | var buffer = null;
53 | socket.on('data', function (chunk) {
54 | if (buffer == null) {
55 | buffer = chunk;
56 | } else {
57 | buffer = Buffer.concat([buffer,chunk]);
58 | }
59 | });
60 | socket.on('end', function() {
61 | var msg = {topic:node.topic, payload:buffer, fromip:socket.remoteAddress+':'+socket.remotePort};
62 | node.send(msg);
63 | });
64 | });
65 | server.on('error', function (e) {
66 | if (e.code == 'EADDRINUSE') {
67 | setTimeout(node.error('TCP port is already in use - please reconfigure socket.'),250);
68 | }
69 | else { console.log(e); }
70 | server = null;
71 | });
72 | server.listen(node.port);
73 | node.log('tcp listener on port :'+node.port);
74 |
75 | this._close = function() {
76 | if (server) server.close();
77 | node.log('tcp listener stopped');
78 | }
79 | }
80 |
81 | if (this.trans == "tcpc") {
82 | var net = require('net');
83 | var client;
84 | var to;
85 | function setupTcpClient() {
86 | node.log('tcpc connecting to port :'+node.port);
87 | client = net.connect({port: node.port}, function() {
88 | node.log("tcpc connected");
89 | });
90 |
91 | client.on('data', function (data) {
92 | var msg = {topic:node.topic, payload:data};
93 | node.send(msg);
94 | });
95 |
96 | client.on('end', function() {
97 | node.log("tcpc socket ended");
98 | });
99 |
100 | client.on('close', function() {
101 | node.log('tcpc socket closed');
102 | to = setTimeout(setupTcpClient, 10000); //Try to reconnect
103 | });
104 |
105 | client.on('error', function() {
106 | node.log('tcpc socket error');
107 | client = null;
108 | to = setTimeout(setupTcpClient, 10000); //Try to reconnect
109 | });
110 | }
111 | setupTcpClient();
112 |
113 | this._close = function() {
114 | if (client) client.end();
115 | //client.destroy();
116 | clearTimeout(to);
117 | node.log('tcpc stopped client');
118 | }
119 | setupTcpClient();
120 | }
121 |
122 | if (this.trans == "udp") {
123 | var dgram = require('dgram');
124 | var server = dgram.createSocket('udp4');
125 | server.on('listening', function () {
126 | var address = server.address();
127 | node.log('udp listener at ' + address.address + ":" + address.port);
128 | });
129 | server.on('message', function (message, remote) {
130 | var msg = {topic:node.topic,payload:message,fromip:remote.address+':'+remote.port};
131 | node.send(msg);
132 | });
133 | server.on('error', function (e) {
134 | console.log(e);
135 | server = null;
136 | });
137 | server.bind(node.port);
138 |
139 | this._close = function() {
140 | if (server) server.close();
141 | node.log('udp listener stopped');
142 | }
143 | }
144 |
145 | }
146 |
147 | RED.nodes.registerType("socket in",SocketIn);
148 |
149 | SocketIn.prototype.close = function() {
150 | this._close();
151 | }
152 |
--------------------------------------------------------------------------------