susi-forge
Version:
326 lines (293 loc) • 11 kB
JavaScript
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;
});
}
};