From 3af6c8c05f7c2be9161e23d37e8c0dd7fb1457d7 Mon Sep 17 00:00:00 2001 From: kev Date: Wed, 26 Apr 2017 17:35:14 +0800 Subject: [PATCH] update node-red-arm --- node-red/arm/Dockerfile | 19 +- node-red/arm/patch/36-rpi-gpio.js | 346 ++++++++++++++++++++++++ node-red/arm/patch/36-rpi-gpio.js.patch | 20 -- node-red/arm/patch/README.md | 2 +- node-red/arm/patch/nrgpio | 22 +- node-red/arm/patch/nrgpio.py | 235 ++++++++++++++++ node-red/arm/patch/nrinput.py | 62 ----- 7 files changed, 608 insertions(+), 98 deletions(-) create mode 100644 node-red/arm/patch/36-rpi-gpio.js delete mode 100644 node-red/arm/patch/36-rpi-gpio.js.patch create mode 100755 node-red/arm/patch/nrgpio.py delete mode 100755 node-red/arm/patch/nrinput.py diff --git a/node-red/arm/Dockerfile b/node-red/arm/Dockerfile index 07317e4..cbdbb3f 100644 --- a/node-red/arm/Dockerfile +++ b/node-red/arm/Dockerfile @@ -6,21 +6,24 @@ FROM easypi/alpine-arm MAINTAINER EasyPi Software Foundation RUN set -xe \ - && apk add --no-cache bash \ - build-base \ + && apk add --no-cache build-base \ ca-certificates \ curl \ nodejs \ - python \ - python-dev \ - sudo \ - && curl https://bootstrap.pypa.io/get-pip.py | python \ - && pip install rpi.gpio \ + python3 \ + python3-dev \ + && ln -sf /usr/bin/python3 /usr/bin/python \ + && pip3 install --no-cache-dir rpi.gpio \ + six \ && npm install -g --unsafe-perm node-red \ node-red-admin \ node-red-dashboard \ + && cd /usr/lib/node_modules/node-red/nodes/core/hardware \ + && curl -sSL https://github.com/vimagick/dockerfiles/raw/master/node-red/arm/patch/nrgpio > nrgpio \ + && curl -sSL https://github.com/vimagick/dockerfiles/raw/master/node-red/arm/patch/nrgpio.py > nrgpio.py \ + && curl -sSL https://github.com/vimagick/dockerfiles/raw/master/node-red/arm/patch/36-rpi-gpio.js > 36-rpi-gpio.js \ && apk del build-base \ - python-dev \ + python3-dev \ && rm -rf /tmp/npm-* WORKDIR /root/.node-red diff --git a/node-red/arm/patch/36-rpi-gpio.js b/node-red/arm/patch/36-rpi-gpio.js new file mode 100644 index 0000000..4dadc45 --- /dev/null +++ b/node-red/arm/patch/36-rpi-gpio.js @@ -0,0 +1,346 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * 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 exec = require('child_process').exec; + var spawn = require('child_process').spawn; + var fs = require('fs'); + + var gpioCommand = __dirname+'/nrgpio'; + + try { + var cpuinfo = fs.readFileSync("/proc/cpuinfo").toString(); + if (cpuinfo.indexOf(": BCM") === -1) { throw "Info : "+RED._("rpi-gpio.errors.ignorenode"); } + } catch(err) { + throw "Info : "+RED._("rpi-gpio.errors.ignorenode"); + } + + try { + fs.statSync("/usr/share/doc/python-rpi.gpio"); // test on Raspbian + // /usr/lib/python3.5/dist-packages/RPi/GPIO + } catch(err) { + try { + fs.statSync("/usr/lib/python3.5/site-packages/RPi/GPIO"); // test on Arch + } + catch(err) { + try { + fs.statSync("/usr/lib/python3.5/dist-packages/RPi/GPIO"); // test on Hypriot + } + catch(err) { + RED.log.warn(RED._("rpi-gpio.errors.libnotfound")); + throw "Warning : "+RED._("rpi-gpio.errors.libnotfound"); + } + } + } + + if ( !(1 & parseInt((fs.statSync(gpioCommand).mode & parseInt("777", 8)).toString(8)[0]) )) { + RED.log.error(RED._("rpi-gpio.errors.needtobeexecutable",{command:gpioCommand})); + throw "Error : "+RED._("rpi-gpio.errors.mustbeexecutable"); + } + + // the magic to make python print stuff immediately + process.env.PYTHONUNBUFFERED = 1; + + var pinsInUse = {}; + var pinTypes = {"out":RED._("rpi-gpio.types.digout"), "tri":RED._("rpi-gpio.types.input"), "up":RED._("rpi-gpio.types.pullup"), "down":RED._("rpi-gpio.types.pulldown"), "pwm":RED._("rpi-gpio.types.pwmout")}; + + function GPIOInNode(n) { + RED.nodes.createNode(this,n); + this.buttonState = -1; + this.pin = n.pin; + this.intype = n.intype; + this.read = n.read || false; + this.debounce = Number(n.debounce || 25); + if (this.read) { this.buttonState = -2; } + var node = this; + if (!pinsInUse.hasOwnProperty(this.pin)) { + pinsInUse[this.pin] = this.intype; + } + else { + if ((pinsInUse[this.pin] !== this.intype)||(pinsInUse[this.pin] === "pwm")) { + node.warn(RED._("rpi-gpio.errors.alreadyset",{pin:this.pin,type:pinTypes[pinsInUse[this.pin]]})); + } + } + + if (node.pin !== undefined) { + node.child = spawn(gpioCommand, ["in",node.pin,node.intype,node.debounce]); + node.running = true; + node.status({fill:"green",shape:"dot",text:"common.status.ok"}); + + node.child.stdout.on('data', function (data) { + var d = data.toString().trim().split("\n"); + for (var i = 0; i < d.length; i++) { + if (node.running && node.buttonState !== -1 && !isNaN(Number(d[i])) && node.buttonState !== d[i]) { + node.send({ topic:"pi/"+node.pin, payload:Number(d[i]) }); + } + node.buttonState = d[i]; + node.status({fill:"green",shape:"dot",text:d[i]}); + if (RED.settings.verbose) { node.log("out: "+d[i]+" :"); } + } + }); + + node.child.stderr.on('data', function (data) { + if (RED.settings.verbose) { node.log("err: "+data+" :"); } + }); + + node.child.on('close', function (code) { + node.running = false; + node.child = null; + if (RED.settings.verbose) { node.log(RED._("rpi-gpio.status.closed")); } + if (node.done) { + node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"}); + node.done(); + } + else { node.status({fill:"red",shape:"ring",text:"rpi-gpio.status.stopped"}); } + }); + + node.child.on('error', function (err) { + if (err.errno === "ENOENT") { node.error(RED._("rpi-gpio.errors.commandnotfound")); } + else if (err.errno === "EACCES") { node.error(RED._("rpi-gpio.errors.commandnotexecutable")); } + else { node.error(RED._("rpi-gpio.errors.error",{error:err.errno})) } + }); + + } + else { + node.warn(RED._("rpi-gpio.errors.invalidpin")+": "+node.pin); + } + + node.on("close", function(done) { + node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"}); + delete pinsInUse[node.pin]; + if (node.child != null) { + node.done = done; + node.child.stdin.write("close "+node.pin); + node.child.kill('SIGKILL'); + } + else { done(); } + }); + } + RED.nodes.registerType("rpi-gpio in",GPIOInNode); + + function GPIOOutNode(n) { + RED.nodes.createNode(this,n); + this.pin = n.pin; + this.set = n.set || false; + this.level = n.level || 0; + this.freq = n.freq || 100; + this.out = n.out || "out"; + var node = this; + if (!pinsInUse.hasOwnProperty(this.pin)) { + pinsInUse[this.pin] = this.out; + } + else { + if ((pinsInUse[this.pin] !== this.out)||(pinsInUse[this.pin] === "pwm")) { + node.warn(RED._("rpi-gpio.errors.alreadyset",{pin:this.pin,type:pinTypes[pinsInUse[this.pin]]})); + } + } + + function inputlistener(msg) { + 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 === "pwm") { limit = 100; } + if ((out >= 0) && (out <= limit)) { + if (RED.settings.verbose) { node.log("out: "+msg.payload); } + if (node.child !== null) { + node.child.stdin.write(msg.payload+"\n"); + node.status({fill:"green",shape:"dot",text:msg.payload.toString()}); + } + else { + node.error(RED._("rpi-gpio.errors.pythoncommandnotfound"),msg); + node.status({fill:"red",shape:"ring",text:"rpi-gpio.status.not-running"}); + } + } + else { node.warn(RED._("rpi-gpio.errors.invalidinput")+": "+out); } + } + + if (node.pin !== undefined) { + if (node.set && (node.out === "out")) { + node.child = spawn(gpioCommand, [node.out,node.pin,node.level]); + node.status({fill:"green",shape:"dot",text:node.level}); + } else { + node.child = spawn(gpioCommand, [node.out,node.pin,node.freq]); + node.status({fill:"green",shape:"dot",text:"common.status.ok"}); + } + node.running = true; + + node.on("input", inputlistener); + + node.child.stdout.on('data', function (data) { + if (RED.settings.verbose) { node.log("out: "+data+" :"); } + }); + + node.child.stderr.on('data', function (data) { + if (RED.settings.verbose) { node.log("err: "+data+" :"); } + }); + + node.child.on('close', function (code) { + node.child = null; + node.running = false; + if (RED.settings.verbose) { node.log(RED._("rpi-gpio.status.closed")); } + if (node.done) { + node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"}); + node.done(); + } + else { node.status({fill:"red",shape:"ring",text:"rpi-gpio.status.stopped"}); } + }); + + node.child.on('error', function (err) { + if (err.errno === "ENOENT") { node.error(RED._("rpi-gpio.errors.commandnotfound")); } + else if (err.errno === "EACCES") { node.error(RED._("rpi-gpio.errors.commandnotexecutable")); } + else { node.error(RED._("rpi-gpio.errors.error")+': ' + err.errno); } + }); + + } + else { + node.warn(RED._("rpi-gpio.errors.invalidpin")+": "+node.pin); + } + + node.on("close", function(done) { + node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"}); + delete pinsInUse[node.pin]; + if (node.child != null) { + node.done = done; + node.child.stdin.write("close "+node.pin); + node.child.kill('SIGKILL'); + } + else { done(); } + }); + + } + RED.nodes.registerType("rpi-gpio out",GPIOOutNode); + + function PiMouseNode(n) { + RED.nodes.createNode(this,n); + this.butt = n.butt || 7; + var node = this; + + node.child = spawn(gpioCommand+".py", ["mouse",node.butt]); + node.status({fill:"green",shape:"dot",text:"common.status.ok"}); + + node.child.stdout.on('data', function (data) { + data = Number(data); + if (data === 1) { node.send({ topic:"pi/mouse", button:data, payload:1 }); } + else { node.send({ topic:"pi/mouse", button:data, payload:0 }); } + }); + + node.child.stderr.on('data', function (data) { + if (RED.settings.verbose) { node.log("err: "+data+" :"); } + }); + + node.child.on('close', function (code) { + node.child = null; + node.running = false; + if (RED.settings.verbose) { node.log(RED._("rpi-gpio.status.closed")); } + if (node.done) { + node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"}); + node.done(); + } + else { node.status({fill:"red",shape:"ring",text:"rpi-gpio.status.stopped"}); } + }); + + node.child.on('error', function (err) { + if (err.errno === "ENOENT") { node.error(RED._("rpi-gpio.errors.commandnotfound")); } + else if (err.errno === "EACCES") { node.error(RED._("rpi-gpio.errors.commandnotexecutable")); } + else { node.error(RED._("rpi-gpio.errors.error")+': ' + err.errno); } + }); + + node.on("close", function(done) { + node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"}); + if (node.child != null) { + node.done = done; + node.child.kill('SIGINT'); + node.child = null; + } + else { done(); } + }); + } + RED.nodes.registerType("rpi-mouse",PiMouseNode); + + function PiKeyboardNode(n) { + RED.nodes.createNode(this,n); + var node = this; + + node.child = spawn(gpioCommand+".py", ["kbd","0"]); + node.status({fill:"green",shape:"dot",text:"common.status.ok"}); + + node.child.stdout.on('data', function (data) { + var b = data.toString().trim().split(","); + var act = "up"; + if (b[1] === "1") { act = "down"; } + if (b[1] === "2") { act = "repeat"; } + node.send({ topic:"pi/key", payload:Number(b[0]), action:act }); + }); + + node.child.stderr.on('data', function (data) { + if (RED.settings.verbose) { node.log("err: "+data+" :"); } + }); + + node.child.on('close', function (code) { + node.running = false; + node.child = null; + if (RED.settings.verbose) { node.log(RED._("rpi-gpio.status.closed")); } + if (node.done) { + node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"}); + node.done(); + } + else { node.status({fill:"red",shape:"ring",text:"rpi-gpio.status.stopped"}); } + }); + + node.child.on('error', function (err) { + if (err.errno === "ENOENT") { node.error(RED._("rpi-gpio.errors.commandnotfound")); } + else if (err.errno === "EACCES") { node.error(RED._("rpi-gpio.errors.commandnotexecutable")); } + else { node.error(RED._("rpi-gpio.errors.error")+': ' + err.errno); } + }); + + node.on("close", function(done) { + node.status({}); + if (node.child != null) { + node.done = done; + node.child.kill('SIGINT'); + node.child = null; + } + else { done(); } + }); + } + RED.nodes.registerType("rpi-keyboard",PiKeyboardNode); + + var pitype = { type:"" }; + exec(gpioCommand+" info", function(err,stdout,stderr) { + if (err) { + RED.log.info(RED._("rpi-gpio.errors.version")); + } + else { + try { + var info = JSON.parse( stdout.trim().replace(/\'/g,"\"") ); + pitype.type = info["TYPE"]; + } + catch(e) { + RED.log.info(RED._("rpi-gpio.errors.sawpitype"),stdout.trim()); + } + } + }); + + RED.httpAdmin.get('/rpi-gpio/:id', RED.auth.needsPermission('rpi-gpio.read'), function(req,res) { + res.json(pitype); + }); + + RED.httpAdmin.get('/rpi-pins/:id', RED.auth.needsPermission('rpi-gpio.read'), function(req,res) { + res.json(pinsInUse); + }); +} diff --git a/node-red/arm/patch/36-rpi-gpio.js.patch b/node-red/arm/patch/36-rpi-gpio.js.patch deleted file mode 100644 index 5a6518c..0000000 --- a/node-red/arm/patch/36-rpi-gpio.js.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/36-rpi-gpio.js -+++ b/36-rpi-gpio.js -@@ -224,7 +224,7 @@ - this.butt = n.butt || 7; - var node = this; - -- node.child = spawn(gpioCommand+".py", ["mouse,node.butt]); -+ node.child = spawn(gpioCommand, ["mouse",node.butt]); - node.status({fill:"green",shape:"dot",text:"common.status.ok"}); - - node.child.stdout.on('data', function (data) { -@@ -270,7 +270,7 @@ - RED.nodes.createNode(this,n); - var node = this; - -- node.child = spawn(gpioCommand+".py", ["kbd","0"]); -+ node.child = spawn(gpioCommand, ["kbd","0"]); - node.status({fill:"green",shape:"dot",text:"common.status.ok"}); - - node.child.stdout.on('data', function (data) { diff --git a/node-red/arm/patch/README.md b/node-red/arm/patch/README.md index 410c657..2bc6d0f 100644 --- a/node-red/arm/patch/README.md +++ b/node-red/arm/patch/README.md @@ -1,4 +1,4 @@ Node-RED PATCH ============== -python2 cannot read usb keyboard input device +python2 (on alpine linux) cannot read usb keyboard input device diff --git a/node-red/arm/patch/nrgpio b/node-red/arm/patch/nrgpio index 94c9671..3488030 100755 --- a/node-red/arm/patch/nrgpio +++ b/node-red/arm/patch/nrgpio @@ -1,9 +1,17 @@ -#!/bin/bash +#!/bin/sh +# +# Copyright JS Foundation and other contributors, http://js.foundation +# +# 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. +# BASEDIR=$(dirname $0) -if [[ $1 == mouse || $1 == kbd ]] -then - exec python3 -u $BASEDIR/nrinput.py $@ -else - sudo python -u $BASEDIR/nrgpio.py $@ -fi +python -u $BASEDIR/nrgpio.py $@ diff --git a/node-red/arm/patch/nrgpio.py b/node-red/arm/patch/nrgpio.py new file mode 100755 index 0000000..38a7959 --- /dev/null +++ b/node-red/arm/patch/nrgpio.py @@ -0,0 +1,235 @@ +#!/usr/bin/python +# +# Copyright JS Foundation and other contributors, http://js.foundation +# +# 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. +# + +# Import library functions we need +import six +import RPi.GPIO as GPIO +import struct +import sys +import os +import subprocess +from time import sleep + +bounce = 25; + +if len(sys.argv) > 2: + cmd = sys.argv[1].lower() + pin = int(sys.argv[2]) + GPIO.setmode(GPIO.BOARD) + GPIO.setwarnings(False) + + if cmd == "pwm": + #print "Initialised pin "+str(pin)+" to PWM" + try: + freq = int(sys.argv[3]) + except: + freq = 100 + + GPIO.setup(pin,GPIO.OUT) + p = GPIO.PWM(pin, freq) + p.start(0) + + while True: + try: + data = six.input() + if 'close' in data: + sys.exit(0) + p.ChangeDutyCycle(float(data)) + except (EOFError, SystemExit): # hopefully always caused by us sigint'ing the program + GPIO.cleanup(pin) + sys.exit(0) + except Exception as ex: + six.print_("bad data: "+data) + + elif cmd == "buzz": + #print "Initialised pin "+str(pin)+" to Buzz" + GPIO.setup(pin,GPIO.OUT) + p = GPIO.PWM(pin, 100) + p.stop() + + while True: + try: + data = six.input() + if 'close' in data: + sys.exit(0) + elif float(data) == 0: + p.stop() + else: + p.start(50) + p.ChangeFrequency(float(data)) + except (EOFError, SystemExit): # hopefully always caused by us sigint'ing the program + GPIO.cleanup(pin) + sys.exit(0) + except Exception as ex: + six.print_("bad data: "+data) + + elif cmd == "out": + #print "Initialised pin "+str(pin)+" to OUT" + GPIO.setup(pin,GPIO.OUT) + if len(sys.argv) == 4: + GPIO.output(pin,int(sys.argv[3])) + + while True: + try: + data = six.input() + if 'close' in data: + sys.exit(0) + data = int(data) + except (EOFError, SystemExit): # hopefully always caused by us sigint'ing the program + GPIO.cleanup(pin) + sys.exit(0) + except: + if len(sys.argv) == 4: + data = int(sys.argv[3]) + else: + data = 0 + if data != 0: + data = 1 + GPIO.output(pin,data) + + elif cmd == "in": + #print "Initialised pin "+str(pin)+" to IN" + bounce = float(sys.argv[4]) + def handle_callback(chan): + sleep(bounce/1000.0) + six.print_(GPIO.input(chan)) + + if sys.argv[3].lower() == "up": + GPIO.setup(pin,GPIO.IN,GPIO.PUD_UP) + elif sys.argv[3].lower() == "down": + GPIO.setup(pin,GPIO.IN,GPIO.PUD_DOWN) + else: + GPIO.setup(pin,GPIO.IN) + + six.print_(GPIO.input(pin)) + GPIO.add_event_detect(pin, GPIO.BOTH, callback=handle_callback, bouncetime=int(bounce)) + + while True: + try: + data = six.input() + if 'close' in data: + sys.exit(0) + except (EOFError, SystemExit): # hopefully always caused by us sigint'ing the program + GPIO.cleanup(pin) + sys.exit(0) + + elif cmd == "byte": + #print "Initialised BYTE mode - "+str(pin)+ + list = [7,11,13,12,15,16,18,22] + GPIO.setup(list,GPIO.OUT) + + while True: + try: + data = six.input() + if 'close' in data: + sys.exit(0) + data = int(data) + except (EOFError, SystemExit): # hopefully always caused by us sigint'ing the program + GPIO.cleanup() + sys.exit(0) + except: + data = 0 + for bit in range(8): + if pin == 1: + mask = 1 << (7 - bit) + else: + mask = 1 << bit + GPIO.output(list[bit], data & mask) + + elif cmd == "borg": + #print "Initialised BORG mode - "+str(pin)+ + GPIO.setup(11,GPIO.OUT) + GPIO.setup(13,GPIO.OUT) + GPIO.setup(15,GPIO.OUT) + r = GPIO.PWM(11, 100) + g = GPIO.PWM(13, 100) + b = GPIO.PWM(15, 100) + r.start(0) + g.start(0) + b.start(0) + + while True: + try: + data = six.input() + if 'close' in data: + sys.exit(0) + c = data.split(",") + r.ChangeDutyCycle(float(c[0])) + g.ChangeDutyCycle(float(c[1])) + b.ChangeDutyCycle(float(c[2])) + except (EOFError, SystemExit): # hopefully always caused by us sigint'ing the program + GPIO.cleanup() + sys.exit(0) + except: + data = 0 + + elif cmd == "mouse": # catch mice button events + file = open( "/dev/input/mice", "rb" ) + oldbutt = 0 + + def getMouseEvent(): + global oldbutt + global pin + buf = file.read(3) + pin = pin & 0x07 + button = six.byte2int(buf) & pin # mask out just the required button(s) + if button != oldbutt: # only send if changed + oldbutt = button + six.print_(button) + + while True: + try: + getMouseEvent() + except: + file.close() + sys.exit(0) + + elif cmd == "kbd": # catch keyboard button events + try: + while not os.path.isdir("/dev/input/by-path"): + time.sleep(10) + infile = subprocess.check_output("ls /dev/input/by-path/ | grep -m 1 'kbd'", shell=True).strip() + infile_path = "/dev/input/by-path/" + infile.decode('utf-8') + EVENT_SIZE = struct.calcsize('llHHI') + file = open(infile_path, "rb") + event = file.read(EVENT_SIZE) + while event: + (tv_sec, tv_usec, type, code, value) = struct.unpack('llHHI', event) + #if type != 0 or code != 0 or value != 0: + if type == 1: + # type,code,value + six.print_("%u,%u" % (code, value)) + event = file.read(EVENT_SIZE) + six.print_("0,0") + file.close() + sys.exit(0) + except: + file.close() + sys.exit(0) + +elif len(sys.argv) > 1: + cmd = sys.argv[1].lower() + if cmd == "rev": + six.print_(GPIO.RPI_REVISION) + elif cmd == "ver": + six.print_(GPIO.VERSION) + elif cmd == "info": + six.print_(GPIO.RPI_INFO) + else: + six.print_("Bad parameters - in|out|pwm|buzz|byte|borg|mouse|kbd|ver|info {pin} {value|up|down}") + six.print_(" only ver (gpio version) and info (board information) accept no pin parameter.") + +else: + six.print_("Bad parameters - in|out|pwm|buzz|byte|borg|mouse|kbd|ver|info {pin} {value|up|down}") diff --git a/node-red/arm/patch/nrinput.py b/node-red/arm/patch/nrinput.py deleted file mode 100755 index 1e4c3bb..0000000 --- a/node-red/arm/patch/nrinput.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python3 - -import os -import struct -import subprocess -import sys -import time - -if sys.version_info < (3,0): - print("Sorry - currently only configured to work with python 3.x") - sys.exit(1) - -if len(sys.argv) > 2: - cmd = sys.argv[1].lower() - pin = int(sys.argv[2]) - - if cmd == "mouse": # catch mice button events - file = open( "/dev/input/mice", "rb" ) - oldbutt = 0 - - def getMouseEvent(): - global oldbutt - global pin - buf = file.read(3) - pin = pin & 0x07 - button = ord( chr(buf[0]) ) & pin # mask out just the required button(s) - if button != oldbutt: # only send if changed - oldbutt = button - print(button) - - while True: - try: - getMouseEvent() - except: - file.close() - sys.exit(0) - - elif cmd == "kbd": # catch keyboard button events - try: - while not os.path.isdir("/dev/input/by-path"): - time.sleep(10) - infile = subprocess.check_output("ls /dev/input/by-path/ | grep -m 1 'kbd'", shell=True).strip() - infile_path = "/dev/input/by-path/" + infile.decode() - EVENT_SIZE = struct.calcsize('llHHI') - file = open(infile_path, "rb") - event = file.read(EVENT_SIZE) - - while event: - (tv_sec, tv_usec, type, code, value) = struct.unpack('llHHI', event) - #if type != 0 or code != 0 or value != 0: - if type == 1: - # type,code,value - print("%u,%u" % (code, value)) - event = file.read(EVENT_SIZE) - print("0,0") - file.close() - sys.exit(0) - except: - file.close() - sys.exit(0) -else: - print("Bad parameters - mouse|kbd {pin}")