UNPKG

susi-forge

Version:
326 lines (293 loc) 11 kB
var GatewayController = { nodeId: null, init: function(){ var self = this; this.nodeId = this.generateGUID(); log("Cluster: nodeId: "+this.nodeId); susi.publish({ topic: "cluster::registerProcessor", payload: { node: 'cloud', topic: '*@'+self.nodeId } },function(){ // If such event occurs, strip the address information and publish it local. susi.registerProcessor("*@"+self.nodeId, function(event){ log("got event from cloud: "+event.topic); susi.publish({ topic: event.topic.split('@')[0], payload: event.payload },function(res){ // when local publish is finished, ack it back. log("local event processing finished, ack it back..."); event.payload = res.payload; event.headers = res.headers; susi.ack(event); }); }); }); susi.publish({ topic: "cluster::forward", payload: { node: 'cloud', topic: 'demo::temperature::update@src:'+self.nodeId } },function(){ susi.registerConsumer("demo::temperature::update", function(event){ log("forward temp update..."); susi.publish({ topic: 'demo::temperature::update@src:'+self.nodeId, payload: event.payload },function(res){ log("forwarded temperature::update to cloud"); }); }); }); susi.registerConsumer("cluster::node::open",function(evt){ if(evt.payload === "cloud"){ // tell the cloud who we are susi.publish({ topic: "registerNewNode@cloud", payload: { nodeId: self.nodeId } },function(evt){ if(evt.payload && evt.payload.success){ log("registerNewNode@cloud: success!"); }else{ log("registerNewNode@cloud: fail..."); log(JSON.stringify(evt)); } }); } }); // Tell local cluster-code to listen for events "*@thid.nodeId" }, generateGUID: function(){ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8); return v.toString(16); }); } }; var LedController = { init: function(){ susi.registerProcessor("demo::led::on", this.setLedOn.bind(this)); susi.registerProcessor("demo::led::off", this.setLedOff.bind(this)); susi.registerProcessor("demo::led::rgb", this.setRGB.bind(this)); susi.registerProcessor("demo::led::red", this.setTrafficRed.bind(this)); susi.registerProcessor("demo::led::yellow", this.setTrafficYellow.bind(this)); susi.registerProcessor("demo::led::green", this.setTrafficGreen.bind(this)); log("LED-Controller init ready."); }, setLedOn: function(event){ MainController.syscall("led-on",function(res){ event.payload = {success: (res.payload.return === 0)}; susi.ack(event); }); }, setLedOff: function(event){ MainController.syscall("led-off",function(res){ event.payload = {success: (res.payload.return === 0)}; susi.ack(event); }); }, setTrafficRed: function(event){ MainController.syscall("led-red",function(res){ event.payload = {success: (res.payload.return === 0)}; susi.ack(event); }); }, setTrafficYellow: function(event){ MainController.syscall("led-yellow",function(res){ event.payload = {success: (res.payload.return === 0)}; susi.ack(event); }); }, setTrafficGreen: function(event){ MainController.syscall("led-green",function(res){ event.payload = {success: (res.payload.return === 0)}; susi.ack(event); }); }, setRGB: function(event){ if( event.payload === undefined || event.payload.red === undefined || event.payload.green === undefined || event.payload.blue === undefined ){ throw "you must specify payload fields 'red', 'green' and 'blue'."; } if( !typeof event.payload.red === 'number' || !typeof event.payload.green === 'number' || !typeof event.payload.blue === 'number' ){ throw "you must specify payload fields 'red', 'green' and 'blue' as integers."; } if( !(event.payload.red >= 0 && event.payload.red <= 255) || !(event.payload.green >= 0 && event.payload.green <= 255) || !(event.payload.blue >= 0 && event.payload.blue <= 255)){ throw "you must specify payload fields 'red', 'green' and 'blue' as integers between 0 and 255."; } var redHex = event.payload.red.toString(16), greenHex = event.payload.green.toString(16), blueHex = event.payload.blue.toString(16); if(redHex.length == 1){ redHex = '0'+redHex; } if(greenHex.length == 1){ greenHex = '0'+greenHex; } if(blueHex.length == 1){ blueHex = '0'+blueHex; } susi.publish({ topic: 'syscall::exec', payload: { cmd: 'set-rgb', args: { RED: redHex, GREEN: greenHex, BLUE: blueHex } } },function(res){ event.payload = {success: (res.payload.return === 0)}; susi.ack(event); }); } }; var MainController = { init: function(){ var self = this; susi.registerConsumer("global::start",function(){ GatewayController.init(); self.syscall('stop-microcontrollers',function(evt){ self.syscall('start-led-microcontroller',function(evt){ LedController.init(); MorseController.init(); }); self.syscall('start-temp-microcontroller',function(evt){ TemperatureController.init(); TempReactor.init(); }); }); }); }, syscall: function(command,cb){ susi.publish({ topic: 'syscall::exec', payload: { cmd: command } },function(res){ if(cb !== undefined){ cb(res); } }); } }; MainController.init();var MorseController = { code : { "a": "._", "b": "_...", "c": "_._.", "d": "_..", "e": ".", "f": ".._.", "g": "__.", "h": "....", "i": "..", "j": ".___", "k": "_._", "l": "._..", "m": "__", "n": "_.", "o": "___", "p": ".__.", "q": "__._", "r": "._.", "s": "...", "t": "_", "u": ".._", "v": "..._", "w": ".__", "x": "_.._", "y": "_.__", "z": "__..", " ": " ", "1": ".____", "2": "..___", "3": "...__", "4": "...._", "5": ".....", "6": "_....", "7": "__...", "8": "___..", "9": "____.", "0": "_____", ".": "._._._", ",": "__..__", "?": "..__..", "'": ".____.", "/": "_.._.", "(": "_.__.", ")": "_.__._", "&": "._...", ":": "___...", ";": "_._._.", "=": "_..._", "+": "._._.", "-": "_...._", "_": "..__._", "\"": "._.._.", "$": "..._.._", "!": "_._.__", "@": ".__._." }, init: function(){ susi.registerProcessor("demo::morse",this.morse.bind(this)); log("Morse-Controller init ready."); }, morse: function(event){ var msg = event.payload; if(msg === undefined){ msg = "?"; } var command = this.strToCommand(msg); log("exec led pattern: "+command); susi.publish({ topic: 'syscall::exec', payload: { cmd: 'exec-pattern', args: { PATTERN: command } } }); }, strToCommand: function(str){ var pattern = ""; for (var i = 0 - 1; i < str.length; i++) { var charPattern = this.code[str[i]] || this.code["?"]; for(var idx=0;idx<charPattern.length;idx++){ if(charPattern[idx] === '.'){ pattern += "hsslss"; }else if(charPattern[idx] === '_'){ pattern += "hsssslss"; }else if(charPattern[idx] === ' '){ pattern += "ssss"; } } } return pattern; } }; var TemperatureController = { lastTemp: 0.0, notifyThreshold: 0.1, init: function(){ var self = this; susi.registerProcessor("demo::temperature::get", self.getTemp.bind(self)); susi.registerConsumer("heartbeat::five",function(evt){ susi.publish({ topic: "demo::temperature::get" },function(res){ log(JSON.stringify(res)); var currentTemp = res.payload.temperature; if(currentTemp !== null && Math.abs(currentTemp-self.lastTemp) > self.notifyThreshold){ self.lastTemp = currentTemp; susi.publish({ topic: "demo::temperature::update", payload: { temperature: currentTemp } }); } }); }); log("Temperature-Controller init ready."); }, getTemp: function(event){ MainController.syscall('get-temperature',function(res){ log(JSON.stringify(res)); var stdout = res.payload.stdout; var arr = stdout.split("\r\n"); var tempStr = arr[1]; event.payload = {temperature: parseFloat(tempStr)}; susi.ack(event); }); } }; var TempReactor = { lastTemp: 0, init: function(){ var self = this; susi.registerConsumer("demo::temperature::update",function(event){ var current = event.payload.temperature; if(current > self.lastTemp){ susi.publish({topic: "demo::led::red"}); }else{ susi.publish({topic: "demo::led::green"}); } self.lastTemp = current; }); } };