plugin.Name = "Vera.Datamine"; plugin.OnChangeRequest = onChangeRequest; plugin.OnConnect = onConnect; plugin.OnDisconnect = onDisconnect; plugin.OnPoll = onPoll; plugin.OnSynchronizeDevices = onSynchronizeDevices; plugin.PollingInterval = 10000; plugin.DefaultSettings = { "Username": "", "Password": "", "SerialNumber": "", "Host": ""}; var VERSION = "beta-1.0"; var http = new HTTPClient(); var params = { vera_login: "", vera_password: "", vera_PKDevice: "", vera_deviceserver: "", vera_relayserver: "", vera_localIP: "", vera_identity: null, vera_identitysign: null, veraMMSSession_Relay: "", vera_shouldUpdateFWServer : true, pref_conn_connection : "", uniqueId : "", vera_refresh : "", vera_discoveredUnits : [], vera_datamine : null, vera_DM_channelList:[] }; function onChangeRequest(device, attribute, value) { var stoptime= Math.floor(Date.now()/1000); if (myIsRemote()) { updateFwServer(); } //console.log("Id: " + device.Id + " Plot Range: "+ attribute + "Value: "+ value); var starttime; switch (attribute) { case ("plotRange"): if (value != "Refresh") { plugin.Devices[device.Id].plotRange = value; } generateGraph(device.Id, plugin.Devices[device.Id].plotRange); //console.log("Id: " + device.Id + " Plot Range: "+ plugin.Devices[device.Id].plotRange); break; default: break; } } function onConnect() { // Assign credentials for plugin var response=null; params.vera_login = plugin.Settings["Username"]; params.vera_password = plugin.Settings["Password"]; params.vera_PKDevice = plugin.Settings["SerialNumber"]; params.vera_localIP = plugin.Settings["Host"]; // Check local / remote connection if (myIsRemote()) { var response = discoverVeraUnits(params); if (!response.status) { console.log(response.message); return; } console.log(response.message); // console.log("Discovered 1: "+JSON.stringify(params)); response = validateVeraUnitIp(); if (!response.status) { console.log(response.message); return; } console.log(response.message); // console.log("Discovered 2: "+JSON.stringify(params)); } response = validateVeraUnit(); if (!response.status) { console.log(response.message); return; } console.log(response.message); // console.log("Discovered: "+JSON.stringify(params)); params.vera_shouldUpdateFWServer = false; //updateFwServer(); //Initialize all Datamine channels available in plugin var veraDM = getDataMine(true); var device; for (var i in veraDM) { if (plugin.Devices[veraDM[i].Id] != null) { device = plugin.Devices[veraDM[i].Id]; device.plotRange = "Week"; device.DeviceType = getDeviceType(veraDM[i].Service); device.channelVariable = veraDM[i].Variable; device.channelName = veraDM[i].Name; device.channelUnits = veraDM[i].Units; //console.log(i + ": Init Id:"+veraDM[i].Id+" Attr:" + device.channelVariable +" - "+ device.Name + " - "+ device.plotRange + " - " +device.channelName +" - " + device.DeviceType + " - " + device.channelUnits); } } } function onDisconnect() { console.log("disconnected"); } function onPoll() { if (myIsRemote()) { CheckUserUpdateSession(); updateFwServer(); } console.log("Datamine polling. Session update: "+params.vera_shouldUpdateFWServer); Object.keys(plugin.Devices).forEach(function(key) { if (plugin.Devices[key].HasSubscribers()) { console.log("Device" +key +": "+ plugin.Devices[key].plotRange); generateGraph(key, plugin.Devices[key].plotRange); } }) } function onSynchronizeDevices() { var veraDataMine = getDataMine(true); console.log("Json: "+ JSON.stringify(veraDataMine)); var dmDevice = new Device(); var attributes = []; for ( var i in veraDataMine) { console.log("ID: " + veraDataMine[i].Id + " Loggas: " +veraDataMine[i].Logging); if (veraDataMine[i].Logging =="1") { console.log(" Channel:" + veraDataMine[i].Id +" - " +veraDataMine[i].Name +" - " +veraDataMine[i].Device+" - "+ veraDataMine[i].Variable +" - "+ veraDataMine[i].Service +" - " +veraDataMine[i].Units); dmDevice = new Device(); dmDevice.DisplayName = "Plot"+veraDataMine[i].Name; dmDevice.DeviceType = getDeviceType(veraDataMine[i].Service); dmDevice.Id = veraDataMine[i].Id; dmDevice.DeviceId = veraDataMine[i].Device; dmDevice.Attributes = ["Url","Out","channelName","channelVariable","channelUnits","plotRange"]; dmDevice.Out ="For HTML binding"; dmDevice.Icon = "lineGraph.png"; dmDevice.TileTemplate = "GraphTile.xaml"; dmDevice.DetailsTemplate = "GraphDetails.xaml"; dmDevice.channelVariable = veraDataMine[i].Variable; dmDevice.channelUnits = veraDataMine[i].Units; dmDevice.channelName = veraDataMine[i].Name; dmDevice.plotRange= "Week"; plugin.Devices[dmDevice.Id] = dmDevice; } } Object.keys(veraDataMine).forEach(function(Id) { console.log("Id: " + Id ); }); } // Vera Datamine specific code part var Base64 = { // private property _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", // public method for encoding encode : function (input) { var output = ""; var chr1, chr2, chr3, enc1, enc2, enc3, enc4; var i = 0; input = Base64._utf8_encode(input); while (i < input.length) { chr1 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++); enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output = output + this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4); } return output; }, // public method for decoding decode : function (input) { var output = ""; var chr1, chr2, chr3; var enc1, enc2, enc3, enc4; var i = 0; input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); while (i < input.length) { enc1 = this._keyStr.indexOf(input.charAt(i++)); enc2 = this._keyStr.indexOf(input.charAt(i++)); enc3 = this._keyStr.indexOf(input.charAt(i++)); enc4 = this._keyStr.indexOf(input.charAt(i++)); chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4; output = output + String.fromCharCode(chr1); if (enc3 != 64) { output = output + String.fromCharCode(chr2); } if (enc4 != 64) { output = output + String.fromCharCode(chr3); } } output = Base64._utf8_decode(output); return output; }, // private method for UTF-8 encoding _utf8_encode : function (string) { string = string.replace(/\r\n/g,"\n"); var utftext = ""; for (var n = 0; n < string.length; n++) { var c = string.charCodeAt(n); if (c < 128) { utftext += String.fromCharCode(c); } else if((c > 127) && (c < 2048)) { utftext += String.fromCharCode((c >> 6) | 192); utftext += String.fromCharCode((c & 63) | 128); } else { utftext += String.fromCharCode((c >> 12) | 224); utftext += String.fromCharCode(((c >> 6) & 63) | 128); utftext += String.fromCharCode((c & 63) | 128); } } return utftext; }, // private method for UTF-8 decoding _utf8_decode : function (utftext) { var string = ""; var i = 0; var c = c1 = c2 = 0; while ( i < utftext.length ) { c = utftext.charCodeAt(i); if (c < 128) { string += String.fromCharCode(c); i++; } else if((c > 191) && (c < 224)) { c2 = utftext.charCodeAt(i+1); string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); i += 2; } else { c2 = utftext.charCodeAt(i+1); c3 = utftext.charCodeAt(i+2); string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); i += 3; } } return string; } } function CheckUserUpdateSession() { //var updateSession = true; var url = remoteGenUrl("data_request?id=lr_dmList&output_format=json"); console.log("URL" + url); try { var response = http.get(url); } catch (error) { var errorResponse = error.response; if (error.status == 304) { console.log("304 code received"); } } // console.log("Resp.data" + JSON.stringify(response.data)); // console.log("Resp.status" + response.status); if (response.status = 200) { params.vera_shouldUpdateFWServer = false; return; } params.vera_shouldUpdateFWServer = true; return; } function updateFwServer() { if (params.vera_shouldUpdateFwServer || params.veraMMSSession_Relay === "") { // Make authentication. Select server { "us-autha11.mios.com" , "vera-us-oem-autha11.mios.com" ) var myauth = getUserAuth(params.vera_login.toLowerCase(), params.vera_password, "vera-us-oem-autha.mios.com"); if (myauth == null) { console.log("Error : could not login while refreshing FwServer"); return false; } /* console.log("Auth: "+ JSON.stringify(myauth)); console.log("Account: "+ myauth.Server_Account); console.log("Identity: "+ myauth.Identity); console.log("IdentitySignature: "+ myauth.IdentitySignature);*/ params.vera_identity = myauth.Identity; params.vera_identitysign = myauth.IdentitySignature; // Get initial AuthMMS var mmssession = getMMSSession(myauth.Server_Account, myauth.Identity, myauth.IdentitySignature); if (mmssession == null) { console.log("Error: Could not get MMS Session while refreshing FwServer"); return false; } // Get vera units list var veraUnits = getVeraUnits(myauth, mmssession); if (veraUnits == null) { console.log("Error : could not get units list while refreshing FwServer"); return false; } console.log("Units: "+ JSON.stringify(veraUnits)); var devserver = ""; for (var i in veraUnits) { console.log(veraUnits[i].PK_Device + " - " + veraUnits[i].Server_Device); if (veraUnits[i].PK_Device == params.vera_PKDevice) { devserver = veraUnits[i].Server_Device; } } // Get device server if (devserver != "") { params.vera_deviceserver = devserver; } else { devserver = params.vera_deviceserver; } // console.log("Dev Server: " + veraUnits[i].Server_Device); var dev_mmssession = getMMSSession(devserver, myauth.Identity, myauth.IdentitySignature); if (dev_mmssession == null) { console.log("Error : could not get devmms session while refreshing FwServer"); return false; } // Get this device's Relay Server var relayserver = ""; var unitDetails = getVeraDetails(devserver, params.vera_PKDevice, dev_mmssession); console.log("Details: "+ unitDetails); console.log("Details: "+ JSON.stringify(unitDetails)); if (unitDetails == null) { console. log("Error : could not get unit details while refreshing FwServer"); relayserver = params.vera_relayserver; return false; } else { relayserver = unitDetails.Server_Relay; params.vera_relayserver = relayserver; params.vera_localIP= unitDetails.InternalIP; console.log("Local IP: "+ params.vera_localIP); console.log("Server Relay: "+ params.vera_relayserver); } console.log("Relay Server: " + relayserver); // Get Relay MMS var relay_mmssession = getMMSSession(relayserver, myauth.Identity, myauth.IdentitySignature); if (relay_mmssession == null) { console.log("Error : could not get relayMSS session while refreshing FwServer"); } else { params.veraMMSSession_Relay = relay_mmssession; //params.vera_shouldUpdateFwServer = false; console.log("Refreshed Servers successfully ! " + params.veraMMSSession_Relay ); return true; } return false; } } function discoverVeraUnits() { var fret = {}; console.log("Validating configuration... "); if (Object.keys(params).length >= 2) { // Get authentication object var myauth = getUserAuth(params.vera_login.toLowerCase(), params.vera_password, "vera-us-oem-autha.mios.com"); if (myauth == null) { fret.status = false; fret.message = "Invalid credentials"; return fret; } // Get MMS Session token var mmssession = getMMSSession(myauth.Server_Account, myauth.Identity, myauth.IdentitySignature); if (mmssession == null) { fret.status = false; fret.message = "Could not get MMS Session"; return fret; } // Get units list var veraUnits = getVeraUnits(myauth, mmssession); if (veraUnits == null || veraUnits.count <= 0) { fret.status = false; fret.message = "Could not find any vera unit associated with your account"; return fret; } params.vera_identity = myauth.Identity; params.vera_identitysign = myauth.IdentitySignature; params.vera_discoveredUnits = JSON.stringify(veraUnits); fret.status = true; //console.log("FRET: "+ params.vera_discoveredUnits); fret.message = "Found unit(s). Select :" +params.vera_discoveredUnits ; return fret; } else { // Manual params.vera_identity = ""; params.vera_identitysign = ""; params.discoveredUnits = JSON.stringify([]); fret.status = true; fret.message = "No unit found"; return fret; } } function validateVeraUnitIp() { var fret = {}; //console.log("Validating units " + JSON.stringify(params.vera_discoveredUnits)); if (params.vera_PKDevice == "0") { // Manual config ==> OK fret.status = true; fret.message = "Manual Config"; return fret; } var discUnits = JSON.parse(params.vera_discoveredUnits); for (idx in discUnits) { var myUnit = discUnits[idx]; if (myUnit.PK_Device === params.vera_PKDevice) { // Get this device's Relay Server var dev_mmssession = getMMSSession(myUnit.Server_Device, params.vera_identity, params.vera_identitysign); var unitdetails = getVeraDetails(myUnit.Server_Device, myUnit.PK_Device, dev_mmssession); params.vera_relayserver = unitdetails.Server_Relay; if (unitdetails.InternalIP.length > 0) { params.vera_ip = unitdetails.InternalIP; } params.uniqueId = myUnit.PK_Device; params.vera_deviceserver = myUnit.Server_Device; //params.vera_identity = myUnit.vera_identity; //params.vera_identitysign = myUnit.vera_identitysign; /* retobj.pref_activated = (("pref_activated" in devObj) ? devObj.pref_activated : true); retobj.vera_shownoroom = (("vera_shownoroom" in devObj) ? devObj.vera_shownoroom : true); retobj.vera_refresh = (("vera_refresh" in devObj) ? devObj.vera_refresh : "5000"); retobj.pref_conn_connection = (("pref_conn_connection" in devObj) ? devObj.pref_conn_connection : "AUTO");*/ // OK fret.status = true; fret.message = "Datamine unit configured successfully !"; return fret; } } fret.status = false; fret.message = "Error during unit discovery"; return fret; } function validateVeraUnit() { var fret = {}; var rettest = null; if (params.vera_PKDevice == "0") { // Manual config IP rettest = localGetRequest("data_request?id=user_data2", params.vera_localIP); params.vera_deviceserver = ""; params.vera_identity = ""; params.vera_identitysign = ""; } console.log("Validating unit " + params.vera_PKDevice); // Make a test request if (params.vera_identitysign && params.vera_identity != "") { // Standard : remote mode test // Create mms ession on relay server veraMMSSession_Relay = getMMSSession(params.vera_relayserver, params.vera_identity, params.vera_identitysign); params.veraMMSSession_Relay = veraMMSSession_Relay; // Get userdata rettest = remoteGetRequest("data_request?id=user_data2", params.vera_PKDevice, params.vera_relayserver, veraMMSSession_Relay); } else { // Local only mode rettest = localGetRequest("data_request?id=user_data2", params.vera_localIP); } if (rettest != null) { try { var dataobj = JSON.parse(JSON.stringify(rettest.data)); // Test if unit is an Vera one if (!dataobj.skin || dataobj.skin != "mios") { fret.status = "error"; fret.message = _("Error connecting : your unit is not a genuine Vera"); return fret; } if ('PK_AccessPoint' in dataobj) { // OK params.uniqueId = dataobj.PK_AccessPoint; //console.log("JSON:" + JSON.stringify(dataobj.skin) +" - " + JSON.stringify(dataobj.PK_AccessPoint)); //retobj.pref_activated = (("pref_activated" in params) ? params.pref_activated : true); //retobj.vera_shownoroom = (("vera_shownoroom" in params) ? params.vera_shownoroom : true); params.vera_refresh = (("vera_refresh" in params) ? params.vera_refresh : "5000"); params.pref_conn_connection = (("pref_conn_connection" in params) ? params.pref_conn_connection : "AUTO"); // OK params.vera_shouldUpdateFwServer = false; fret.status = true; fret.message = "Vera Datamine unit configured successfully !"; return fret; } } catch (e) { console.log("Error reading json data : " + JSON.stringify(rettest)); fret.status = false; fret.message = "Error connecting : please check your credentials"; return fret; } } fret.status = false; fret.message = "Error during unit discovery"; return fret; } function getUserAuth(login, password, server) { var sha1pass = sha1(login.toLowerCase() + password + "oZ7QE6LcLJp6fiWzdqZc"); var url = "https://" + server + "/autha/auth/username/" + encodeURI(login) + "?SHA1Password=" + sha1pass + "&PK_Oem=1"; var resp = http.get(url, { timeout: 60000 }); var retobj; try { retobj = JSON.parse(JSON.stringify(resp.data)); } catch (e) { console.log("Error : invalid credential format (" + e.message+" : "+resp.data + ")"); return null; } if (!("Identity" in retobj)) { console.log("Error : invalid credential content (" + resp.data + ")"); return null; } // All is ok : return auth obj return retobj; } function getMMSSession(server, identity, signature) { var url = "https://" + server + "/info/session/token"; var resp = http.get(url, {headers: {"MMSAuth": identity , "MMSAuthSig": signature }, timeout: 60000}); if (resp.data.length == 38) { return resp.data; } return null; } function getVeraUnits(authObj, mmssession) { var identity = decodeIdentity(authObj.Identity); var url = "https://" + authObj.Server_Account + "/account/account/account/" + identity.PK_Account + "/devices" var resp = http.get(url, {headers:{ "MMSSession": mmssession}, timeout:60000}); try { console.log("Got VERA Unit : " + JSON.stringify(resp.data)); var obj = JSON.parse(JSON.stringify(resp.data)); return obj.Devices; } catch (e) { console.log("Error decoding units list : " +e.message +" - "+ resp); } return null; } function getVeraDetails(devserver, pkdevice, mmssession) { var url = "https://" + devserver + "/device/device/device/" + pkdevice; var resp = http.get(url, {headers:{ "MMSSession": mmssession}, timeout:60000}); try { console.log("GOT VERA Details : " + JSON.stringify(resp.data)); return JSON.parse(JSON.stringify(resp.data)); } catch (e) { console.log("Error : could not parse unitDetails : " + e.message + " - "+ resp.data); } return null; } function getDataMine(forcereload) { var resp = null; if (!forcereload) { // Try to get from cached preferences resp = params.vera_datamine; console.log("Datamine : Trying to get from cached prefs"); } if (typeof resp == 'undefined' || resp == null) { console.log("Refreshing datamine because undefined (force=" + forcereload + ")"); resp = veraGetRequest("data_request?id=lr_dmList&output_format=json"); } // Parse json try { veraDataMine = JSON.parse(JSON.stringify(resp.data)); } catch (e) { resp = "[]"; console.log("Error parsing datamine data :" + resp); console.log("Could not retrieve data " + e); } // Save datamine to pref params.vera_datamine= resp; return veraDataMine; } function validateIPaddress(ipaddress) { var ipformat = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; if (ipaddress.match(ipformat)) { return (true) } return (false) } function myIsRemote() { //if (typeof params.vera_localIP == 'undefined' || params.vera_localIP == null) { if (validateIPaddress(params.vera_localIP)) { console.log("Local IP: "+validateIPaddress(params.vera_localIP)+" - "+params.vera_localIP); return false; } else { return true; } } function veraGetRequest(url) { var url; if (myIsRemote()) { var relayserver = params.vera_relayserver; var veraPKDevice = params.vera_PKDevice; var relaySession = params.veraMMSSession_Relay; return remoteGetRequest(url,veraPKDevice, relayserver, relaySession); } else { var ip = params.vera_localIP; return localGetRequest(url, ip); } } function localGetRequest(url, ip) { var myurl = "http://" + ip + ":3480/" + url; console.log("Calling LOCAL: " + myurl); return http.get(myurl); } function remoteGetRequest(url, veraPKDevice, relayserver, MMSSession) { var myurl = "https://" + relayserver + "/relay/relay/relay/device/" + veraPKDevice + "/session/" + MMSSession + "/port_3480/" + url; console.log("Calling REMOTE: " + myurl); try { var response = http.get( myurl, {headers:{ "Connection": "keep-alive"}, timeout:10000}); } catch (error) { var errorResponse = error.response; if (error.status == 304) { console.log("304 code received"); } } //var resp = http.get(myurl, {headers:{ "MMSSession": params.veraMMSSession_Relay}, timeout:60000}); return response; } function remoteGenUrl(url) { var relayserver = params.vera_relayserver; var veraPKDevice = params.vera_PKDevice; return "https://" + relayserver + "/relay/relay/relay/device/" + veraPKDevice + "/session/" + params.veraMMSSession_Relay + "/port_3480/" + url; } function decodeIdentity(identity) { var txt = Base64.decode(identity); console.log("DECODED TEXT : " + txt); var ret; try { ret = JSON.parse(txt); } catch (e) { console.log("Error : Could not decode identity"); return null; } return ret; } function getDeviceType(urn) { var devType=""; switch (urn){ case "urn:upnp-org:serviceId:TemperatureSensor1": return "TemperatureSensor"; break; case "urn:micasaverde-com:serviceId:HumiditySensor1": return "HumiditySensor"; break; case "urn:micasaverde-com:serviceId:LightSensor1": return "LightSensor"; break; case "urn:micasaverde-com:serviceId:EnergyMetering1": return "EnergyMetering"; break; case "urn:micasaverde-com:serviceId:HVAC_OperatingState1": return "Thermostat"; break; case "urn:upnp-org:serviceId:HVAC_UserOperatingMode1": return "Thermostat"; break; default: return ""; break; } } function generateGraph(identity, plotRange) { var device = plugin.Devices[identity]; var stoptime= Math.floor(Date.now()/1000); var starttime=stoptime - (7*24*60*60); var graphUrl = ""; var outHtml= "No plot assigned"; var lineData =""; var aggby = 0; var aggtype switch (plotRange){ case "Day": starttime=stoptime - (24*60*60); aggby=2;aggtype=1; break; case "Week": starttime=stoptime - (7*24*60*60); aggby=2;aggtype=1; break; case "Month": starttime=stoptime - (30*24*60*60); aggby=3;aggtype=1; break; case "3Month": starttime=stoptime - (3*30*24*60*60); aggby=4;aggtype=1; break; case "6Month": starttime=stoptime - (6*30*24*60*60); aggby=4;aggtype=1; break; case "Year": starttime=stoptime - (365*24*60*60); aggby=5;aggtype=1; break; default: starttime=stoptime - (7*24*60*60); aggby=0;aggtype=0; break; } switch (device.channelVariable) { case "CurrentTemperature": switch (identity) { case "15": lineData = veraGetRequest( "data_request?id=lr_dmGoogle&start="+starttime+"&stop="+stoptime+"&channel1=15&channel2=36&channel3=39&channel4=22" ); outHtml = linePlot(lineData.data,device.DisplayName, "Temperatur",device.channelUnits); break; case "29": lineData = veraGetRequest("data_request?id=lr_dmGoogle&start="+starttime+"&stop="+stoptime+"&channel1=29&channel2=33"); outHtml = linePlot(lineData.data,device.DisplayName, "Temperatur",device.channelUnits); break; case "26": lineData = veraGetRequest("data_request?id=lr_dmGoogle&start="+starttime+"&stop="+stoptime+"&channel1=26&channel2=27"); outHtml = linePlot(lineData.data,device.DisplayName, "Temperatur",device.channelUnits); break; default: lineData = veraGetRequest("data_request?id=lr_dmGoogle&start="+starttime+"&stop="+stoptime+"&channel1="+identity); outHtml = linePlot(lineData.data,device.DisplayName, "Temperatur",device.channelUnits); break; } break; case "Watts": switch (identity) { case "7": lineData = veraGetRequest("data_request?id=lr_dmGoogle&start="+starttime+"&stop="+stoptime+"&channel1=7&channel2=19"); break; default: lineData = veraGetRequest("data_request?id=lr_dmGoogle&start="+starttime+"&stop="+stoptime+"&channel1="+identity); break; } outHtml = stepLinePlot(lineData.data, device.DisplayName, "Effekt",device.channelUnits); break; case "KWH": switch (identity) { case "46": lineData = veraGetRequest("data_request?id=lr_dmGoogle&start="+starttime+"&stop="+stoptime+"&channel1=46&aggby1="+aggby+"&aggtype1="+aggtype+"&channel2=47&aggby2="+aggby+"&aggtype2="+aggtype+"&channel3=48&aggby3="+aggby+"&aggtype3="+aggtype+"&channel4=14&aggby4="+aggby+"&aggtype4="+aggtype+"&channel5=65&aggby5="+aggby+"&aggtype5="+aggtype); outHtml = columnPlot(lineData.data, device.DisplayName,"Effekt", device.channelUnits ); break; default: lineData = veraGetRequest("data_request?id=lr_dmGoogle&start="+starttime+"&stop="+stoptime+"&channel1="+identity+"&aggby1="+aggby+"&aggtype1="+aggtype); outHtml = columnPlot(lineData.data, device.DisplayName, "Effekt",device.channelUnits ); break; } break; case "Volts": lineData = veraGetRequest("data_request?id=lr_dmGoogle&start="+starttime+"&stop="+stoptime+"&channel1="+identity+"&channel2=21"); outHtml = linePlot(lineData.data, device.DisplayName, "Spänning", device.channelUnits); break; case "CurrentLevel": switch (device.DeviceType) { case "HumiditySensor": lineData = veraGetRequest("data_request?id=lr_dmGoogle&start="+starttime+"&stop="+stoptime+"&channel1="+identity); outHtml = linePlot(lineData.data, device.DisplayName,"Fuktighet", device.channelUnits); break; case "LightSensor": lineData = veraGetRequest("data_request?id=lr_dmGoogle&start="+starttime+"&stop="+stoptime+"&channel1="+identity); outHtml = stepLinePlot(lineData.data, device.DisplayName,"Ljusstyrka", device.channelUnits); break; default: outHtml = device.DeviceType+": Ej bundet plot kanal"; break; } break; case "ModeState": lineData = veraGetRequest("data_request?id=lr_dmGoogle&start="+starttime+"&stop="+stoptime+"&channel1="+identity); outHtml = stepLinePlot(lineData.data, device.DisplayName,"Mode", device.channelUnits); break; default: outHtml = "Ej bunden plot kanal"; break; } device.Out = outHtml; } function stepLinePlot(dataTable,name, yaxis, units) { var outbuffer = ''; outbuffer+='
'; outbuffer+=' '; outbuffer+=' '; outbuffer+=' '; outbuffer+=' '; outbuffer+=''; return outbuffer; } function columnPlot(dataTable, name, yaxis,units) { var outbuffer = ''; outbuffer+=' '; outbuffer+=' '; outbuffer+=' '; outbuffer+=' '; outbuffer+=' '; outbuffer+=''; return outbuffer; } function linePlot(dataTable, name, yaxis, units) { var outbuffer = ''; outbuffer+=' '; outbuffer+=' '; outbuffer+=' '; outbuffer+=' '; outbuffer+=' '; outbuffer+=''; return outbuffer; } function comboPlot(dataTable,name) { var outbuffer = ''; outbuffer+=' '; outbuffer+=' '; outbuffer+=' '; outbuffer+=' '; outbuffer+=' '; outbuffer+=''; return outbuffer; }