node-red-nodes/hardware/pigpiod/pi-gpiod.js

183 lines
7.6 KiB
JavaScript

module.exports = function(RED) {
"use strict";
var Pigpio = require('js-pigpio');
var bcm2pin = {
"2":"3", "3":"5", "4":"7", "14":"8", "15":"10", "17":"11", "18":"12", "27":"13", "22":"15",
"23":"16", "24":"18", "10":"19", "9":"21", "25":"22", "11":"23", "8":"24", "7":"26",
"5":"29", "6":"31", "12":"32", "13":"33", "19":"35", "16":"36", "26":"37", "20":"38", "21":"40"
};
var pinTypes = {
"PUD_OFF":RED._("pi-gpiod:types.input"),
"PUD_UP":RED._("pi-gpiod:types.pullup"),
"PUD_DOWN":RED._("pi-gpiod:types.pulldown"),
"out":RED._("pi-gpiod:types.digout"),
"pwm":RED._("pi-gpiod:types.pwmout"),
"ser":RED._("pi-gpiod:types.servo")
};
function GPioInNode(n) {
RED.nodes.createNode(this,n);
this.host = n.host || "127.0.0.1";
this.port = n.port || 8888;
this.pin = n.pin;
this.pio = bcm2pin[n.pin];
this.intype = n.intype;
this.read = n.read || false;
this.debounce = Number(n.debounce || 25);
var node = this;
var PiGPIO;
if (node.pin !== undefined) {
PiGPIO = new Pigpio();
var inerror = false;
var doit = function() {
PiGPIO.pi(node.host, node.port, function(err) {
if (err) {
node.status({fill:"red",shape:"ring",text:err.code+" "+node.host+":"+node.port});
if (!inerror) { node.error(err); inerror = true; }
node.retry = setTimeout(function() { doit(); }, 5000);
}
else {
inerror = false;
PiGPIO.set_mode(node.pin,PiGPIO.INPUT);
PiGPIO.set_pull_up_down(node.pin,PiGPIO[node.intype]);
PiGPIO.set_glitch_filter(node.pin,node.debounce);
node.status({fill:"green",shape:"dot",text:"node-red:common.status.ok"});
node.cb = PiGPIO.callback(node.pin, PiGPIO.EITHER_EDGE, function(gpio, level, tick) {
node.send({ topic:"pi/"+node.pio, payload:Number(level), host:node.host });
node.status({fill:"green",shape:"dot",text:level});
});
if (node.read) {
setTimeout(function() {
PiGPIO.read(node.pin, function(err, level) {
node.send({ topic:"pi/"+node.pio, payload:Number(level), host:node.host });
node.status({fill:"green",shape:"dot",text:level});
});
}, 20);
}
}
});
}
doit();
}
else {
node.warn(RED._("pi-gpiod:errors.invalidpin")+": "+node.pio);
}
node.on("close", function(done) {
if (node.retry) { clearTimeout(node.retry); }
node.status({fill:"grey",shape:"ring",text:"pi-gpiod.status.closed"});
node.cb.cancel();
PiGPIO.close();
done();
});
}
RED.nodes.registerType("pi-gpiod in",GPioInNode);
function GPioOutNode(n) {
RED.nodes.createNode(this,n);
this.host = n.host || "127.0.0.1";
this.port = n.port || 8888;
this.pin = n.pin;
this.pio = bcm2pin[n.pin];
this.set = n.set || false;
this.level = parseInt(n.level || 0);
this.out = n.out || "out";
this.freq = parseInt(n.freq) || 800;
this.sermin = Number(n.sermin)/100;
this.sermax = Number(n.sermax)/100;
if (this.sermin > this.sermax) {
var tmp = this.sermin;
this.sermin = this.sermax;
this.sermax = tmp;
}
if (this.sermin < 5) { this.sermin = 5; }
if (this.sermax > 25) { this.sermax = 25; }
var node = this;
var PiGPIO;
function inputlistener(msg) {
if (node.out === "ser" && (msg.payload === null || msg.payload === "")) {
if (!inerror) {
PiGPIO.setServoPulsewidth(node.pin, 0);
node.status({fill:"green",shape:"dot",text:""});
}
else { node.status({fill:"grey",shape:"ring",text:"N/C: " + msg.payload.toString()}); }
}
else {
if (msg.payload === "true") { msg.payload = true; }
if (msg.payload === "false") { msg.payload = false; }
var out = Number(msg.payload);
var limit = 1;
if (node.out !== "out") { limit = 100; }
var pre = "";
if ((out >= 0) && (out <= limit)) {
if (RED.settings.verbose) { node.log("out: "+msg.payload); }
if (!inerror) {
if (node.out === "out") {
PiGPIO.write(node.pin, out);
}
if (node.out === "pwm") {
PiGPIO.set_PWM_frequency(node.pin, node.freq);
PiGPIO.set_PWM_dutycycle(node.pin, parseInt(out * 2.55));
}
if (node.out === "ser") {
var r = (node.sermax - node.sermin) * 100;
PiGPIO.setServoPulsewidth(node.pin, parseInt(1500 - (r/2) + (out * r / 100)));
}
node.status({fill:"green",shape:"dot",text:out.toString()});
}
else {
node.status({fill:"grey",shape:"ring",text:"N/C: " + out.toString()});
}
}
else { node.warn(RED._("pi-gpiod:errors.invalidinput")+": "+out); }
}
}
if (node.pin !== undefined) {
PiGPIO = new Pigpio();
var inerror = false;
var doit = function() {
PiGPIO.pi(node.host, node.port, function(err) {
if (err) {
node.status({fill:"red",shape:"ring",text:err.code+" "+node.host+":"+node.port});
if (!inerror) { node.error(err,err); inerror = true; }
node.retry = setTimeout(function() { doit(); }, 5000);
}
else {
inerror = false;
PiGPIO.set_mode(node.pin,PiGPIO.OUTPUT);
if (node.set) {
setTimeout(function() { PiGPIO.write(node.pin,node.level); }, 25 );
node.status({fill:"green",shape:"dot",text:node.level});
} else {
node.status({fill:"green",shape:"dot",text:"node-red:common.status.ok"});
}
// if (node.out === "pwm") {
// PiGPIO.set_PWM_frequency(1000);
// PiGPIO.set_PWM_range(1000);
// }
}
});
}
doit();
node.on("input", inputlistener);
}
else {
node.warn(RED._("pi-gpiod:errors.invalidpin")+": "+node.pio);
}
node.on("close", function(done) {
if (node.retry) { clearTimeout(node.retry); }
node.status({fill:"grey",shape:"ring",text:"pi-gpiod.status.closed"});
PiGPIO.close();
done();
});
}
RED.nodes.registerType("pi-gpiod out",GPioOutNode);
}