plugin.Name = "Isy994i";
plugin.OnChangeRequest = onChangeRequest;
plugin.OnConnect = onConnect;
plugin.OnDisconnect = onDisconnect;
plugin.OnPoll = onPoll;
plugin.OnSynchronizeDevices = onSynchronizeDevices;
plugin.PollingInterval = 100;
plugin.DefaultSettings = { "HostName": "192.168.1.75", "IsyPort": "80", "EncodedUsernPass": "", "UserName": "", "Password": "", "EnableScenes": "Yes", "EnablePrograms": "No", "EnableIntegerVariables": "No", "EnableStateVariables": "No" };
//IMPORTANT! This is not the HostName used. Value actually used is configured in "Properties" pane.
// Ver 8_6 By James Knutson 3/28/2021
var VERSION = "8_6";
var debug = true;
var LOG_MAX = 5000; // maximum size of the log in characters; set to 0 for unlimited
var LOG_TRIM = 500; // when maximum size reached, trim the log plus this much more so not constantly trimming
var socket = new TCPClient();
var http = new HTTPClient();
var LOG_ID = "Log";
var leftover = "";
var firstrun = "Yes";
var needSubscribe = true;
function getDevice(id) {
return plugin.Devices[id];
}
function formatJSDate(dt)
{
return (dt.toLocaleString('en-US', { hour: 'numeric',minute:'numeric', hour12: true }));
}
function log(message) {
console.log(message);
}
function fixprogramdate(mydate){
var temphour = mydate.substring(7,9);
var tempdaytime ="AM";
if(temphour=="00") { temphour="12";}
if(temphour.substring(0,1)=="0") { temphour=" "+temphour.substring(1,2);}
if(Number(temphour)>12) {
var x=Number(temphour)-12;
temphour=x.toString();
tempdaytime="PM";
}
var tempdate = "20"+mydate.substring(0,2)+"/"+mydate.substring(2,4)+"/"+mydate.substring(4,7)+temphour+mydate.substring(9,12)+" "+ tempdaytime;
return dateToText(tempdate);
}
function dateToText(mydate){
if(mydate!=""){
var myTime=mydate.substring(mydate.indexOf(" ")+1, mydate.length);
var myYear =mydate.substring(0, 4);
var tempDate = mydate.substring(5, mydate.length);
var myMonth = tempDate.substring(0, tempDate.indexOf("/"));
var myDay = tempDate.substring(tempDate.indexOf("/")+1, tempDate.indexOf(" "));
var d = new Date(myYear,myMonth-1,myDay);
var weekday = new Array(7);
weekday[0] = "Sun";
weekday[1] = "Mon";
weekday[2] = "Tue";
weekday[3] = "Wed";
weekday[4] = "Thu";
weekday[5] = "Fri";
weekday[6] = "Sat";
var month = new Array();
month[0] = "Jan";
month[1] = "Feb";
month[2] = "Mar";
month[3] = "April";
month[4] = "May";
month[5] = "June";
month[6] = "July";
month[7] = "Aug";
month[8] = "Sept";
month[9] = "Oct";
month[10] = "Nov";
month[11] = "Dec";
var myWeekday=weekday[d.getDay()];
var myMonthName=month[d.getMonth()];
//You can use any Format you wish.
return myWeekday+" "+myMonthName+" "+myDay+" "+myTime;
} else return "";
}
function updateProgram(curid, ParentId,PEnabled,PStatus,Running, lastRunTime, lastFinishTime, nextScheduledRunTime) {
var curDevice = getDevice(curid);
try {
//log("id:"+curid+" ParentId:"+ParentId+" Enabled:"+PEnabled+" Status:"+PStatus+" Running:"+Running+" LastRun:"+dateToText(lastRunTime)+" LastFinish:"+dateToText(lastFinishTime)+" NextSchedTime:"+dateToText(nextScheduledRunTime));
if(lastRunTime!=""){ curDevice.lastRunTime = dateToText(lastRunTime);}
if(lastFinishTime!=""){ curDevice.lastFinishTime = dateToText(lastFinishTime);}
if(nextScheduledRunTime!=""){ curDevice.nextScheduledRunTime = dateToText(nextScheduledRunTime);}
if(PEnabled!=""){ curDevice.PEnabled = PEnabled;}
if(PStatus!=""){ curDevice.PStatus = PStatus;}
if(Running!=""){ curDevice.Running = Running;}
if(ParentId!=""){curDevice.ParentId=ParentId;}
} catch (err) {}
}
function updatevalue(node, control, value) {
//This is where all the data from ISY994i is used to update the state of all ISY994i devices in app
//log(node+" "+control+" "+value);
var curDevice = getDevice(node);
if (firstrun == "No") {log("UpdateValue "+node+" "+control+" "+value);}
try {
if (node.substring(0, 1)=="n") {
switch(control){
case "ST":
curDevice.ST= value;
if (value > 0) {
curDevice.Switch = "On";
} else {
curDevice.Switch = "Off";
}
break;
case "SVOL":
curDevice.SVOL= value;
break;
case "GV0":
curDevice.GV0= value;
break;
case "GV1":
curDevice.GV1= value;
break;
case "GV2":
curDevice.GV2= value;
break;
case "GV3":
curDevice.GV3= value;
break;
case "GV4":
curDevice.GV4= value;
break;
case "GV5":
curDevice.GV5= value;
break;
case "GV6":
curDevice.GV6= value;
break;
case "GV7":
curDevice.GV7= value;
break
case "GV8":
curDevice.GV8= value;
break;
case "GV9":
curDevice.GV9= value;
break;
case "GV10":
curDevice.GV10= value;
break;
}
}else {
switch (control) {
case "ST":
switch (curDevice.DeviceType) {
case "Thermostat":
// log("Insteon Thermostat "+curDevice.DeviceType+" "+control+" "+value);
curDevice.Temperature = Math.round(Number(value) / 2);
break;
case "ZThermostat":
// log("ZWave Thermostat "+curDevice.DeviceType+" "+control+" "+value);
curDevice.Temperature = Math.round(Number(value));
break;
case "Light":
if (value > 0) {
curDevice.Switch = "On";
curDevice.Level = Math.round(Number(value) / 2.55);
} else {
curDevice.Switch = "Off";
curDevice.Level = 0;
}
break;
case "Status":
if (value > 0) {
curDevice.Switch = "On";
} else {
curDevice.Switch = "Off";
}
break;
case "Outlet":
if (value > 0) {
curDevice.Switch = "On";
} else {
curDevice.Switch = "Off";
}
break;
case "ContactSensor":
if (value == "255") {
curDevice.Contact = "Open";
} else {
curDevice.Contact = "Closed";
}
break;
case "MotionSensor":
if (value == "255") {
curDevice.Motion = "Active";
} else {
curDevice.Motion = "Inactive";
}
break;
case "Battery":
if (value == "255") {
curDevice.Battery = 100;
} else {
curDevice.Battery = 0;
}
break;
case "PresenceSensor":
curDevice.Presence = "NotPresent";
if (value == "255") {
curDevice.Presence = "Present";
}
if (value == "0") {
curDevice.Presence = "Present";
}
break;
case "WaterSensor":
if (node.substring(node.length - 1, node.length) == "1") {
if (value == "255") {
curDevice.Water = "Dry";
} else {
curDevice.Water = "Wet";
}
}
if (node.substring(node.length - 1, node.length) == "2") {
if (value == "255") {
curDevice.Water = "Wet";
} else {
curDevice.Water = "Dry";
}
}
break;
}
break;
case "CLIMD":
if (value == "0") {
curDevice.ThermostatMode = "Off";
}
if (value == "1") {
curDevice.ThermostatMode = "Heat";
}
if (value == "2") {
curDevice.ThermostatMode = "Cool";
}
if (value == "3") {
curDevice.ThermostatMode = "Auto";
}
break;
case "BATLVL":
curDevice.BatteryLevel=value+"%";
break;
case "LUMIN":
curDevice.Luminance=value+"%";
break;
case "CLITEMP":
curDevice.Temperature=value.substring(0,2);
break;
case "GV1":
if (value == "0") {
curDevice.BatteryPowered = "False";
}
if (value == "1") {
curDevice.BatteryPowered = "True";
}
break;
case "CLIHCS":
//log("CLIHCS(Calling for): "+value);
// 0 off
//1 calling for heat
//2 calling for cool
if (value == "0") {
curDevice.Status = "Idle";
}
if (value == "1") {
curDevice.Status = "Heating";
}
if (value == "2") {
curDevice.Status = "Cooling";
}
break;
case "UOM":
// mine is 2
break;
case "CLIFS":
//log("CLIFS(Fan Mode): "+value);
curDevice.SupportedThermostatFanModes = ["Auto", "On"];
if (value == "8") {
curDevice.ThermostatFanMode = "Auto";
}
if (value == "7") {
curDevice.ThermostatFanMode = "On";
}
break;
case "CLIHUM":
curDevice.Humidity = Number(value);
break;
case "CLISPH":
if (curDevice.DeviceType == "ZThermostat"){
curDevice.HeatingSetpoint = Math.round(Number(value));
} else {
curDevice.HeatingSetpoint = Math.round(Number(value) / 2);
}
break;
case "CLISPC":
if (curDevice.DeviceType == "ZThermostat"){
curDevice.CoolingSetpoint = Math.round(Number(value));
} else {
curDevice.CoolingSetpoint = Math.round(Number(value) / 2);
}
break;
case "ISYIntegerValue":
curDevice.ISYIntegerValue = value;
break;
case "ISYStateValue":
curDevice.ISYStateValue = value;
break;
case "timeSet":
curDevice.timeSet = value;
//log("Updated Variable:"+curDevice.name+" Id:"+curDevice.Id+" timeSet:"+value);
break;
default:
//log(node+" "+control+" "+value);
}
}
} catch (err) {}
}
function onChangeRequest(device, attribute, value) {
//Any changes made by user input are sent here to be interpreted and sent to ISY994i
var outputNum = device.Id;
var devicenode = encodeURI(outputNum);
var config = {
auth: {
username: plugin.Settings["UserName"],
password: plugin.Settings["Password"]
}
}
log("ChangeRequest: "+device.DeviceType+" Node: "+devicenode+" Attribute: "+attribute+" Value: "+value);
//Send commands to ISY994i base off attribute(type of command) and value(actual change)
// check if device is a ISY Node
if (outputNum.substring(0, 1)=="n") {
if (attribute =="Switch") {
if (value =="Off") { var inputCmd = "/rest/nodes/" + devicenode + "/cmd/DFOF";}
if (value == "On"){ var inputCmd = "/rest/nodes/" + devicenode + "/cmd/DFON";}
http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + inputCmd, config);
}
else {
var inputCmd = "/rest/nodes/" + devicenode + "/cmd/"+value;
log(inputCmd);
http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + inputCmd, config);
}}
else {
switch (attribute) {
case "Switch":
if (devicenode.substring(devicenode.length - 1, devicenode.length) == "1") {
//These are all your On/Off devices
if (value == "On") {
var inputCmd = "/rest/nodes/" + devicenode + "/cmd/DON/255";
} else {
var inputCmd = "/rest/nodes/" + devicenode + "/cmd/DOF";
}
http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + inputCmd, config);
}
break;
case "Level":
//These are your Dimmer Devices
if (value == 0) {
var inputCmd = "/rest/nodes/" + devicenode + "/cmd/DOF";
} else {
var inputCmd = "/rest/nodes/" + devicenode + "/cmd/DON/" + Math.round(Number(value * 2.55));
}
http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + inputCmd, config);
break;
case "HeatingSetpoint":
//Thermostat adjustment for heat setpoint
//log("set heat to:"+value);
if (device.DeviceType =="ZThermostat") {
var inputCmd = "/rest/nodes/" + devicenode + "/cmd/CLISPH/" + Number(value);
} else {
var inputCmd = "/rest/nodes/" + devicenode + "/cmd/CLISPH/" + Number(value) * 2;
}
http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + inputCmd, config);
break;
case "CoolingSetpoint":
//Thermostat adjustment for cool setpoint
//log("set cool to:"+value);
if (device.DeviceType =="ZThermostat") {
var inputCmd = "/rest/nodes/" + devicenode + "/cmd/CLISPC/" + Number(value);
} else {
var inputCmd = "/rest/nodes/" + devicenode + "/cmd/CLISPC/" + Number(value) * 2;
}
http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + inputCmd, config);
break;
case "ThermostatMode":
//Thermostat adjustment for new mode
if (value == "Cool") {
value = "2";
}
if (value == "Heat") {
value = "1";
}
if (value == "Off") {
value = "0";
}
if (value == "Auto") {
value = "3";
}
if (value == "Eco") {
value = "5";
}
var inputCmd = "/rest/nodes/" + devicenode + "/cmd/CLIMD/" + value;
http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + inputCmd, config);
break;
case "ThermostatFanMode":
if (value == "Auto") {
value = "8";
}
if (value == "On") {
value = "7";
}
if (value == "7" || value == "8" ) {
var inputCmd = "/rest/nodes/" + devicenode + "/cmd/CLIFS/" + value;
http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + inputCmd, config);
}
break;
case "Scene":
//These are all your ISY scenes if you enabled them
if (device.Switch == "On") {
var inputCmd = "/rest/nodes/" + devicenode + "/cmd/DOF";
device.Switch = "Off";
} else {
var inputCmd = "/rest/nodes/" + devicenode + "/cmd/DON/255";
device.Switch = "On";
}
http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + inputCmd, config);
break;
case "PCommand":
//This is for controlling ISY Programs
var inputCmd = "/rest/programs/" + outputNum + "/" + value;
http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + inputCmd, config);
break;
case "ISYIntegerValue":
//This is for setting ISY Integer variables
outputNum = outputNum.substring(10, outputNum.length);
var inputCmd = "/rest/vars/set/1/" + outputNum + "/" + value;
http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + inputCmd, config);
break;
case "ISYStateValue":
//This is for setting ISY State variables
outputNum = outputNum.substring(8, outputNum.length);
var inputCmd = "/rest/vars/set/2/" + outputNum + "/" + value;
http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + inputCmd, config);
break;
case "updateVariables":
//This is for controlling ISY Programs
if (plugin.Settings["EnableIntegerVariables"] == "Yes" || plugin.Settings["EnableIntegerVariables"] == "YES") {
updateIntegerVariables();
}
if (plugin.Settings["EnableStateVariables"] == "Yes" || plugin.Settings["EnableStateVariables"] == "YES") {
updateStateVariables();
}
break;
case "updatePrograms":
updatePrograms();
break;
case "updateDevices":
updateDevices();
break;
case "updateWeather":
updateWeather();
break;
case "customCommand":
//This is for controlling ISY Programs
var inputCmd = value;
http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + inputCmd, config);
break;
default:
if (attribute == "Log") {
if (value == "ClearLog") {
var logDevice = getDevice("Log");
logDevice.Log = "Isy Feedback\n";
}
}
//log("Command:"+attribute+" "+value);
}}
return;
}
function fixdate(isydate){
if(isydate!=""){
var isyYear =isydate.substring(0, 4);
var isyMonth =isydate.substring(4, 6);
var isyDay =isydate.substring(6,8);
var isyHour =isydate.substring(9,11);
var isyMinutes =isydate.substring(12, 14);
var isydaytime="AM";
if(isyHour=="12"){isydaytime="PM";}
if(Number(isyHour)>12) {
var x=Number(isyHour)-12;
isyHour=x.toString();
isydaytime="PM";
}
var d = new Date(isyYear,isyMonth-1,isyDay);
var weekday = new Array(7);
weekday[0] = "Sun";
weekday[1] = "Mon";
weekday[2] = "Tue";
weekday[3] = "Wed";
weekday[4] = "Thu";
weekday[5] = "Fri";
weekday[6] = "Sat";
var month = new Array();
month[0] = "Jan";
month[1] = "Feb";
month[2] = "Mar";
month[3] = "April";
month[4] = "May";
month[5] = "June";
month[6] = "July";
month[7] = "Aug";
month[8] = "Sept";
month[9] = "Oct";
month[10] = "Nov";
month[11] = "Dec";
var isyWeekday=weekday[d.getDay()];
var isyMonthName=month[d.getMonth()];
//You can use any Format you wish.
return isyWeekday+" "+isyMonthName+" "+isyDay+" "+isyHour+":"+isyMinutes+" "+isydaytime;
} else return "";
}
function updateIntegerVariables() {
//log("Updating Integer Variables");
var config = {
auth: {
username: plugin.Settings["UserName"],
password: plugin.Settings["Password"]
}
}
var r = http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + "/rest/vars/get/1", config); //get list of all integer variables
var data = r.data;
//00020190818 10:55:10
try{
var varElement = XML.parse(data);
varElement.elements.forEach(function (node) {
var varid = node.attributes.id;
var varvalue = "", varts = "";
node.elements.forEach(function (element) {
switch (element.name) {
case "val":
varvalue = element.text;
break;
case "ts":
varts = element.text;
break;
default:
}
});
//log(" ISYInteger:" + varid+" ISYIntegerValue:"+varvalue+" time set:"+varts);
updatevalue("ISYInteger" + varid, "ISYIntegerValue", varvalue);
updatevalue("ISYInteger" + varid, "timeSet", fixdate(varts));
});
} catch(err) { log("No Integer Variables!");
}
}
function updateStateVariables() {
//log("Updating State Variables");
var config = {
auth: {
username: plugin.Settings["UserName"],
password: plugin.Settings["Password"]
}
}
//Update State variable value
var r = http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + "/rest/vars/get/2", config); //get list of all State variables
var data = r.data;
//log(data);
try{
//00020190818 10:55:10
var varElement = XML.parse(data);
varElement.elements.forEach(function (node) {
var varid = node.attributes.id;
var varvalue = "", varts = "";
node.elements.forEach(function (element) {
switch (element.name) {
case "val":
varvalue = element.text;
break;
case "ts":
varts = element.text;
break;
default:
}
});
//log(" ISYState:" + varid+" ISYStateValue:"+varvalue+" time set:"+varts);
updatevalue("ISYState" + varid, "ISYStateValue", varvalue);
updatevalue("ISYState" + varid, "timeSet", fixdate(varts));
});
} catch(err) { log("No State Variables!");
}
}
function updatePrograms() {
//log("Updating Programs");
var config = {
auth: {
username: plugin.Settings["UserName"],
password: plugin.Settings["Password"]
}
}
var r = http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + "/rest/programs?subfolders=true", config); //get list of all programs
var data = r.data;
//Outside Lights On2020/01/09 4:36:45 PM2020/01/09 4:36:45 PM2020/01/10 4:37:44 PM
var programElement = XML.parse(data);
programElement.elements.forEach(function (program) {
var PStatus = program.attributes.status;
var curid = program.attributes.id;
var PEnabled = program.attributes.enabled;
var Running = program.attributes.running;
var ParentId = program.attributes.parentId;
var lastRunTime = "", lastFinishTime = "", nextScheduledRunTime = "",name = "";
program.elements.forEach(function (element) {
switch (element.name) {
case "name":
name = element.text;
break;
case "lastRunTime":
lastRunTime = element.text;
break;
case "lastFinishTime":
lastFinishTime = element.text;
break;
case "nextScheduledRunTime":
nextScheduledRunTime = element.text;
break;
default:
}
});
//log("id:"+curid+" ParentId:"+ParentId+" Enabled:"+PEnabled+" Status:"+PStatus+" Running:"+Running+" LastRun:"+dateToText(lastRunTime)+" LastFinish:"+dateToText(lastFinishTime)+" NextSchedTime:"+dateToText(nextScheduledRunTime));
updateProgram(curid, ParentId,PEnabled,PStatus,Running, lastRunTime, lastFinishTime, nextScheduledRunTime);
});
}
function subscribe(){
//This sends the subscribe command to the ISY994i so any changes are automaticaly sent to this socket
socket.send("POST /services HTTP/1.1\r\n");
socket.send("Authorization: Basic " + plugin.Settings["EncodedUsernPass"] + "\r\n");
socket.send("Content-Length: 192\r\n");
socket.send("Content-Type: text/xml; charset=\"utf-8\"\r\n");
socket.send("SOAPACTION:\"urn:udi-com:service:X_Insteon_Lighting_Service:1#Subscribe\"\r\n");
socket.send("\r\n");
socket.send("\r\n");
socket.send("REUSE_SOCKETinfinite\r\n");
needSubscribe = false;
}
function onConnect() {
//log("Connecting!");
firstrun = "Yes";
socket.connect(plugin.Settings["HostName"], plugin.Settings["IsyPort"]);
needSubscribe = true;
}
function onDisconnect() {
//log("Disconnecting!");
socket.close();
}
function onPoll() {
if(needSubscribe){subscribe();}
//Get new data from ISY994i
var dataReceived = socket.receive();
var data = dataReceived;
//log("****************************************************************New Data Received*******************************************************");
//log(data);
//log("*****************************************************************End Data Received*******************************************************");
//log(leftover);
if (leftover > "") {
data = leftover + data;
}
//Update current values from ISY
while (data.length > 1) {
if (data.indexOf(" -1 && data.indexOf("") > -1) {
leftover = "";
var curevent = data.substring(data.indexOf("")+8);
//log(curevent);
if (firstrun == "No") { log(curevent);}
var xmlObj = XML.parse(curevent);
//_160120200118 10:57:51
//_103200118 10:57:52200118 10:57:5231
var seqnum = xmlObj.attributes.seqnum;
var control = "", action = "", node = "";
xmlObj.elements.forEach(function (element) {
switch (element.name) {
case "control":
control = element.text;
break;
case "action":
action = element.text;
break;
case "node":
node = element.text;
break;
case "eventInfo":
if(control=="_1"){
if(action=="6"){ varelement=element; } //Save XML for more parsing to get Variable info 0120200118 10:57:51
if(action=="0"){ progelement=element; } // Save XML for more parsing to get Program info 3200118 10:57:52200118 10:57:5231
}
break;
default:
}
});
// log("Control:"+control+" Action"+action);
if (control == "_0" && action == "120") {
var dt = new Date();
var today=formatJSDate(dt);
try {
var myISY = getDevice("IsyRequest");
myISY.lastPing=today;
//log("Ping received: "+today);
} catch (err) {}
}
if ((control == "_23" && action == "1") || (control == "_11" && action == "100")) {
if (firstrun == "Yes") {
//log(curevent);
log("End of Device Update");
if (plugin.Settings["EnableIntegerVariables"] == "Yes" || plugin.Settings["EnableIntegerVariables"] == "YES") {
//log("Updating Integer Variables");
updateIntegerVariables();
}
if (plugin.Settings["EnableStateVariables"] == "Yes" || plugin.Settings["EnableStateVariables"] == "YES") {
//log("Updating State Variables");
updateStateVariables();
}
if (plugin.Settings["EnablePrograms"] == "Yes" || plugin.Settings["EnablePrograms"] == "YES") {
//log("Updating Programs");
updatePrograms();
}
firstrun = "No";
}
}
if(control=="_1" && action=="6"){
//update Variable
//0120200118 10:57:51
if (varelement.elements.length > 0) {
varelement.elements.forEach(function (eventinfo) {
if(eventinfo.name=="var"){
var curid = eventinfo.attributes.id;
var curtype = eventinfo.attributes.type;
var curval = "",curts = "";
eventinfo.elements.forEach(function (curvariable) {
switch (curvariable.name) {
case "val":
curval = curvariable.text;
break;
case "ts":
curts = curvariable.text;
break;
default:
}
});
// log("Variable ID: "+curid+" Type: "+curtype+" Value: "+curval+" Time Set: "+curts);
if(curtype=="2"){
if (plugin.Settings["EnableStateVariables"] == "Yes" || plugin.Settings["EnableStateVariables"] == "YES") {
updatevalue("ISYState" + curid, "ISYStateValue",curval);
updatevalue("ISYState" + curid, "timeSet", fixdate(curts));
}
}
if(curtype=="1"){
if (plugin.Settings["EnableIntegerVariables"] == "Yes" || plugin.Settings["EnableIntegerVariables"] == "YES") {
updatevalue("ISYInteger" + curid, "ISYIntegerValue", curval);
updatevalue("ISYInteger" + curid, "timeSet", fixdate(curts));
}
}
}
});
}
}
if(control=="_1" && action=="0"){
//update Program
//3200118 10:57:52200118 10:57:5231
if (plugin.Settings["EnablePrograms"] == "Yes" || plugin.Settings["EnablePrograms"] == "YES") {
if (progelement.elements.length > 0) {
var lastRunTime = "",lastFinishTime="",curid="",nextScheduledRunTime="",PEnabled="";
progelement.elements.forEach(function (eventinfo) {
switch (eventinfo.name) {
case "r":
lastRunTime = eventinfo.text;
break;
case "f":
lastFinishTime = eventinfo.text;
break;
case "on":
PEnabled="true";
break;
case "off":
PEnabled="false";
break;
case "id":
curid = eventinfo.text;
break;
case "nsr":
nextScheduledRunTime = eventinfo.text;
break;
default:
}
});
//log("Program Id: "+curid+" Enabled: "+PEnabled+" R: "+lastRunTime+" F: "+lastFinishTime+" NSR: "+nextScheduledRunTime);
updateProgram("00"+curid, "",PEnabled,"","", lastRunTime, lastFinishTime, nextScheduledRunTime);
}
}
}
if (node!= "" && control!= "RR" && control!= "OL") {
//Take new data from ISY994i and send it to the update function to update app variables
updatevalue(node, control, action);
}
data = data.substring(data.indexOf("/Event>") + 7, data.length);
} else {
if (data.indexOf(" -1 || data.indexOf("") > -1) {
//Valid Leftover data!
//log(data);
leftover = data;
}
//Garbage Leftover Data
data = "";
}
//End of Getting values from ISY
}
//Update Integer variable value
}
function onSynchronizeDevices() {
//This is ran from in the HomeRemote Designer and used to import all your ISY994i devices
var config = {
auth: {
username: plugin.Settings["UserName"],
password: plugin.Settings["Password"]
}
}
// var pluginDevices = []; //this deletes all current devices
var pluginDevice = new Device();
pluginDevice.Id = "Log";
pluginDevice.DisplayName = "Log";
pluginDevice.Icon = "PC";
pluginDevice.DeviceType = "";
pluginDevice.TileTemplate = "";
pluginDevice.DetailsTemplate = "";
pluginDevice.Capabilities = [""];
pluginDevice.Attributes = ["Log"];
plugin.Devices[pluginDevice.Id] = pluginDevice;
var pluginDevice = new Device();
pluginDevice.Id = "IsyRequest";
pluginDevice.DisplayName = "IsyRequest";
pluginDevice.Icon = "PC";
pluginDevice.DeviceType = "";
pluginDevice.TileTemplate = "";
pluginDevice.DetailsTemplate = "";
pluginDevice.Capabilities = [""];
pluginDevice.Attributes = ["lastPing","updateVariables", "updatePrograms", "updateDevices", "customCommand"];
plugin.Devices[pluginDevice.Id] = pluginDevice;
//Finished creating log device for testing
var r = http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + "/rest/nodes", config); //get list of all devices
var data = r.data;
//log(data);
var nodesElement = XML.parse(data);
try {
var curadd = "",nodename= "",nodetype = "";
nodesElement.elements.forEach(function (node) {
//log(node.name);
if (node.name!="root") {
node.elements.forEach(function (element) {
switch (element.name) {
case "name":
nodename = element.text;
break;
case "address":
curadd = element.text;
break;
case "type":
nodetype = element.text;
break;
default:
}
});
if (node.name=="group") {
if (plugin.Settings["EnableScenes"] == "Yes" || plugin.Settings["EnableScenes"] == "YES") {
var pluginDevice = new Device();
pluginDevice.Id = curadd;
//pluginDevice.Name = "Scene_" + nodename;
pluginDevice.DisplayName = "Scene_" +nodename;
pluginDevice.Icon = "Sun";
pluginDevice.DeviceType = "Scene";
pluginDevice.TileTemplate = "SceneTile.xaml";
pluginDevice.DetailsTemplate = "";
pluginDevice.Capabilities = ["Switch"];
pluginDevice.Attributes = ["Scene"];
plugin.Devices[pluginDevice.Id] = pluginDevice;
}
} else if (curadd.substring(0, 1)=="n") {
if (plugin.Settings["EnableNodes"] == "Yes" || plugin.Settings["EnableNodes"] == "YES") {
var pluginDevice = new Device();
pluginDevice.Id = curadd;
pluginDevice.DisplayName = "Node_" +nodename;
pluginDevice.Icon = "Sensor";
pluginDevice.DeviceType = "Node";
pluginDevice.TileTemplate = "ISYNodeTile.xaml";
pluginDevice.DetailsTemplate = "ISYNodeDetails.xaml";
pluginDevice.Capabilities = ["Switch"];
pluginDevice.Attributes = ["NCommand","ST","SVOL","GV0","GV1","GV2","GV3","GV4","GV5","GV6","GV7","GV8","GV9","GV10"];
plugin.Devices[pluginDevice.Id] = pluginDevice;
}
} else {
var basicnodetype = nodetype.substring(0, 2);
/*
This is a list of all ISY994i device types I have found. Included this incase you want to break down into more specific types for your GUI
1.0. =LampLinc Dimmable
1.14 =Dual Band LampLinc Dimmable
1.1. =SwitchLinc Dimmer
1.12 =KeypadLinc Dimmer 8 Buttons
1.25 =SwitchLinc Dimmer W/Beeper
1.27 =KeypadLinc Dimmer 6 Buttons
1.28 =KeypadLinc Dimmer 8 Buttons
1.32 =Dual Band SwitchLinc Dimmer
1.33 =Insteon OutletLinc Dimmer
1.46 =FanLinc Dimmable Light/Fan (Off/Low/Medium/High)
1.65 =KeypadLinc Dimmer 8 Buttons
1.66 =KeypadLinc Dimmer 5 Buttons
1.9. =KeypadLinc Dimmer
2.13 =ToggleLinc On/Off
2.15 =KeypadLinc Relay On/Off
2.20 =In-LineLinc Relay W/ Sense On/Off
2.22 =Icon Relay Switch On/Off
2.26 =ToggleLinc Relay On/Off
2.28 =SwitchLinc Relay On/Off
2.42 =Dual Band SwitchLinc On/Off
2.44 =Dual Band KeypadLinc Relay On/Off
2.47 =Micro On/Off
2.55 =Plugin On/Off Module
2.57 =Dual OutletLinc Top/Bottom On/Off
2.8. =OutletLinc On/Off
2.9. =ApplianceLinc
4.16 =Power Switch Zwave On/Off
4.17 =Zwave Dimmer
4.64 =Zwave Door Locks
4.7. =Zwave Motion Detector
5.11 =Thermostat
7.0. =I/OLink GarageDoor Sensor Opened/Closed, Contacts Open/Close
7.9. =SynchroLinc Status of PLugged Devices On/Off
15.6 =MorningLinc DoorLock Lock/Unlock
16.1. =Insteon Motion Sensor Status On/Off
16.2 =TriggerLinc Door/Window Sensor Open/Close
16.8 =Water Sensor
16.17 =Hidden Door Sensor
16.22 =Motion Sensor II
*/
switch (basicnodetype) {
case "1.":
// All Dimmable Devices
// MultiButton Device-Only main button is Controllable, other buttons can only be controlled by scenes!
if (curadd.substring(curadd.length - 1, curadd.length) == "1") {
pluginDevice = new Device();
pluginDevice.Id = curadd;
//pluginDevice.Name = nodename;
pluginDevice.DisplayName = nodename;
pluginDevice.Icon = "Lightbulb";
pluginDevice.DeviceType = "Light";
pluginDevice.TileTemplate = "LightTile.xaml";
pluginDevice.DetailsTemplate = "LightDetails.xaml";
pluginDevice.Capabilities = ["Switch", "SwitchLevel"];
pluginDevice.Attributes = [];
plugin.Devices[pluginDevice.Id] = pluginDevice;
} else {
// This is the secondary buttons of multi button devices. No commands can be sent only used for status.
pluginDevice = new Device();
pluginDevice.Id = curadd;
pluginDevice.DisplayName = nodename;
pluginDevice.Icon = "Lightbulb";
pluginDevice.DeviceType = "Status";
pluginDevice.TileTemplate = "ISYStatusTile.xaml";
pluginDevice.DetailsTemplate = "";
pluginDevice.Capabilities = ["Switch"];
pluginDevice.Attributes = [];
plugin.Devices[pluginDevice.Id] = pluginDevice;
}
break;
case "2.":
//All On/Off switch types
if (curadd.substring(curadd.length - 1, curadd.length) == "1") {
pluginDevice = new Device();
pluginDevice.Id = curadd;
//pluginDevice.Name = nodename;
pluginDevice.DisplayName = nodename;
if (nodetype.substring(0, 3) == "2.5" || nodetype.substring(0, 3) == "2.8") { // This is for switched Outlets
pluginDevice.Icon = "Plug";
pluginDevice.DeviceType = "Outlet";
pluginDevice.TileTemplate = "OutletTile.xaml";
pluginDevice.DetailsTemplate = "";
pluginDevice.Capabilities = ["Switch"];
} else {
pluginDevice.Icon = "Lightbulb";
pluginDevice.DeviceType = "Light";
pluginDevice.TileTemplate = "LightTile.xaml";
pluginDevice.DetailsTemplate = "LightDetails.xaml";
pluginDevice.Capabilities = ["Switch", "SwitchLevel"];
}
pluginDevice.Attributes = [];
plugin.Devices[pluginDevice.Id] = pluginDevice;
} else {
// This is the secondary buttons of multi button devices. No commands can be sent only used for status.
pluginDevice = new Device();
pluginDevice.Id = curadd;
pluginDevice.DisplayName = nodename;
pluginDevice.Icon = "Lightbulb";
pluginDevice.DeviceType = "Status";
pluginDevice.TileTemplate = "ISYStatusTile.xaml";
pluginDevice.DetailsTemplate = "";
pluginDevice.Capabilities = ["Switch"];
pluginDevice.Attributes = [];
plugin.Devices[pluginDevice.Id] = pluginDevice;
}
break;
case "4.":
//All ZWave
//Added by CA to accommodate ZWave T'stat (4.8.x.x) and Motion Detector (4.7.x.x)
pluginDevice = new Device();
pluginDevice.Id = curadd;
pluginDevice.DisplayName = nodename;
if (nodetype.substring(0, 4) == "4.8.") {
pluginDevice.Icon = "Thermometer";
pluginDevice.DeviceType = "ZThermostat";
pluginDevice.TileTemplate = "ThermostatTile.xaml";
pluginDevice.DetailsTemplate = "";
pluginDevice.Capabilities = ["TemperatureMeasurement", "ThermostatCoolingSetpoint", "ThermostatFanMode", "ThermostatHeatingSetpoint", "ThermostatMode", "RelativeHumidityMeasurement"];
pluginDevice.Attributes = ["Status"];
}
plugin.Devices[pluginDevice.Id] = pluginDevice;
if (nodetype.substring(0, 4) == "4.7.") {
pluginDevice.Icon = "Sensor";
pluginDevice.TileTemplate = "MotionSensorTile.xaml";
pluginDevice.DetailsTemplate = "";
pluginDevice.DeviceType = "MotionSensor";
pluginDevice.Capabilities = ["MotionSensor"];
pluginDevice.Attributes = ["Status"];
}
break;
case "5.":
//Thermostats
//var nodeflag = nodeinfo.substring(nodeinfo.indexOf(""));
// if (nodeflag != "0") {
pluginDevice = new Device();
pluginDevice.Id = curadd;
//pluginDevice.Name = nodename;
pluginDevice.DisplayName = nodename;
pluginDevice.Icon = "Thermometer";
pluginDevice.DeviceType = "Thermostat";
pluginDevice.TileTemplate = "ThermostatTile.xaml";
pluginDevice.DetailsTemplate = "ThermostatDetails.xaml";
pluginDevice.Capabilities = ["TemperatureMeasurement", "ThermostatCoolingSetpoint", "ThermostatFanMode", "ThermostatHeatingSetpoint", "ThermostatMode", "RelativeHumidityMeasurement"];
pluginDevice.Attributes = ["Status"];
plugin.Devices[pluginDevice.Id] = pluginDevice;
//}
break;
case "7.":
//Sensor status of Plug Device
if (nodetype.substring(0, 4) == "7.9.") {
pluginDevice = new Device();
pluginDevice.Id = curadd;
//pluginDevice.Name = nodetype + nodename;
pluginDevice.DisplayName = nodename;
pluginDevice.Icon = "Sensor";
pluginDevice.DeviceType = "ContactSensor";
pluginDevice.TileTemplate = "ContactSensorTile.xaml";
pluginDevice.DetailsTemplate = "";
pluginDevice.Capabilities = ["ContactSensor"];
pluginDevice.Attributes = [];
plugin.Devices[pluginDevice.Id] = pluginDevice;
}
//Sensor status with Controll On/Off Garage control device------Work in Progress
if (nodetype.substring(0, 4) == "7.0.") {
pluginDevice = new Device();
pluginDevice.Id = curadd;
//pluginDevice.Name = nodetype + nodename;
pluginDevice.DisplayName = nodename;
pluginDevice.Icon = "Home";
pluginDevice.DeviceType = "GarageDoor";
pluginDevice.TileTemplate = "GarageDoorTile.xaml";
pluginDevice.DetailsTemplate = "GarageDoorDetails.xaml";
pluginDevice.Capabilities = ["DoorControl"];
pluginDevice.Attributes = ["Status"];
plugin.Devices[pluginDevice.Id] = pluginDevice;
}
break;
case "16":
//All Sensors
//Node ends in 1-Main Sensor, 2-Secodary(wet), 3-Low battery, 4-Heartbeat
pluginDevice = new Device();
pluginDevice.TileTemplate = "ContactSensorTile.xaml";
pluginDevice.DeviceType = "ContactSensor";
pluginDevice.Icon = "Sensor";
pluginDevice.Capabilities = ["ContactSensor"];
pluginDevice.Attributes = [];
if (nodetype.substring(0, 4) == "16.8") {
pluginDevice.TileTemplate = "WaterSensorTile.xaml";
pluginDevice.DeviceType = "WaterSensor";
pluginDevice.Icon = "Drop";
pluginDevice.Capabilities = ["WaterSensor"];
}
if (nodetype.substring(0, 5) == "16.1.") {
pluginDevice.TileTemplate = "MotionSensorTile.xaml";
pluginDevice.DeviceType = "MotionSensor";
pluginDevice.Icon = "Sensor";
pluginDevice.Capabilities = ["MotionSensor"];
pluginDevice.Attributes = ["Status"];
}
if (nodetype.substring(0, 5) == "16.22") {
pluginDevice.TileTemplate = "MotionSensorTile.xaml";
pluginDevice.DeviceType = "MotionSensor";
pluginDevice.Icon = "Sensor";
pluginDevice.Capabilities = ["MotionSensor"];
pluginDevice.Attributes = ["Status", "BatteryPowered", "BatteryLevel", "Temperature", "Luminance"];
}
pluginDevice.Id = curadd;
//pluginDevice.Name = nodename;
pluginDevice.DisplayName = nodename;
pluginDevice.Icon = "Sensor";
pluginDevice.DetailsTemplate = "";
if (curadd.substring(curadd.length - 1, curadd.length) == "3") {
pluginDevice.TileTemplate = "";
pluginDevice.DeviceType = "LowBattery";
pluginDevice.Icon = "BatteryUnknown";
pluginDevice.Capabilities = ["Battery"];
}
if (curadd.substring(curadd.length - 1, curadd.length) == "4") {
pluginDevice.TileTemplate = "";
pluginDevice.DeviceType = "Heartbeat";
pluginDevice.Icon = "Heart";
pluginDevice.Capabilities = ["PresenceSensor"];
}
plugin.Devices[pluginDevice.Id] = pluginDevice;
break;
default:
var pluginDevice = new Device();
pluginDevice.Id = curadd;
pluginDevice.DisplayName = "Unknown_" +nodename;
pluginDevice.Icon = "More";
pluginDevice.DeviceType = "";
pluginDevice.TileTemplate = "";
pluginDevice.DetailsTemplate = "";
pluginDevice.Capabilities = ["Switch"];
pluginDevice.Attributes = [];
plugin.Devices[pluginDevice.Id] = pluginDevice;
}
}
}
});
} catch (err) {
var pluginDevice = new Device();
pluginDevice.Id = curadd;
pluginDevice.DisplayName = "Error_" +nodename;
pluginDevice.Icon = "More";
pluginDevice.DeviceType = "";
pluginDevice.TileTemplate = "";
pluginDevice.DetailsTemplate = "";
pluginDevice.Capabilities = ["Switch"];
pluginDevice.Attributes = [];
plugin.Devices[pluginDevice.Id] = pluginDevice;
}
//Check if Programs are enabled if so begin importing
if (plugin.Settings["EnablePrograms"] == "Yes" || plugin.Settings["EnablePrograms"] == "YES") {
var r = http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + "/rest/programs?subfolders=true", config); //get list of all scenes
var data = r.data;
var r = http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + "/rest/programs?subfolders=true", config); //get list of all scenes
var data = r.data;
var programElement = XML.parse(data);
programElement.elements.forEach(function (program) {
var curid = program.attributes.id;
var IsFolder = program.attributes.folder;
var programname = "";
program.elements.forEach(function (element) {
switch (element.name) {
case "name":
programname = element.text;
break;
default:
}
});
var pluginDevice = new Device();
pluginDevice.Id = curid;
//pluginDevice.Name = "Program_" + programname;
if (IsFolder== "true") {
pluginDevice.DisplayName = "ProgramFolder_" +programname;
pluginDevice.Icon = "PC";
pluginDevice.DeviceType = "ISYProgramFolder";
pluginDevice.TileTemplate = "ISYProgramFolderTile.xaml";
pluginDevice.DetailsTemplate = "";
pluginDevice.Capabilities = [];
pluginDevice.Attributes = ["PCommand","PStatus","ParentId","PFolder", "PEnabled","Running", "lastRunTime", "lastFinishTime", "nextScheduledRunTime"]; // Set this to any of these options run, runThen, runElse, stop, enable, disable, enableRunAtStartup, disableRunAtStartup
} else {
pluginDevice.DisplayName = "Program_" +programname;
pluginDevice.Icon = "PC";
pluginDevice.DeviceType = "ISYProgram";
pluginDevice.TileTemplate = "ISYProgramTile.xaml";
pluginDevice.DetailsTemplate = "";
pluginDevice.Capabilities = [];
pluginDevice.Attributes = ["PCommand","PStatus","ParentId","PFolder", "PEnabled","Running", "lastRunTime", "lastFinishTime", "nextScheduledRunTime"]; // Set this to any of these options run, runThen, runElse, stop, enable, disable, enableRunAtStartup, disableRunAtStartup
}
plugin.Devices[pluginDevice.Id] = pluginDevice;
});
}
/*
var r = http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + "/rest/nodes/folders", config); //get list of all Lighting Folders
//get list of all folders
var data = r.data;
while (data.length > 1) {
if (data.indexOf(" -1 && data.indexOf("/folder>") > -1) {
var curfolder = data.substring(data.indexOf("") + 8);
var curfoladd = curfolder.substring(curfolder.indexOf("") + 9, curfolder.indexOf(""));
var foldername = curfolder.substring(curfolder.indexOf("") + 6, curfolder.indexOf(""));
var pluginDevice = new Device();
pluginDevice.Id = curfoladd;
//pluginDevice.Name = "Folder_" + foldername;
pluginDevice.DisplayName = "Folder_" + foldername;
pluginDevice.Icon = "folder";
pluginDevice.DeviceType = "Folder";
pluginDevice.TileTemplate = "FolderTile.xaml";
pluginDevice.DetailsTemplate = "FolderDetailsTile.xaml";
pluginDevice.Capabilities = [];
pluginDevice.Attributes = [""];
plugin.Devices[pluginDevice.Id] = pluginDevice;
data = data.substring(data.indexOf("/folder>") + 8, data.length);
} else {
data = "";
}
} */
//Check if Variables are enabled if so begin importing integer variables
if (plugin.Settings["EnableIntegerVariables"] == "Yes" || plugin.Settings["EnableIntegerVariables"] == "YES") {
var r = http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + "/rest/vars/definitions/1", config); //get list of all integer variables
var data = r.data;
var varElement = XML.parse(data);
if (varElement.elements!=null) {
varElement.elements.forEach(function (node) {
var curid = node.attributes.id;
var varname = node.attributes.name;
var pluginDevice = new Device();
pluginDevice.Id = "ISYInteger" + curid;
//pluginDevice.Name = "ISYInteger_" + varname;
pluginDevice.DisplayName = "ISYInteger_" +varname;
pluginDevice.Icon = "Globe";
pluginDevice.DeviceType = "ISYIntegerVariable";
pluginDevice.TileTemplate = "ISYIntegerVariableTile.xaml";
pluginDevice.DetailsTemplate = "";
pluginDevice.Capabilities = [];
pluginDevice.Attributes = ["ISYIntegerValue", "timeSet"];
plugin.Devices[pluginDevice.Id] = pluginDevice;
});
} else {log("No Integer Variables!");}
}
if (plugin.Settings["EnableStateVariables"] == "Yes" || plugin.Settings["EnableStateVariables"] == "YES") {
var r = http.get("http://" + plugin.Settings["HostName"] + ":" + plugin.Settings["IsyPort"] + "/rest/vars/definitions/2", config); //get list of all state(0 or 1) variables
var data = r.data;
var varElement = XML.parse(data);
if (varElement.elements!=null) {
varElement.elements.forEach(function (node) {
var curid = node.attributes.id;
var varname = node.attributes.name;
var pluginDevice = new Device();
pluginDevice.Id = "ISYState" + curid;
//pluginDevice.Name = "ISYState_" + varname;
pluginDevice.DisplayName = "ISYState_" + varname;
pluginDevice.Icon = "Globe";
pluginDevice.DeviceType = "ISYStateVariable";
pluginDevice.TileTemplate = "ISYStateVariableTile.xaml";
pluginDevice.DetailsTemplate = "";
pluginDevice.Capabilities = [];
pluginDevice.Attributes = ["ISYStateValue", "timeSet"];
plugin.Devices[pluginDevice.Id] = pluginDevice;
});
} else {log("No State Variables!");}
}
// plugin.Devices = pluginDevices; //add all new devices to the plugin
}