2 * Copyright 2013 IBM Corp.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 module.exports = function(RED) {
19 var util = require("util");
20 var exec = require('child_process').exec;
21 var fs = require('fs');
23 var gpioCommand = '/usr/local/bin/gpio';
25 if (!fs.existsSync("/dev/ttyAMA0")) { // unlikely if not on a Pi
26 throw "Info : Ignoring Raspberry Pi specific node.";
29 if (!fs.existsSync(gpioCommand)) { // gpio command not installed
30 throw "Info : Can't find Raspberry Pi wiringPi gpio command.";
33 // Map physical P1 pins to Gordon's Wiring-Pi Pins (as they should be V1/V2 tolerant)
35 // Physical : WiringPi
66 // WiringPi : Physical
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;
104 if (node.pin !== undefined) {
105 exec(gpioCommand+" mode "+node.pin+" "+node.intype, function(err,stdout,stderr) {
106 if (err) { node.error(err); }
108 node._interval = setInterval( function() {
109 exec(gpioCommand+" read "+node.pin, function(err,stdout,stderr) {
110 if (err) { node.error(err); }
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};
127 node.error("Invalid GPIO pin: "+node.pin);
130 node.on("close", function() {
131 clearInterval(node._interval);
135 function GPIOOutNode(n) {
136 RED.nodes.createNode(this,n);
137 this.pin = pintable[n.pin];
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); }
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); }
154 else { node.warn("Invalid input - not 0 or 1"); }
161 node.error("Invalid GPIO pin: "+node.pin);
164 node.on("close", function() {
165 exec(gpioCommand+" mode "+node.pin+" in");
169 var pitype = { type:"" };
170 exec(gpioCommand+" -v | grep Type", function(err,stdout,stderr) {
172 util.log('[36-rpi-gpio.js] Error: "'+gpioCommand+' -v" command failed for some reason.');
175 pitype = { type:(stdout.split(","))[0].split(": ")[1], rev:(stdout.split(","))[1].split(": ")[1] };
179 RED.nodes.registerType("rpi-gpio in",GPIOInNode);
180 RED.nodes.registerType("rpi-gpio out",GPIOOutNode);
182 RED.httpAdmin.get('/rpi-gpio/:id',function(req,res) {
183 res.send( JSON.stringify(pitype) );