[CCSDK-28] populated the seed code for dgbuilder
[ccsdk/distribution.git] / dgbuilder / core_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 module.exports = function(RED) {
18     "use strict";
19     var util = require("util");
20     var exec = require('child_process').exec;
21     var fs =  require('fs');
22
23     var gpioCommand = '/usr/local/bin/gpio';
24
25     if (!fs.existsSync("/dev/ttyAMA0")) { // unlikely if not on a Pi
26         throw "Info : Ignoring Raspberry Pi specific node.";
27     }
28
29     if (!fs.existsSync(gpioCommand)) { // gpio command not installed
30         throw "Info : Can't find Raspberry Pi wiringPi gpio command.";
31     }
32
33     // Map physical P1 pins to Gordon's Wiring-Pi Pins (as they should be V1/V2 tolerant)
34     var pintable = {
35     // Physical : WiringPi
36             "11":"0",
37             "12":"1",
38             "13":"2",
39             "15":"3",
40             "16":"4",
41             "18":"5",
42             "22":"6",
43              "7":"7",
44              "3":"8",
45              "5":"9",
46             "24":"10",
47             "26":"11",
48             "19":"12",
49             "21":"13",
50             "23":"14",
51              "8":"15",
52             "10":"16",
53             "27":"30",
54             "28":"31",
55             "29":"21",
56             "31":"22",
57             "32":"26",
58             "33":"23",
59             "35":"24",
60             "36":"27",
61             "37":"25",
62             "38":"28",
63             "40":"29"
64     }
65     var tablepin = {
66     // WiringPi : Physical
67             "0":"11",
68             "1":"12",
69             "2":"13",
70             "3":"15",
71             "4":"16",
72             "5":"18",
73             "6":"22",
74             "7":"7",
75             "8":"3",
76             "9":"5",
77            "10":"24",
78            "11":"26",
79            "12":"19",
80            "13":"21",
81            "14":"23",
82            "15":"8",
83            "16":"10",
84            "30":"27",
85            "31":"28",
86            "21":"29",
87            "22":"31",
88            "26":"32",
89            "23":"33",
90            "24":"35",
91            "27":"36",
92            "25":"37",
93            "28":"38",
94            "29":"40"
95     }
96
97     function GPIOInNode(n) {
98         RED.nodes.createNode(this,n);
99         this.buttonState = -1;
100         this.pin = pintable[n.pin];
101         this.intype = n.intype;
102         var node = this;
103
104         if (node.pin !== undefined) {
105             exec(gpioCommand+" mode "+node.pin+" "+node.intype, function(err,stdout,stderr) {
106                 if (err) { node.error(err); }
107                 else {
108                     node._interval = setInterval( function() {
109                         exec(gpioCommand+" read "+node.pin, function(err,stdout,stderr) {
110                             if (err) { node.error(err); }
111                             else {
112                                 if (node.buttonState !== Number(stdout)) {
113                                     var previousState = node.buttonState;
114                                     node.buttonState = Number(stdout);
115                                     if (previousState !== -1) {
116                                         var msg = {topic:"pi/"+tablepin[node.pin], payload:node.buttonState};
117                                         node.send(msg);
118                                     }
119                                 }
120                             }
121                         });
122                     }, 250);
123                 }
124             });
125         }
126         else {
127             node.error("Invalid GPIO pin: "+node.pin);
128         }
129
130         node.on("close", function() {
131             clearInterval(node._interval);
132         });
133     }
134
135     function GPIOOutNode(n) {
136         RED.nodes.createNode(this,n);
137         this.pin = pintable[n.pin];
138         var node = this;
139
140         if (node.pin !== undefined) {
141             process.nextTick(function() {
142                 exec(gpioCommand+" mode "+node.pin+" out", function(err,stdout,stderr) {
143                     if (err) { node.error(err); }
144                     else {
145                         node.on("input", function(msg) {
146                             if (msg.payload === "true") { msg.payload = true; }
147                             if (msg.payload === "false") { msg.payload = false; }
148                             var out = Number(msg.payload);
149                             if ((out === 0)|(out === 1)) {
150                                 exec(gpioCommand+" write "+node.pin+" "+out, function(err,stdout,stderr) {
151                                     if (err) { node.error(err); }
152                                 });
153                             }
154                             else { node.warn("Invalid input - not 0 or 1"); }
155                         });
156                     }
157                 });
158             });
159         }
160         else {
161             node.error("Invalid GPIO pin: "+node.pin);
162         }
163
164         node.on("close", function() {
165             exec(gpioCommand+" mode "+node.pin+" in");
166         });
167     }
168
169     var pitype = { type:"" };
170     exec(gpioCommand+" -v | grep Type", function(err,stdout,stderr) {
171         if (err) {
172             util.log('[36-rpi-gpio.js] Error: "'+gpioCommand+' -v" command failed for some reason.');
173         }
174         else {
175             pitype = { type:(stdout.split(","))[0].split(": ")[1], rev:(stdout.split(","))[1].split(": ")[1] };
176         }
177     });
178
179     RED.nodes.registerType("rpi-gpio in",GPIOInNode);
180     RED.nodes.registerType("rpi-gpio out",GPIOOutNode);
181
182     RED.httpAdmin.get('/rpi-gpio/:id',function(req,res) {
183         res.send( JSON.stringify(pitype) );
184     });
185 }