var PinoConnection = function(path) { EventEmitter.call(this); var portOpen = false; var self = this; debug("Creating Pinocc.io object with the following info:"); debug(path); if (path.token === undefined) return; // Initialize the API with the API token var myPino = pinoccio(path.token); var sync = myPino.sync({stale:1}); var forwardData = function(data) { debug(data); self.emit('data',data); }; /** * The main role of this is to respawn the stream which * sometimes dies on us. * @param {String} error the error message */ var handleError = function(error) { debug('Error on stream'); debug(error); // Close the stream, and reopen it sync.end(); sync.destroy(); sync = myPino.sync({stale:1}) self.open(); } this.open = function() { debug("Listening to data stream"); sync.on('data', forwardData); sync.on('error', handleError); portOpen = true; debug('Port open'); this.emit('status', {portopen: portOpen}); }; this.write = function(data) { } this.close = function() { sync.removeListener('data', forwardData); sync.removeListener('error', handleError); portOpen = false; self.emit('status', {portopen: portOpen}); } return this; }
function PinoccioIO(opts){ if (!(this instanceof PinoccioIO)) { return new PinoccioIO(opts); } var z = this; Emitter.call(z); z._api = pinoccio(opts); z.troop = opts.troop; z.scout = opts.scout; z._api.rest({url:'v1/'+opts.troop+'/'+opts.scout},function(err,data){ if(err) { console.error(err); return z.emit('error',err); } if(!data) { console.error(err); return z.emit('error',new Error('unknown troop or scout')); } z.sync = z._api.sync({stale:1}); // make sure we get a fresh pin report. edge case where a report may be missing. z.command("pin.digital.report;pin.analog.report;",function(err,res){ if(err) console.error('error sending pin report command ',err); }) z.data = {};// sync data object. // board is ready after i get available && digital && analog events. // TODO FIND GREAT Way to message when a scout may be off / unavailable var isReady = function(){ return !z.isReady && (z.data.available && z.data.available.available) && z.data.digital && z.data.analog; }; z.emit('connect'); var delay; z.sync.on('data',function(data){ // i care about 3 api events // // available: {"scout":1,"available":1,"reply":"11\n","_t":1399594464252,"type":"available"} // digital: {"type":"digital","mode":[-1,-1,-1,-1,2,-1,-1],"state":[-1,-1,-1,-1,0,-1,-1],"_t":1396672122237} // analog: {"type":"analog","mode":[-1,-1,-1,-1,-1,-1,-1,-1],"state":[-1,-1,-1,-1,-1,-1,-1,-1],"_t":1396651237836} // data = data.data; if(data.account && data.troop == z.troop && data.scout == z.scout && data.type) { clearTimeout(delay); var key = data.type z.data[key] = data.value||data; if(key == 'digital' || key == 'analog') { var offset = key == 'analog'?9:2; var report = data.value; var skew = key == 'digital'?2:0; //console.log('report',report); report.mode.forEach(function(mode,i){ // mode may be undefined if the pin becomes disabled because this is not a state understood by the j5 interface mode = internalModeMap[mode];// var value = report.state[i]; var pin = z.pins[offset+i]; var change = false; if(mode != pin.mode) { change = true; pin.mode = mode; } if(value != pin.value) { change = true; pin.value = value; } if(z.isReady && change) { z.emit(key+'-pin-'+(i+offset),value); } }); } if(isReady()) { // completely ready... z.isReady = true; z.emit('ready'); } } }).on('error',function(err){ z.emit('error',err); }); }); z.pins = pins.map(function(pin,i) { return { id:pin.id, supportedModes: pin.modes, mode: -1, // disabled. waiting for push from api. value: 0, report:1,// all pins report analogChannel:i>=9?i-9:127 }; }); this.analogPins = this.pins.slice(9).map(function(pin, i) { return i+9; }); }
var express = require('express'), pinoccio = require('pinoccio'), twitter = require('twit'); var app = express(); // Pinoccio API var pinoccioAPI = pinoccio("asdf"); // Twitter API var twitterAPI = new twit({ consumer_key: 'asdf', consumer_secret: 'asdf', access_token: 'asdf', access_token_secret: 'adsf' }); // Open the tweet stream, and act on incoming tweets var tweetStream = twitter.stream('user'); tweetStream.on('tweet', function(tweet){ // change links back into their original text _.each(tweet.entities.urls, function(url){ tweet.text = tweet.text.replace(url.url, url.display_url); }); // If this was a command tweet to our Scout var match = /^@gopinoccio\b.*>(.+)/gi.exec(tweet.text); if (match) {