/** * Copyright 2016 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 fs = require('fs'); var PNG = require('pngjs').PNG; var spawn = require('child_process').spawn; var hatCommand = __dirname+'/unihat'; if (!fs.existsSync("/dev/ttyAMA0")) { // unlikely if not on a Pi //RED.log.info(RED._("rpi-gpio.errors.ignorenode")); throw "Info : "+RED._("rpi-gpio.errors.ignorenode"); } if (!fs.existsSync('/usr/local/lib/python2.7/dist-packages/unicornhat.py')) { RED.log.warn("Can't find Unicorn HAT python libraries"); throw "Warning : Can't find Unicorn HAT python libraries"; } if ( !(1 & parseInt ((fs.statSync(hatCommand).mode & parseInt ("777", 8)).toString (8)[0]) )) { RED.log.error(hatCommand + " command is not executable"); throw "Error : "+RED._("rpi-gpio.errors.mustbeexecutable"); } // the magic to make python print stuff immediately process.env.PYTHONUNBUFFERED = 1; function UnicornHatNode(n) { RED.nodes.createNode(this,n); this.png = n.png; this.bright = n.bright || 20; this.items = {}; var node = this; var pic = new Buffer(192); pic.fill(0); var ready = false; if (node.png) { if (node.png.split(",").length === 3) { var c = node.png.split(","); for (var i=0; i<192; i++) { pic[i] = c[0]; pic[i+1] = c[1]; pic[i+2] = c[2]; i += 2; } ready = true; } else { try { var file = fs.readFileSync(node.png); new PNG().parse( file, function(error, data) { if (error) { node.warn("error reading : "+node.png); ready = true; } else { var pix = data.data; var j=0; for (var i=0; i<192; i++) { pic[i] = pix[j]; pic[i+1] = pix[j+1]; pic[i+2] = pix[j+2]; i += 2; j += 4; } ready = true; } }); } catch(e) { node.warn("error loading : "+node.png); ready = true; } } } else { ready = true; } function inputlistener(msg) { var s = msg.payload.toUpperCase().split(","); var doDraw = true; if (s.length === 1) { if (s[0] == "CLS") { //console.log("CLEAR") pic.fill(0); node.items = {}; } if (s[0] == "DEL") { //console.log("DELETE") node.items = {}; } } else if (s.length === 2) { if (s[0] === "BRIGHTNESS") { //console.log("BRIGHTNESS",s[1]) node.child.stdin.write("B"+s[1]+"\n"); } if (s[0] === "ROTATE") { //console.log("ROTATE",s[1]) node.child.stdin.write("R"+s[1]+"\n"); } } else if (s.length === 3) { //console.log("BACKGROUND",s) for (var i=0; i<192; i++) { pic[i] = s[0]; pic[i+1] = s[1]; pic[i+2] = s[2]; i += 2; } } else if (s.length % 5 === 0) { // handles pixel updates if (msg.topic) { node.items[msg.topic] = msg.payload; } else { node.child.stdin.write('P'+msg.payload+'\n'); doDraw = false; for (var a=0; a