isy-js
Version:
Javascript wrapper for ISY interface including websockets for change notifications. Designed to be used in a node.js application. Unsupported and no longer under active development.
736 lines (683 loc) • 29.4 kB
JavaScript
var restler = require('restler');
var xmldoc = require('xmldoc');
var isyDevice = require('./isydevice');
var WebSocket = require("faye-websocket");
var elkDevice = require('./elkdevice.js');
var isyDeviceTypeList = require("./isydevicetypes.json");
var ISYOutletDevice = require('./isydevice').ISYOutletDevice;
var ISYLightDevice = require('./isydevice').ISYLightDevice;
var ISYLockDevice = require('./isydevice').ISYLockDevice;
var ISYDoorWindowDevice = require('./isydevice').ISYDoorWindowDevice;
var ISYFanDevice = require('./isydevice').ISYFanDevice;
var ISYMotionSensorDevice = require('./isydevice').ISYMotionSensorDevice;
var ISYScene = require('./isyscene').ISYScene;
var ISYBaseDevice = require('./isydevice').ISYBaseDevice;
var ISYVariable = require('./isyvariable').ISYVariable
function isyTypeToTypeName(isyType,address) {
for(var index = 0; index < isyDeviceTypeList.length; index++ ) {
if(isyDeviceTypeList[index].type == isyType) {
var addressElementValue = isyDeviceTypeList[index].address;
if( addressElementValue != "") {
var lastAddressNumber = address[address.length-1];
if(lastAddressNumber != addressElementValue) {
continue;
}
}
return isyDeviceTypeList[index];
}
}
return null;
}
var ISY = function(address, username, password, elkEnabled, changeCallback, useHttps, scenesInDeviceList, enableDebugLogging, variableCallback) {
this.address = address;
this.userName = username;
this.password = password;
this.deviceIndex = {};
this.deviceList = [];
this.variableList = [];
this.variableIndex = {};
this.variableCallback = variableCallback;
this.nodesLoaded = false;
this.protocol = (useHttps == true) ? 'https' : 'http';
this.elkEnabled = elkEnabled;
this.zoneMap = {};
this.sceneList = [];
this.sceneIndex = {};
this.debugLogEnabled = (enableDebugLogging == undefined) ? false : enableDebugLogging;
this.scenesInDeviceList = (scenesInDeviceList==undefined) ? false : scenesInDeviceList;
this.guardianTimer = null;
if(this.elkEnabled) {
this.elkAlarmPanel = new elkDevice.ELKAlarmPanelDevice(this,1);
}
this.changeCallback = changeCallback;
};
ISY.prototype.DEVICE_TYPE_LOCK = 'DoorLock';
ISY.prototype.DEVICE_TYPE_SECURE_LOCK = 'SecureLock';
ISY.prototype.DEVICE_TYPE_LIGHT = 'Light';
ISY.prototype.DEVICE_TYPE_DIMMABLE_LIGHT = 'DimmableLight';
ISY.prototype.DEVICE_TYPE_OUTLET = 'Outlet';
ISY.prototype.DEVICE_TYPE_FAN = 'Fan';
ISY.prototype.DEVICE_TYPE_UNKNOWN = 'Unknown';
ISY.prototype.DEVICE_TYPE_DOOR_WINDOW_SENSOR = "DoorWindowSensor";
ISY.prototype.DEVICE_TYPE_ALARM_DOOR_WINDOW_SENSOR = 'AlarmDoorWindowSensor'
ISY.prototype.DEVICE_TYPE_CO_SENSOR = 'COSensor';
ISY.prototype.DEVICE_TYPE_ALARM_PANEL = 'AlarmPanel';
ISY.prototype.DEVICE_TYPE_MOTION_SENSOR = 'MotionSensor';
ISY.prototype.DEVICE_TYPE_SCENE = 'Scene';
ISY.prototype.VARIABLE_TYPE_INTEGER = '1';
ISY.prototype.VARIABLE_TYPE_STATE = '2';
ISY.prototype.logger = function(msg) {
if(this.debugLogEnabled || (process.env.ISYJSDEBUG != undefined && process.env.ISYJSDEBUG != null)) {
var timeStamp = new Date();
console.log(timeStamp.getFullYear()+"-"+timeStamp.getMonth()+"-"+timeStamp.getDay()+"#"+timeStamp.getHours()+":"+timeStamp.getMinutes()+":"+timeStamp.getSeconds()+"- "+msg);
}
}
ISY.prototype.buildDeviceInfoRecord = function(isyType, deviceFamily, deviceType) {
return {
type: isyType,
address: "",
name: "Generic Device",
deviceType: deviceType,
connectionType: deviceFamily,
batteryOperated: false
};
}
ISY.prototype.getDeviceTypeBasedOnISYTable = function(deviceNode) {
var familyId = 1;
if(deviceNode.childNamed('family') != null) {
familyId = Number(deviceNode.childNamed('family').val);
}
var isyType = deviceNode.childNamed('type').val;
var addressData = deviceNode.childNamed('address').val
var addressElements = addressData.split(' ');
var typeElements = isyType.split('.');
var mainType = Number(typeElements[0]);
var subType = Number(typeElements[1]);
var subAddress = Number(addressElements[3]);
// ZWave nodes identify themselves with devtype node
if(deviceNode.childNamed('devtype') != null) {
if(deviceNode.childNamed('devtype').childNamed('cat') != null) {
subType = Number(deviceNode.childNamed('devtype').childNamed('cat').val);
}
}
// Insteon Device Family
if(familyId == 1) {
// Dimmable Devices
if(mainType == 1) {
// Special case fanlinc has a fan element
if(subType == 46 && subAddress == 2) {
return this.buildDeviceInfoRecord(isyType, "Insteon", this.DEVICE_TYPE_FAN);
} else {
return this.buildDeviceInfoRecord(isyType, "Insteon", this.DEVICE_TYPE_DIMMABLE_LIGHT);
}
} else if(mainType == 2) {
// Special case appliance Lincs into outlets
if(subType == 6 || subType == 9 || subType == 12 || subType == 23) {
return this.buildDeviceInfoRecord(isyType, "Insteon", this.DEVICE_TYPE_OUTLET);
// Outlet lincs
} else if(subType == 8 || subType == 33) {
return this.buildDeviceInfoRecord(isyType, "Insteon", this.DEVICE_TYPE_OUTLET);
// Dual outlets
} else if(subType == 57) {
return this.buildDeviceInfoRecord(isyType, "Insteon", this.DEVICE_TYPE_OUTLET);
} else {
return this.buildDeviceInfoRecord(isyType, "Insteon", this.DEVICE_TYPE_LIGHT);
}
// Sensors
} else if(mainType == 7) {
// I/O Lincs
if(subType == 0) {
if(subAddress == 1) {
return this.buildDeviceInfoRecord(isyType, "Insteon", this.DEVICE_TYPE_DOOR_WINDOW_SENSOR);
} else {
return this.buildDeviceInfoRecord(isyType, "Insteon", this.DEVICE_TYPE_OUTLET);
}
// Other sensors. Not yet supported
} else {
return null;
}
// Access controls/doors/locks
} else if(mainType == 15) {
// MorningLinc
if(subType == 6) {
if(subAddress == 1) {
return this.buildDeviceInfoRecord(isyType, "Insteon", this.DEVICE_TYPE_LOCK);
// Ignore subdevice which operates opposite for the locks
} else {
return null;
}
// Other devices, going to guess they are similar to MorningLinc
} else {
return null;
}
} else if(mainType == 16) {
// Motion sensors
if(subType == 1 || subType == 3) {
if(subAddress == 1) {
return this.buildDeviceInfoRecord(isyType, "Insteon", this.DEVICE_TYPE_MOTION_SENSOR);
// Ignore battery level sensor and daylight sensor
} else {
}
} else if(subType == 2 || subType == 9 || subType == 17) {
return this.buildDeviceInfoRecord(isyType, "Insteon", this.DEVICE_TYPE_DOOR_WINDOW_SENSOR);
// Smoke, leak sensors, don't yet know how to support
} else {
return null;
}
// No idea how to test or support
} else {
return null;
}
// Z-Wave Device Family
} else if(familyId == 4) {
// Appears to be all ZWave devices seen so far
if(mainType == 4) {
// Identified by user zwave on/off switch
if(subType == 16) {
return this.buildDeviceInfoRecord(isyType, "ZWave", this.DEVICE_TYPE_LIGHT);
// Identified by user door lock
} else if(subType == 111) {
return this.buildDeviceInfoRecord(isyType, "ZWave", this.DEVICE_TYPE_SECURE_LOCK);
// This is a guess based on the naming in the ISY SDK
} else if(subType == 109) {
return this.buildDeviceInfoRecord(isyType, "ZWave", this.DEVICE_TYPE_DIMMABLE_LIGHT);
// Otherwise we don't know how to handle
} else {
return null;
}
}
}
return null;
}
ISY.prototype.nodeChangedHandler = function(node) {
var that = this;
if(this.nodesLoaded) {
this.logger('Node: '+node.address+' changed');
this.changeCallback(that, node);
}
}
ISY.prototype.getElkAlarmPanel = function() {
return this.elkAlarmPanel;
}
ISY.prototype.loadNodes = function(result) {
var document = new xmldoc.XmlDocument(result);
this.loadDevices(document);
this.loadScenes(document);
}
ISY.prototype.loadScenes = function(document) {
var nodes = document.childrenNamed('group');
for(var index = 0; index < nodes.length; index++) {
var sceneAddress = nodes[index].childNamed('address').val;
var sceneName = nodes[index].childNamed('name').val;
var linkNodes = nodes[index].childNamed('members').childrenNamed('link');
var childDevices = [];
for(var linkIndex = 0; linkIndex < linkNodes.length; linkIndex++) {
var linkDevice = this.deviceIndex[linkNodes[linkIndex].val];
if(linkDevice != null && linkDevice != undefined) {
childDevices.push(linkDevice);
}
}
var newScene = new ISYScene(this, sceneName, sceneAddress, childDevices);
this.sceneList.push(newScene);
this.sceneIndex[newScene.address] = newScene;
if(this.scenesInDeviceList) {
this.deviceIndex[newScene.address] = newScene;
this.deviceList.push(newScene);
}
}
}
ISY.prototype.loadDevices = function(document) {
var nodes = document.childrenNamed('node');
for(var index = 0; index < nodes.length; index++) {
var deviceAddress = nodes[index].childNamed('address').val;
var isyDeviceType = nodes[index].childNamed('type').val;
var deviceName = nodes[index].childNamed('name').val;
var newDevice = null;
var deviceTypeInfo = isyTypeToTypeName(isyDeviceType, deviceAddress);
var enabled = nodes[index].childNamed('enabled').val;
if(enabled !== 'false') {
// Try fallback to new generic device identification when not specifically identified.
if(deviceTypeInfo == null) {
deviceTypeInfo = this.getDeviceTypeBasedOnISYTable(nodes[index]);
}
if(deviceTypeInfo != null) {
if (deviceTypeInfo.deviceType == this.DEVICE_TYPE_DIMMABLE_LIGHT ||
deviceTypeInfo.deviceType == this.DEVICE_TYPE_LIGHT) {
newDevice = new ISYLightDevice(
this,
deviceName,
deviceAddress,
deviceTypeInfo
)
} else if (deviceTypeInfo.deviceType == this.DEVICE_TYPE_DOOR_WINDOW_SENSOR) {
newDevice = new ISYDoorWindowDevice(
this,
deviceName,
deviceAddress,
deviceTypeInfo
);
} else if (deviceTypeInfo.deviceType == this.DEVICE_TYPE_MOTION_SENSOR) {
newDevice = new ISYMotionSensorDevice(
this,
deviceName,
deviceAddress,
deviceTypeInfo
);
} else if (deviceTypeInfo.deviceType == this.DEVICE_TYPE_FAN) {
newDevice = new ISYFanDevice(
this,
deviceName,
deviceAddress,
deviceTypeInfo
);
} else if (deviceTypeInfo.deviceType == this.DEVICE_TYPE_LOCK ||
deviceTypeInfo.deviceType == this.DEVICE_TYPE_SECURE_LOCK) {
newDevice = new ISYLockDevice(
this,
deviceName,
deviceAddress,
deviceTypeInfo
);
} else if (deviceTypeInfo.deviceType == this.DEVICE_TYPE_OUTLET) {
newDevice = new ISYOutletDevice(
this,
deviceName,
deviceAddress,
deviceTypeInfo
);
}
// Support the device with a base device object
} else {
this.logger('Device: '+deviceName+' type: '+isyDeviceType+' is not specifically supported, returning generic device object. ');
newDevice = new ISYBaseDevice(
this,
deviceName,
deviceAddress,
isyDeviceType,
this.DEVICE_TYPE_UNKNOWN,
'Insteon'
);
}
if(newDevice != null) {
this.deviceIndex[deviceAddress] = newDevice;
this.deviceList.push(newDevice);
if(nodes[index].childNamed('property') != null) {
this.handleISYStateUpdate(deviceAddress, nodes[index].childNamed('property').attr.value);
}
}
} else {
this.logger('Ignoring disabled device: '+deviceName);
}
}
}
ISY.prototype.loadElkNodes = function(result) {
var document = new xmldoc.XmlDocument(result);
var nodes = document.childNamed('areas').childNamed('area').childrenNamed('zone');
for(var index = 0; index < nodes.length; index++) {
var id = nodes[index].attr.id;
var name = nodes[index].attr.name;
var alarmDef = nodes[index].attr.alarmDef;
var newDevice = new elkDevice.ElkAlarmSensor(
this,
name,
1,
id,
(alarmDef==17) ? this.DEVICE_TYPE_CO_SENSOR : this.DEVICE_TYPE_ALARM_DOOR_WINDOW_SENSOR);
this.zoneMap[newDevice.zone] = newDevice;
}
}
ISY.prototype.loadElkInitialStatus = function(result) {
var document = new xmldoc.XmlDocument(result);
var nodes = document.childrenNamed('ae');
for(var index = 0; index < nodes.length; index++) {
this.elkAlarmPanel.setFromAreaUpdate(nodes[index]);
}
nodes = document.childrenNamed('ze');
for(var index = 0; index < nodes.length; index++) {
var id = nodes[index].attr.zone;
var zoneDevice = this.zoneMap[id];
if(zoneDevice != null) {
zoneDevice.setFromZoneUpdate(nodes[index]);
if(this.deviceIndex[zoneDevice.address] == null && zoneDevice.isPresent()) {
this.deviceList.push(zoneDevice);
this.deviceIndex[zoneDevice.address] = zoneDevice;
}
}
}
}
ISY.prototype.finishInitialize = function(success, initializeCompleted) {
this.nodesLoaded = true;
initializeCompleted();
if(success) {
if(this.elkEnabled) {
this.deviceList.push(this.elkAlarmPanel);
}
this.guardianTimer = setInterval(this.guardian.bind(this), 60000);
this.initializeWebSocket();
}
}
ISY.prototype.guardian = function() {
var timeNow = new Date();
if((timeNow - this.lastActivity) > 60000) {
this.logger('ISY-JS: Guardian: Detected no activity in more then 60 seconds. Reinitializing web sockets');
this.initializeWebSocket();
}
}
ISY.prototype.variableChangedHandler = function(variable) {
this.logger('ISY-JS: Variable:'+variable.id+' ('+variable.type+') changed');
if(this.variableCallback != null && this.variableCallback != undefined) {
this.variableCallback(this, variable);
}
}
ISY.prototype.checkForFailure = function(response) {
return (response == null || response instanceof Error || response.statusCode != 200);
}
ISY.prototype.loadVariables = function(type,done) {
var that = this;
var options = {
username: this.userName,
password: this.password
}
// Load definitions
restler.get(
that.protocol+'://'+that.address+'/rest/vars/definitions/'+type,
options
).on('complete', function(result, response) {
if (that.checkForFailure(response)) {
that.logger("ISY-JS: Error loading variables from isy. Device likely doesn't have any variables defined. Safe to ignore.");
done()
} else {
that.createVariables(type, result);
// Load initial values
restler.get(
that.protocol+'://'+that.address+'/rest/vars/get/'+type,
options
).on('complete', function(result, response) {
if (that.checkForFailure(response)) {
that.logger('ISY-JS: Error loading variables from isy: ' + result.message);
throw new Error("Unable to load variables from the ISY");
} else {
that.setVariableValues(result);
}
done()
});
}
});
}
ISY.prototype.getVariableList = function() {
return this.variableList;
}
ISY.prototype.getVariable = function(type,id) {
var key = this.createVariableKey(type,id);
if(this.variableIndex[key] != null && this.variableIndex[key] != undefined) {
return this.variableIndex[key];
}
return null;
}
ISY.prototype.handleISYVariableUpdate = function(id, type, value, ts) {
var variableToUpdate = this.getVariable(type,id);
if(variableToUpdate != null) {
variableToUpdate.value = value;
variableToUpdate.lastChanged = ts;
this.variableChangedHandler(variableToUpdate);
}
}
ISY.prototype.createVariableKey = function(type,id) {
return type+':'+id;
}
ISY.prototype.createVariables = function(type, result) {
var document = new xmldoc.XmlDocument(result);
var variables = document.childrenNamed('e');
for(var index = 0; index < variables.length; index++) {
var id = variables[index].attr.id;
var name = variables[index].attr.name;
var newVariable = new ISYVariable(
this,
id,
name,
type);
this.variableList.push(newVariable);
this.variableIndex[this.createVariableKey(type,id)] = newVariable;
}
}
ISY.prototype.setVariableValues = function(result) {
var document = new xmldoc.XmlDocument(result);
var variables = document.childrenNamed('var');
for(var index = 0; index < variables.length; index++) {
var variableNode = variables[index];
var id = variableNode.attr.id;
var type = variableNode.attr.type;
var init = parseInt(variableNode.childNamed('init').val);
var value = parseInt(variableNode.childNamed('val').val);
var ts = variableNode.childNamed('ts').val;
var variable = this.getVariable(type,id);
if(variable != null) {
variable.value = value;
variable.init = init;
variable.lastChanged = new Date(ts);
}
}
}
ISY.prototype.initialize = function(initializeCompleted) {
var that = this;
var options = {
username: this.userName,
password: this.password
}
restler.get(
this.protocol+'://'+this.address+'/rest/nodes',
options
).on('complete', function(result, response) {
if(that.checkForFailure(response)) {
this.logger('ISY-JS: Error:'+result.message);
throw new Error("Unable to contact the ISY to get the list of nodes");
} else {
that.loadNodes(result);
that.loadVariables(that.VARIABLE_TYPE_INTEGER, function() {
that.loadVariables(that.VARIABLE_TYPE_STATE, function() {
if (that.elkEnabled) {
restler.get(
that.protocol + '://' + that.address + '/rest/elk/get/topology',
options
).on('complete', function (result, response) {
if (that.checkForFailure(response)) {
that.logger('ISY-JS: Error loading from elk: ' + result.message);
throw new Error("Unable to contact the ELK to get the topology");
} else {
that.loadElkNodes(result);
restler.get(
that.protocol + '://' + that.address + '/rest/elk/get/status',
options
).on('complete', function (result, response) {
if (that.checkForFailure(response)) {
that.logger('ISY-JS: Error:' + result.message);
throw new Error("Unable to get the status from the elk");
} else {
that.loadElkInitialStatus(result);
that.finishInitialize(true, initializeCompleted);
}
});
}
});
} else {
that.finishInitialize(true, initializeCompleted);
}
});
});
}
}).on('error', function(err,response) {
that.logger("ISY-JS: Error while contacting ISY"+err);
throw new Error("Error calling ISY"+err);
}).on('fail', function(data,response) {
that.logger("ISY-JS: Error while contacting ISY -- failure");
throw new Error("Failed calling ISY");
}).on('abort', function() {
that.logger("ISY-JS: Abort while contacting ISY");
throw new Error("Call to ISY was aborted");
}).on('timeout', function(ms) {
that.logger("ISY-JS: Timed out contacting ISY");
throw new Error("Timeout contacting ISY");
});
}
ISY.prototype.handleWebSocketMessage = function(event) {
//console.log("WEBSOCKET: "+event.data);
this.lastActivity = new Date();
var document = new xmldoc.XmlDocument(event.data);
if(document.childNamed('control') != null) {
var controlElement = document.childNamed('control').val;
var actionValue = document.childNamed('action').val;
var address = document.childNamed('node').val;
if(controlElement == 'ST') {
this.handleISYStateUpdate(address, actionValue);
} else if(controlElement == '_19') {
if(actionValue == 2) {
var aeElement = document.childNamed('eventInfo').childNamed('ae');
if(aeElement != null) {
if(this.elkAlarmPanel.setFromAreaUpdate(aeElement)) {
this.nodeChangedHandler(this.elkAlarmPanel);
}
}
} else if(actionValue == 3) {
var zeElement = document.childNamed('eventInfo').childNamed('ze');
var zoneId = zeElement.attr.zone;
var zoneDevice = this.zoneMap[zoneId];
if(zoneDevice != null) {
if(zoneDevice.setFromZoneUpdate(zeElement)) {
this.nodeChangedHandler(zoneDevice);
}
}
}
} else if(controlElement == '_1') {
if(actionValue == 6) {
var varNode = document.childNamed('eventInfo').childNamed('var');
if(varNode != null) {
var id = varNode.attr.id;
var type = varNode.attr.type;
var val = parseInt(varNode.childNamed('val').val);
var ts = varNode.childNamed('ts').val;
var year = parseInt(ts.substr(0,4));
var month = parseInt(ts.substr(4,2));
var day = parseInt(ts.substr(6,2));
var hour = parseInt(ts.substr(9,2));
var min = parseInt(ts.substr(12,2));
var sec = parseInt(ts.substr(15,2));
var timeStamp = new Date(year,month,day,hour,min,sec);
this.handleISYVariableUpdate(id, type, val, timeStamp);
}
}
}
}
}
ISY.prototype.initializeWebSocket = function() {
var that = this;
var auth = 'Basic ' + new Buffer(this.userName + ':' + this.password).toString('base64');
this.webSocket = new WebSocket.Client(
"ws://"+this.address+"/rest/subscribe",
["ISYSUB"],
{
headers: {
"Origin": "com.universal-devices.websockets.isy",
"Authorization": auth
}
});
this.lastActivity = new Date();
this.webSocket.on('message', function(event) {
that.handleWebSocketMessage(event);
});
}
ISY.prototype.getDeviceList = function() {
return this.deviceList;
}
ISY.prototype.getDevice = function(address) {
return this.deviceIndex[address];
}
ISY.prototype.getScene = function(address) {
return this.sceneIndex[address];
}
ISY.prototype.getSceneList = function() {
return this.sceneList;
}
ISY.prototype.handleISYStateUpdate = function(address, state) {
var deviceToUpdate = this.deviceIndex[address];
if(deviceToUpdate != undefined && deviceToUpdate != null) {
if(deviceToUpdate.handleIsyUpdate(state)) {
this.nodeChangedHandler(deviceToUpdate);
if(this.scenesInDeviceList) {
// Inefficient, we could build a reverse index (device->scene list)
// but device list is relatively small
for(var index = 0; index < this.sceneList.length; index++) {
if(this.sceneList[index].isDeviceIncluded(deviceToUpdate)) {
if(this.sceneList[index].reclalculateState()) {
this.nodeChangedHandler(this.sceneList[index]);
}
}
}
}
}
}
}
ISY.prototype.sendISYCommand = function(path, handleResult) {
var uriToUse = this.protocol+'://'+this.address+'/rest/'+path;
this.logger("ISY-JS: Sending ISY command..."+uriToUse);
var options = {
username: this.userName,
password: this.password
}
restler.get(uriToUse, options).on('complete', function(data, response) {
if(response.statusCode == 200) {
handleResult(true);
} else {
handleResult(false);
}
});
}
ISY.prototype.sendRestCommand = function(deviceAddress, command, parameter, handleResult) {
var uriToUse = this.protocol+'://'+this.address+'/rest/nodes/'+deviceAddress+'/cmd/'+command;
if(parameter != null) {
uriToUse += '/' + parameter;
}
this.logger("ISY-JS: Sending command..."+uriToUse);
var options = {
username: this.userName,
password: this.password
}
restler.get(uriToUse, options).on('complete', function(data, response) {
if(response.statusCode == 200) {
handleResult(true);
} else {
handleResult(false);
}
});
}
ISY.prototype.sendGetVariable = function(id, type, handleResult) {
var uriToUse = this.protocol+'://'+this.address+'/rest/vars/get/'+type+'/'+id;
this.logger("ISY-JS: Sending ISY command..."+uriToUse);
var options = {
username: this.userName,
password: this.password
}
restler.get(uriToUse, options).on('complete', function(result, response) {
if(response.statusCode == 200) {
var document = new xmldoc.XmlDocument(result);
var val = parseInt(document.childNamed('val').val);
var init = parseInt(document.childNamed('init').val);
handleResult(val, init);
}
});
}
ISY.prototype.sendSetVariable = function(id, type, value, handleResult) {
var uriToUse = this.protocol+'://'+this.address+'/rest/vars/set/'+type+'/'+id+'/'+value;
this.logger("ISY-JS: Sending ISY command..."+uriToUse);
var options = {
username: this.userName,
password: this.password
}
restler.get(uriToUse, options).on('complete', function(result, response) {
if(response.statusCode == 200) {
handleResult(true);
} else {
handleResult(false);
}
});
}
exports.ISY = ISY;