Skip to content

Instantly share code, notes, and snippets.

@plopp
Last active October 9, 2017 16:20
Show Gist options
  • Save plopp/85b3cceabd35dbe2554a65c6b1a9f4e0 to your computer and use it in GitHub Desktop.
Save plopp/85b3cceabd35dbe2554a65c6b1a9f4e0 to your computer and use it in GitHub Desktop.
Example client for the Yanzi Cirrus API
const WebSocket = require('ws');
const http = require('http');
function assertDefinedEnv(varname) {
if (!(varname in process.env))
throw "Error: Missing required env var " + varname;
}
assertDefinedEnv("SHREK_URL");
assertDefinedEnv("PLUG_ENERGY_DID");
assertDefinedEnv("PLUG_GPIO_DID");
assertDefinedEnv("SENSOR_LID");
assertDefinedEnv("YANZI_USER");
assertDefinedEnv("YANZI_PASS");
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
const PORT = process.env.PORT || 5000;
let cirrus_ws = new WebSocket(process.env.SHREK_URL, {
origin: 'https://devshrek.yanzi.se'
});
//For this simple example, lets just store the last value in a global var.
var global_last_known_usage = -1;
/**
* Send an object over the cirrus connection. This will fail if the websocket
* is not open.
*/
function sendMessage(message) {
if (cirrus_ws.readyState != WebSocket.OPEN) {
console.error("Couldn't send cirrus message: Socket not open");
return;
}
try {
cirrus_ws.send(JSON.stringify(message, null, 1));
} catch (e) {
console.error("Couldn't send cirrus message. " + e);
}
}
function sendLoginRequest(username, password) {
var request = {
"messageType": "LoginRequest",
"username": username,
"password": password,
"timeSent": new Date().getTime()
}
sendMessage(request);
}
function subscribeToDataFromLocation(locationId) {
var request = {
"messageType": "SubscribeRequest",
"timeSent": new Date().getTime(),
"unitAddress": {
"resourceType": "UnitAddress",
"locationId": locationId
},
"subscriptionType": {
"resourceType": "SubscriptionType",
"name": "data"
}
}
sendMessage(request);
}
/**
* Really simple method to extract a single instantPower from a SubscribeData
* response for the specified lid/did. Will return undefined if not found.
* */
function extractPlugUsageFromSubscribeData(json, lid, did) {
for (var i in json.list) {
var sample_list = json.list[i];
//Is this our sensor?
if (sample_list.dataSourceAddress.did == did) {
console.log("Got update from plug")
console.log(JSON.stringify(sample_list.list[0]))
if (sample_list.list.length == 0)
throw "Error: empty sample list";
return sample_list.list[0].instantPower;
}
}
return undefined;
}
function processResponse(json) {
if (json.messageType == "LoginResponse") {
console.log("Got login status: " + json.responseCode.name);
// lets assume we were logged in
subscribeToDataFromLocation(process.env.SENSOR_LID);
} else if (json.messageType == "SubscribeData") {
var res = extractPlugUsageFromSubscribeData(json, process.env.SENSOR_LID, process.env.PLUG_ENERGY_DID);
if (res !== undefined) {
global_last_known_usage = res;
}
}
}
/**
* Send a message to do a binary turn-off of the specified unit.
*/
function sendTurnOff(lid, did) {
var request = {
"messageType": "ControlRequest",
"timeSent": new Date().getTime(),
"unitAddress": {
"resourceType": "UnitAddress",
"did": did,
"locationId": lid
},
"did": did,
"controlValue": {
"resourceType": "ControlValueBinary",
"value": false
}
};
sendMessage(request);
}
function sendTurnOn(lid, did) {
var request = {
"messageType": "ControlRequest",
"timeSent": new Date().getTime(),
"unitAddress": {
"resourceType": "UnitAddress",
"did": did,
"locationId": lid
},
"did": did,
"controlValue": {
"resourceType": "ControlValueBinary",
"value": true
}
};
sendMessage(request);
}
/**
* Event handlers for websocket:
*/
cirrus_ws.on('connection', function connection(ws, req) {
console.log(JSON.stringify(req));
const ip = req.connection.remoteAddress;
});
cirrus_ws.on('open', function open() {
console.log("Connection opened");
// Lets log in immidiately
sendLoginRequest(process.env.YANZI_USER, process.env.YANZI_PASS);
});
cirrus_ws.on('message', function (data, flags) {
processResponse(JSON.parse(data));
});
function handleRequest(request, response) {
response.write("<html>");
if (request.url == "/off") {
sendTurnOff(process.env.SENSOR_LID, process.env.PLUG_GPIO_DID);
response.write("Sent turn-off command");
}
if (request.url == "/on") {
sendTurnOn(process.env.SENSOR_LID, process.env.PLUG_GPIO_DID);
response.write("Sent turn-on command");
}
if (global_last_known_usage == -1) {
response.write("Waiting for information about the plug");
} else {
response.write('The plug is using '
+ (global_last_known_usage > 2 ? global_last_known_usage + " W" : "0 W"));
}
response.write("<br><a href=/on>Send turn-on command</a>")
response.end("<br><a href=/off>Send turn-off command</a></html>");
}
var server = http.createServer(handleRequest);
//Lets start our server
server.listen(PORT, function () {
console.log("Server listening on: http://localhost:%s", PORT);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment