[CCSDK-28] populated the seed code for dgbuilder
[ccsdk/distribution.git] / dgbuilder / core_nodes / hardware / 36-rpi-gpio.js
diff --git a/dgbuilder/core_nodes/hardware/36-rpi-gpio.js b/dgbuilder/core_nodes/hardware/36-rpi-gpio.js
new file mode 100644 (file)
index 0000000..93cbc4e
--- /dev/null
@@ -0,0 +1,185 @@
+/**
+ * Copyright 2013 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **/
+
+module.exports = function(RED) {
+    "use strict";
+    var util = require("util");
+    var exec = require('child_process').exec;
+    var fs =  require('fs');
+
+    var gpioCommand = '/usr/local/bin/gpio';
+
+    if (!fs.existsSync("/dev/ttyAMA0")) { // unlikely if not on a Pi
+        throw "Info : Ignoring Raspberry Pi specific node.";
+    }
+
+    if (!fs.existsSync(gpioCommand)) { // gpio command not installed
+        throw "Info : Can't find Raspberry Pi wiringPi gpio command.";
+    }
+
+    // Map physical P1 pins to Gordon's Wiring-Pi Pins (as they should be V1/V2 tolerant)
+    var pintable = {
+    // Physical : WiringPi
+            "11":"0",
+            "12":"1",
+            "13":"2",
+            "15":"3",
+            "16":"4",
+            "18":"5",
+            "22":"6",
+             "7":"7",
+             "3":"8",
+             "5":"9",
+            "24":"10",
+            "26":"11",
+            "19":"12",
+            "21":"13",
+            "23":"14",
+             "8":"15",
+            "10":"16",
+            "27":"30",
+            "28":"31",
+            "29":"21",
+            "31":"22",
+            "32":"26",
+            "33":"23",
+            "35":"24",
+            "36":"27",
+            "37":"25",
+            "38":"28",
+            "40":"29"
+    }
+    var tablepin = {
+    // WiringPi : Physical
+            "0":"11",
+            "1":"12",
+            "2":"13",
+            "3":"15",
+            "4":"16",
+            "5":"18",
+            "6":"22",
+            "7":"7",
+            "8":"3",
+            "9":"5",
+           "10":"24",
+           "11":"26",
+           "12":"19",
+           "13":"21",
+           "14":"23",
+           "15":"8",
+           "16":"10",
+           "30":"27",
+           "31":"28",
+           "21":"29",
+           "22":"31",
+           "26":"32",
+           "23":"33",
+           "24":"35",
+           "27":"36",
+           "25":"37",
+           "28":"38",
+           "29":"40"
+    }
+
+    function GPIOInNode(n) {
+        RED.nodes.createNode(this,n);
+        this.buttonState = -1;
+        this.pin = pintable[n.pin];
+        this.intype = n.intype;
+        var node = this;
+
+        if (node.pin !== undefined) {
+            exec(gpioCommand+" mode "+node.pin+" "+node.intype, function(err,stdout,stderr) {
+                if (err) { node.error(err); }
+                else {
+                    node._interval = setInterval( function() {
+                        exec(gpioCommand+" read "+node.pin, function(err,stdout,stderr) {
+                            if (err) { node.error(err); }
+                            else {
+                                if (node.buttonState !== Number(stdout)) {
+                                    var previousState = node.buttonState;
+                                    node.buttonState = Number(stdout);
+                                    if (previousState !== -1) {
+                                        var msg = {topic:"pi/"+tablepin[node.pin], payload:node.buttonState};
+                                        node.send(msg);
+                                    }
+                                }
+                            }
+                        });
+                    }, 250);
+                }
+            });
+        }
+        else {
+            node.error("Invalid GPIO pin: "+node.pin);
+        }
+
+        node.on("close", function() {
+            clearInterval(node._interval);
+        });
+    }
+
+    function GPIOOutNode(n) {
+        RED.nodes.createNode(this,n);
+        this.pin = pintable[n.pin];
+        var node = this;
+
+        if (node.pin !== undefined) {
+            process.nextTick(function() {
+                exec(gpioCommand+" mode "+node.pin+" out", function(err,stdout,stderr) {
+                    if (err) { node.error(err); }
+                    else {
+                        node.on("input", function(msg) {
+                            if (msg.payload === "true") { msg.payload = true; }
+                            if (msg.payload === "false") { msg.payload = false; }
+                            var out = Number(msg.payload);
+                            if ((out === 0)|(out === 1)) {
+                                exec(gpioCommand+" write "+node.pin+" "+out, function(err,stdout,stderr) {
+                                    if (err) { node.error(err); }
+                                });
+                            }
+                            else { node.warn("Invalid input - not 0 or 1"); }
+                        });
+                    }
+                });
+            });
+        }
+        else {
+            node.error("Invalid GPIO pin: "+node.pin);
+        }
+
+        node.on("close", function() {
+            exec(gpioCommand+" mode "+node.pin+" in");
+        });
+    }
+
+    var pitype = { type:"" };
+    exec(gpioCommand+" -v | grep Type", function(err,stdout,stderr) {
+        if (err) {
+            util.log('[36-rpi-gpio.js] Error: "'+gpioCommand+' -v" command failed for some reason.');
+        }
+        else {
+            pitype = { type:(stdout.split(","))[0].split(": ")[1], rev:(stdout.split(","))[1].split(": ")[1] };
+        }
+    });
+
+    RED.nodes.registerType("rpi-gpio in",GPIOInNode);
+    RED.nodes.registerType("rpi-gpio out",GPIOOutNode);
+
+    RED.httpAdmin.get('/rpi-gpio/:id',function(req,res) {
+        res.send( JSON.stringify(pitype) );
+    });
+}