Created
April 5, 2014 15:16
-
-
Save ozzieg/9993285 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Code snippet for integrating with the Ninjablocks cloud | |
//Requires signing up with the Ninjablocks cloud here: https://a.ninja.is/born | |
// | |
//Assumptions: | |
// - Uses the User Access Token method | |
// - Create a Block ID that is unique and alphanumeric | |
// - | |
// | |
// NINJABLOCKS API | |
// | |
const NINJA_SERVER_URL = "https://api.ninja.is/rest/v0"; | |
const NINJA_AUTH = "user_access_token=<YOUR_USER_ACCESS_TOKEN>"; | |
const NINJA_BLOCK_ID = "YOURUNIQUEID"; | |
ninja_blockToken <- ""; | |
// helper | |
function ninja_blockUrl() { | |
return NINJA_SERVER_URL + "/block/" + NINJA_BLOCK_ID; | |
} | |
// helper | |
function ninja_auth(url) { | |
return url + "?" + NINJA_AUTH; | |
} | |
// ninja_activateBlock() | |
// | |
// Call to /activate REST API using the user_access_token | |
// This will return a token which needs to be stored for subsequent calls | |
// This token should be stored away permanently in a database, but I haven't | |
// done that here to keep it simple | |
// | |
// Also, this should probably be called only when the device connects | |
// | |
function ninja_activateBlock() { | |
//post to activate a block | |
local url = ninja_auth(ninja_blockUrl() + "/activate"); | |
local response = http.get(url).sendsync(); | |
server.log("response received: " + response.body); | |
local data = http.jsondecode(response.body); | |
ninja_blockToken = data.token; | |
server.log("Activated block. Received token: " + ninja_blockToken); | |
} | |
// ninja_removeBlock() | |
// | |
// Called when the device disconnects and relinquishes the token | |
// for next time. Call activate method to get a new token. | |
// | |
// This doesn't affect the ninjablock cloud dashboard. All devices | |
// still remain. | |
// | |
function ninja_removeBlock() { | |
local url = ninja_auth(ninja_blockUrl()); | |
local response = http.httpdelete(url).sendsync(); | |
server.log("unpaired block: " + response.body); | |
} | |
// ninja_emitData() | |
// | |
// Send device data to ninjablocks. This will also create the devices | |
// if they don't exist. It is a good idea to call this regularly to keep | |
// the dashboard active. The gadgets on the dashboard will grey out after some | |
// inactivity timeout. | |
// | |
// N.B.: I could have utilized the "heartbeat" method as well, but it says that it is | |
// depracated. | |
// | |
function ninja_emitData() { | |
local data = {}; | |
//emit temp state | |
data = { "G":"TEMP", "V":0, "D":1, "DA":("Temp" in lastFeedJSON)?lastFeedJSON.Temp:0 }; | |
ninja_emitSensorData(data); | |
//emit light state | |
data = { "G":"LIGHTS", "V":0, "D":5, "DA":("LightsState" in lastFeedJSON)?(lastFeedJSON.LightsState == "ON"?1:0):0 }; | |
ninja_emitSensorData(data); | |
//emit door state | |
data = { "G":"DOOR", "V":0, "D":244, "DA":("DoorState" in lastFeedJSON)?lastFeedJSON.DoorState:"UNKNOWN" }; | |
ninja_emitSensorData(data); | |
//create a door switch | |
data = { "G":"DOORSWITCH", "V":0, "D":244, "DA":("DoorState" in lastFeedJSON)?lastFeedJSON.DoorState:"UNKNOWN" }; | |
ninja_emitSensorData(data); | |
} | |
// helper | |
// ninja_emitSensorData() | |
// | |
// Does the actual HTTP POST call | |
// | |
function ninja_emitSensorData(data) { | |
local url = ninja_auth(ninja_blockUrl() + "/data"); | |
local response = http.post( | |
url, | |
{"Content-type":"application/json", "X-Ninja-Token":ninja_blockToken}, | |
http.jsonencode(data) | |
).sendsync(); | |
server.log("sent data: " + http.jsonencode(data)); | |
return response; | |
} | |
// ninja_listen() | |
// | |
// Long GET call to ninjablocks cloud to listen to commands | |
// that you are sending from the dashboard. These commands capture the | |
// "actuate" commands. For example, if you have a state device, you can | |
// capture the clicks on the state to flip a relay. | |
// | |
// This method is called async since it is really a callback operation. | |
// The ninjablocks cloud will timeout after 30 seconds or when a command is sent. | |
// So, this method will need to be called again from the callback method to keep | |
// it going. | |
// | |
function ninja_listen() { | |
local url = ninja_auth(ninja_blockUrl() + "/commands"); | |
http.get( | |
url, | |
{"Content-type":"application/json", "X-Ninja-Token":ninja_blockToken}).sendasync(ninja_parseCommands); | |
server.log("registered to listen to ninja"); | |
} | |
// ninja_parseCommands() | |
// | |
// Callback method from the async Long GET call initiated from the listen() method. | |
// It loops through all of the commands queued up and detects the devices that can | |
// be actuated. For example, you can capture the activation of different states on a | |
// state device (id = 244), take some action, and then also send back this state so that | |
// it reflects on the dashboard. | |
// | |
// It re-listens at the end of the method to keep the method alive. | |
// | |
function ninja_parseCommands(response) { | |
server.log("receiving commands: " + response.body); | |
if( response.body != "" ) { | |
local data = http.jsondecode(response.body); | |
//{"DEVICE":[{"G":"LIGHTS","V":0,"D":5,"DA":"1"}]} | |
foreach( d in data.DEVICE ) { | |
if( d.G == "DOORSWITCH" ) { | |
if( d.DA != "" ) { | |
//toggle door | |
if( d.DA == "OPEN" || d.DA == "CLOSED" ) { | |
ninja_emitSensorData(d); | |
device.send("toggle_door", 1); | |
} | |
} | |
} | |
} | |
} | |
ninja_listen(); //re-listen | |
} | |
// device.on("data") | |
// | |
// If "data" is the event name where the device sends its data to be displayed on the | |
// dashboard, then add the method to call out | |
// | |
// Assumes that the device is sending data in JSON format. This makes it really easy | |
// to use it later in the code base. | |
// | |
lastFeedJSON <- {}; | |
device.on("data", function(data) { | |
lastFeedJSON <- data; | |
server.log(data); | |
ninja_emitData(); | |
}); | |
// device.onconnect() | |
// | |
// Activate and De-activate the ninja block whenever the device connects | |
// You can also deactivate when the device disconnects | |
// If you want to utilize a web service database, you can store away the token | |
// and re-use it instead of deactivating and re-activating | |
// | |
// ninja_emitData - emits all initial values (this also creates the devices) | |
// ninja_listen - makes the long get asynch and parses the commands as it comes in | |
// | |
device.onconnect(function() { | |
server.log("device connected to agent"); | |
if( ninja_blockToken == "" ) { | |
ninja_removeBlock(); | |
ninja_activateBlock(); | |
} | |
ninja_emitData(); | |
ninja_listen(); | |
}); | |
// device.ondisconnect() | |
// | |
// Remove block from ninjablocks | |
// | |
device.ondisconnect(function() { | |
server.log("device disconnected from agent"); | |
ninja_removeBlock(); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment