- Location:
- /trunk
- Files:
-
- 4 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
/trunk/L_VeraConnectWWN1.lua
r20 r30 11 11 local DEVICE_FILES = { 12 12 TEMPERATURE_SENSOR = "D_TemperatureSensor1.xml", 13 THERMOSTAT = "D_ HVAC_ZoneThermostat1.xml",13 THERMOSTAT = "D_VeraConnectWWNThermostat1.xml", 14 14 HUMIDITY = "D_HumiditySensor1.xml", 15 15 SMOKE_SENSOR = "D_SmokeSensor1.xml", 16 BINARY_LIGHT = "D_BinaryLight1.xml" 16 BINARY_LIGHT = "D_BinaryLight1.xml", 17 NEST_STRUCTURE = "D_VeraConnectWWNStructure1.xml" 17 18 } 18 19 local DEVICE_TYPES = { … … 21 22 HUMIDITY = "urn:schemas-micasaverde-com:device:HumiditySensor:1", 22 23 SMOKE_SENSOR = "urn:schemas-micasaverde-com:device:SmokeSensor:1", 23 BINARY_LIGHT = "urn:schemas-upnp-org:device:BinaryLight:1" 24 BINARY_LIGHT = "urn:schemas-upnp-org:device:BinaryLight:1", 25 NEST_STRUCTURE = "urn:schemas-micasaverde-com:device:VeraConnectWWNStructure:1" 24 26 } 25 27 local SID = { … … 28 30 TEMP = "urn:upnp-org:serviceId:TemperatureSensor1", 29 31 HVAC_UOM = "urn:upnp-org:serviceId:HVAC_UserOperatingMode1", 30 HVAC_OS = "urn: micasaverde-com:serviceId:HVAC_OperatingState1",32 HVAC_OS = "urn:upnp-org:serviceId:HVAC_OperatingState1", 31 33 HVAC_FOM = "urn:upnp-org:serviceId:HVAC_FanOperatingMode1", 32 34 HVAC_HEAT = "urn:upnp-org:serviceId:TemperatureSetpoint1_Heat", … … 45 47 -- LastUpdate 46 48 local DISPLAY_SECONDS = 20 47 local POLLING_RATE = 1 -- 30 --"PollFrequency"49 local POLLING_RATE = 10 --"PollFrequency" 48 50 -- Globals 49 51 local lug_device = nil … … 105 107 local function getTemperatureScale() 106 108 local code, data = luup.inet.wget("http://localhost:3480/data_request?id=lu_sdata") 107 if (code == 0) then 108 data = dkjson.decode(data) 109 end 110 temperatureScale = ((code == 0) and (data ~= nil) and (data.temperature ~= nil)) and string.lower(data.temperature) or "f" 109 if code == 0 then 110 temperatureScale = string.lower(data:match('"temperature":%s*"(%a)"')) or "f" 111 else 112 local code1, data1 = luup.inet.wget("http://127.0.0.1:3480/data_request?id=lu_sdata") 113 if code1 == 0 then 114 temperatureScale = string.lower(data1:match('"temperature":%s*"(%a)"')) or "f" 115 else 116 temperatureScale = "f" 117 end 118 end 111 119 end 112 120 … … 118 126 end 119 127 return 128 end 129 130 local function checkPackageUpdate() 131 local gw = {"Sercomm NA900", "Sercomm NA910", "MiCasaVerde VeraLite"} 132 local found 133 local flagFound = false 134 local stdout = io.popen("cat /proc/cpuinfo | awk '/machine/'") 135 local gwType = stdout:read("*a") 136 stdout:close() 137 for k,v in pairs(gw) do 138 found = gwType:find(v) 139 if found then 140 return true 141 end 142 end 143 return false 144 end 145 146 local function checkPackageVersion() 147 log("checkPackageVersion","Verifying... ") 148 local update = {} 149 local REQUIRED_VERSION = { '7', '3', '8', '0', '2'} 150 local stdout = io.popen("opkg list-installed | awk '/libcurl/ {print $3}'") 151 local version = stdout:read("*a") 152 version = version:match("([^%s]+)") 153 stdout:close() 154 local i = 1 155 for c in version:gmatch("[^.-]") do 156 if c < REQUIRED_VERSION[i] then 157 table.insert(update, "opkg install libcurl") 158 log("checkPackageVersion","libcurl library added to queue... ") 159 break 160 end 161 i = i + 1 162 end 163 REQUIRED_VERSION = { '7', '3', '8', '0', '2'} 164 stdout = io.popen("opkg list-installed | awk '/^curl/ {print $3}'") 165 version = stdout:read("*a") 166 version = version:match("([^%s]+)") 167 stdout:close() 168 i = 1 169 for c in version:gmatch("[^.-]") do 170 if c < REQUIRED_VERSION[i] then 171 table.insert(update, "opkg install curl") 172 log("checkPackageVersion","curl library added to queue...") 173 break 174 end 175 i = i + 1 176 end 177 REQUIRED_VERSION = { '1', '0', '1', 'l', '1'} 178 stdout = io.popen("opkg list-installed | awk '/libopenssl/ {print $3}'") 179 version = stdout:read("*a") 180 version = version:match("([^%s]+)") 181 stdout:close() 182 i = 1 183 for c in version:gmatch("[^.-]") do 184 if c < REQUIRED_VERSION[i] then 185 table.insert(update, "opkg install libopenssl") 186 log("checkPackageVersion","libopenssl library added to queue...") 187 break 188 end 189 i = i + 1 190 end 191 192 REQUIRED_VERSION = { '1', '0', '1', 'l', '1'} 193 stdout = io.popen("opkg list-installed | awk '/openssl-util/ {print $3}'") 194 version = stdout:read("*a") 195 version = version:match("([^%s]+)") 196 stdout:close() 197 i = 1 198 for c in version:gmatch("[^.-]") do 199 if c < REQUIRED_VERSION[i] then 200 table.insert(update, "opkg install openssl-util") 201 log("checkPackageVersion","openssl-util library added to queue...") 202 break 203 end 204 i = i + 1 205 end 206 207 if #update > 0 then 208 log("checkPackageVersion","Updating libraries...") 209 os.execute ("opkg update") 210 for k,v in pairs(update) do 211 os.execute (v) 212 end 213 end 214 log("checkPackageVersion","Packages OK!") 120 215 end 121 216 … … 129 224 local SetpointTarget = 0 130 225 local ModeStatus = "" 226 local ModeState = "" 131 227 local CurrentHumidity = 0 132 228 local EnergyModeStatus = "" 133 229 for key, value in pairs(g_thermostats) do 230 DeviceID = tonumber(value.vera_id) 134 231 CurrentTemperature = tostring(value["ambient_temperature_" .. temperatureScale]) 135 232 CurrentSetpoint = tostring(value["target_temperature_" .. temperatureScale]) … … 137 234 CurrentAutoSetPointCool = tostring(value["target_temperature_low_" .. temperatureScale]) 138 235 ModeStatus = tostring(value.hvac_mode) 236 ModeState = tostring(value.hvac_state) 139 237 CurrentHumidity = value.humidity 140 238 EnergyModeStatus = value.has_leaf … … 148 246 ModeStatus = "Off" 149 247 end 248 if ModeState == "heating" then 249 ModeState = "Heating" 250 elseif ModeState == "cooling" then 251 ModeState = "Cooling" 252 elseif ModeState == "off" then 253 ModeState = "Idle" 254 end 150 255 if EnergyModeStatus then 151 256 EnergyModeStatus = "EnergySavingsMode" … … 155 260 156 261 local AllSetpoints = CurrentSetpoint .. "," .. CurrentSetpoint .. ",0" 157 local ModeStatusUI = luup.variable_get("urn:upnp-org:serviceId:HVAC_UserOperatingMode1", "ModeStatus", tonumber(value.vera_id)) or "" 158 local CurrentSetpointUI = luup.variable_get("urn:upnp-org:serviceId:TemperatureSetpoint1", "CurrentSetpoint", tonumber(value.vera_id)) or "" 159 local CurrentTemperatureUI = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1", "CurrentTemperature", tonumber(value.vera_id)) or "" 160 local HumidityUI = luup.variable_get("urn:micasaverde-com:serviceId:HumiditySensor1", "CurrentLevel", tonumber(value.vera_id)) or "" 161 local EnergyModeStatusUI = luup.variable_get("urn:upnp-org:serviceId:HVAC_UserOperatingMode1", "EnergyModeStatus", tonumber(value.vera_id)) or "" 162 local CurrentAutoSetPointCoolUI = luup.variable_get(SID.NEST, "AutoSetPointCool", tonumber(value.vera_id)) or "" 163 local CurrentAutoSetPointHeatUI = luup.variable_get(SID.NEST, "AutoSetPointHeat", tonumber(value.vera_id)) or "" 262 local ModeStatusUI = luup.variable_get("urn:upnp-org:serviceId:HVAC_UserOperatingMode1", "ModeStatus", DeviceID) or "" 263 local ModeStateUI = luup.variable_get("urn:upnp-org:serviceId:HVAC_OperatingState1", "ModeState", DeviceID) or "" 264 local CurrentSetpointUI = luup.variable_get("urn:upnp-org:serviceId:TemperatureSetpoint1", "CurrentSetpoint", DeviceID) or "" 265 local CurrentTemperatureUI = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1", "CurrentTemperature", DeviceID) or "" 266 local HumidityUI = luup.variable_get("urn:micasaverde-com:serviceId:HumiditySensor1", "CurrentLevel", DeviceID) or "" 267 local EnergyModeStatusUI = luup.variable_get("urn:upnp-org:serviceId:HVAC_UserOperatingMode1", "EnergyModeStatus", DeviceID) or "" 268 local CurrentAutoSetPointCoolUI = luup.variable_get(SID.NEST, "AutoSetPointCool", DeviceID) or "" 269 local CurrentAutoSetPointHeatUI = luup.variable_get(SID.NEST, "AutoSetPointHeat", DeviceID) or "" 164 270 165 271 if ModeStatus ~= ModeStatusUI then 166 luup.variable_set("urn:upnp-org:serviceId:HVAC_UserOperatingMode1", "ModeStatus", ModeStatus, tonumber(value.vera_id)) 272 luup.variable_set("urn:upnp-org:serviceId:HVAC_UserOperatingMode1", "ModeStatus", ModeStatus, DeviceID) 273 end 274 if ModeState ~= ModeStateUI then 275 luup.variable_set("urn:upnp-org:serviceId:HVAC_OperatingState1", "ModeState", ModeState, DeviceID) 167 276 end 168 277 if CurrentSetpoint ~= CurrentSetpointUI then 169 luup.variable_set("urn:upnp-org:serviceId:TemperatureSetpoint1", "CurrentSetpoint", CurrentSetpoint, tonumber(value.vera_id))170 luup.variable_set("urn:upnp-org:serviceId:TemperatureSetpoint1", "AllSetpoints", AllSetpoints, tonumber(value.vera_id))171 luup.variable_set("urn:upnp-org:serviceId:TemperatureSetpoint1", "SetpointTarget", CurrentSetpoint, tonumber(value.vera_id))278 luup.variable_set("urn:upnp-org:serviceId:TemperatureSetpoint1", "CurrentSetpoint", CurrentSetpoint, DeviceID) 279 luup.variable_set("urn:upnp-org:serviceId:TemperatureSetpoint1", "AllSetpoints", AllSetpoints, DeviceID) 280 luup.variable_set("urn:upnp-org:serviceId:TemperatureSetpoint1", "SetpointTarget", CurrentSetpoint, DeviceID) 172 281 end 173 282 if CurrentTemperature ~= CurrentTemperatureUI then 174 luup.variable_set("urn:upnp-org:serviceId:TemperatureSensor1", "CurrentTemperature", CurrentTemperature, tonumber(value.vera_id))283 luup.variable_set("urn:upnp-org:serviceId:TemperatureSensor1", "CurrentTemperature", CurrentTemperature, DeviceID) 175 284 end 176 285 if tonumber(HumidityUI) ~= CurrentHumidity then … … 179 288 180 289 if EnergyModeStatus ~= EnergyModeStatusUI then 181 local EnergyModeStatusUI = luup.variable_set("urn:upnp-org:serviceId:HVAC_UserOperatingMode1", "EnergyModeStatus", EnergyModeStatus , tonumber(value.vera_id))182 local EnergyModeStatusUI = luup.variable_set("urn:upnp-org:serviceId:HVAC_UserOperatingMode1", "EnergyModeTarget", EnergyModeStatus , tonumber(value.vera_id))290 local EnergyModeStatusUI = luup.variable_set("urn:upnp-org:serviceId:HVAC_UserOperatingMode1", "EnergyModeStatus", EnergyModeStatus ,DeviceID) 291 local EnergyModeStatusUI = luup.variable_set("urn:upnp-org:serviceId:HVAC_UserOperatingMode1", "EnergyModeTarget", EnergyModeStatus ,DeviceID) 183 292 end 184 293 185 294 if CurrentAutoSetPointCool ~= CurrentAutoSetPointCoolUI then 186 luup.variable_set(SID.NEST, "AutoSetPointCool", CurrentAutoSetPointCool, tonumber(value.vera_id))295 luup.variable_set(SID.NEST, "AutoSetPointCool", CurrentAutoSetPointCool, DeviceID) 187 296 end 188 297 189 298 if CurrentAutoSetPointHeat ~= CurrentAutoSetPointHeatUI then 190 luup.variable_set(SID.NEST, "AutoSetPointHeat", CurrentAutoSetPointHeat, tonumber(value.vera_id))299 luup.variable_set(SID.NEST, "AutoSetPointHeat", CurrentAutoSetPointHeat, DeviceID) 191 300 end 192 301 … … 222 331 local function updateStructureValues() 223 332 debug("updateStructureValues","Verifying... ") 333 local Status = "" 224 334 for key, value in pairs(g_structures) do 225 local Status = value.away 226 if Status == "home" then 227 Status = "0" 228 elseif Status == "away" then 229 Status = "1" 230 end 231 local StatusUI = luup.variable_get(SID.SWP, "Status", value.vera_id) or "" 335 Status = value.away 336 local StatusUI = luup.variable_get(SID.NEST, "StructureHW", value.vera_id) or "" 232 337 if Status ~= StatusUI then 233 luup.variable_set(SID.SWP, "Status", Status, value.vera_id) 234 luup.variable_set(SID.SWP, "Target", Status, value.vera_id) 338 luup.variable_set(SID.NEST, "StructureHW", Status, value.vera_id) 235 339 end 236 340 end … … 285 389 local bbc = string.char(unpack(bb)) 286 390 local code = g_AUTHORIZATION_CODE 287 local URL = "curl -k -X POST 'https://api.home.nest.com/oauth2/access_token?client_id=" .. aac .. "&code=" .. code .. "&client_secret=".. bbc .. "&grant_type=authorization_code'"391 local URL = "curl -k -X POST -D /tmp/header.txt 'https://api.home.nest.com/oauth2/access_token?client_id=" .. aac .. "&code=" .. code .. "&client_secret=".. bbc .. "&grant_type=authorization_code'" 288 392 local stdout = io.popen(URL) 289 393 local response = stdout:read("*a") … … 295 399 debug("getNestToken", "error = " .. tostring(json_response.error)) 296 400 debug("getNestToken", "description = " .. tostring(json_response.error_description)) 401 if tostring(json_response.error) == "oauth2_error" or tostring(json_response.error) == "client_not_active" or tostring(json_response.error) == "input_error" then 402 luup.variable_set(SID.NEST, "TOKEN", "default", device) 403 luup.variable_set(SID.NEST, "AUTHORIZATION_CODE", "default", device) 404 end 297 405 return 298 406 else … … 324 432 end 325 433 326 local function clearNestOutputFile()434 local function getNestStreamPids() 327 435 local stdout = io.popen("ps | grep 'curl -N -k -v -L https://developer-api.nest.com/?auth=' | grep -v 'grep'") 328 436 local response = stdout:read("*a") 329 437 stdout:close() 330 response = response:gmatch("(%d+) root") 331 for v in response do 438 return response:gmatch("(%d+) root") 439 end 440 441 local function isStreaming() 442 for v in getNestStreamPids() do 443 return true 444 end 445 return false 446 end 447 448 local function clearNestOutputFile() 449 for v in getNestStreamPids() do 332 450 debug("clearNestOutputFile", "Killed process " .. v) 333 451 os.execute("kill " .. v) 334 452 end 335 453 os.execute("rm /tmp/NestOutput.txt") 454 g_fileSize = 0 336 455 end 337 456 … … 353 472 local fileSize = lfs.attributes("/tmp/NestOutput.txt", "size") 354 473 debug("getStreamEvents", "File size is = [" .. tostring(fileSize) .. "]") 355 -- check for new str am events474 -- check for new stream events 356 475 if fileSize then 357 476 if fileSize > g_fileSize then … … 363 482 local newEvent = file:read("*a") 364 483 file:close() 365 newEvent = newEvent:match(" data: (.*)}")484 newEvent = newEvent:match(".*data: (.*})") 366 485 debug("getStreamEvents", "newEvent = [" .. tostring(newEvent) .. "]") 367 486 g_fileSize = fileSize 368 487 if newEvent and not string.find(newEvent, "null") then 369 local response = dkjson.decode(newEvent .. "}")488 local response = dkjson.decode(newEvent) 370 489 local therm = response.data.devices.thermostats 371 490 if therm then … … 422 541 end -- if fileSize > g_fileSize 423 542 end 424 if tonumber(fileSize) > g_maxFileSize then543 if tonumber(fileSize) > g_maxFileSize or not isStreaming() then 425 544 startStreaming() 426 545 debug("getStreamEvents", "Restarting Streaming!") … … 468 587 g_thermostats[count].away_temperature_low_c = v.away_temperature_low_c 469 588 g_thermostats[count].hvac_mode = v.hvac_mode 589 g_thermostats[count].hvac_state = v.hvac_state 470 590 g_thermostats[count].ambient_temperature_f = v.ambient_temperature_f 471 591 g_thermostats[count].ambient_temperature_c = v.ambient_temperature_c … … 584 704 585 705 function setCurrentSetpoint(device, value) 706 value = math.floor(value) 586 707 local thermostatID = getNestDeviceID(device, g_thermostats) 587 708 local url = g_URL .. "/devices/thermostats/" .. tostring(thermostatID) .. "?auth=" .. nest_token … … 607 728 end 608 729 609 function setTarget(device, value) 610 if value == "0" then 611 value = "home" 612 elseif value == "1" then 613 value = "away" 614 end 615 local structerID = getNestDeviceID(device, g_structures) 616 local url = g_URL .. "/structures/" .. tostring(structerID) .. "?auth=" .. nest_token 617 local header = "-H 'Content-Type: application/json'" 618 local data = "-d '{\"away\" : \"" .. value .."\"}'" 619 debug("setTarget", "data = " .. data) 620 local response, response_string = nestRequest("PUT", header, url, data) 621 if response then 622 debug("setTarget", "Nest Response = " .. response_string) 623 luup.variable_set(SID.SWP, "Status", value, device) 624 luup.variable_set(SID.SWP, "Target", value, device) 625 else 626 debug("setTarget", "ERROR : Could not set Data!") 627 end 730 function setStructure(device, value) 731 if value == "unknown" then 732 debug("setStructure", "Structure has no devices!") 733 else 734 local structerID = getNestDeviceID(device, g_structures) 735 local url = g_URL .. "/structures/" .. tostring(structerID) .. "?auth=" .. nest_token 736 local header = "-H 'Content-Type: application/json'" 737 local data = "-d '{\"away\" : \"" .. value .."\"}'" 738 debug("setStructure", "data = " .. data) 739 local response, response_string = nestRequest("PUT", header, url, data) 740 if response then 741 debug("setStructure", "Nest Response = " .. response_string) 742 luup.variable_set(SID.NEST, "StructureHW", value, device) 743 else 744 debug("setStructure", "ERROR : Could not set Data!") 745 end 746 end 747 628 748 end 629 749 --------------------------------------------------------- … … 704 824 for k, v in ipairs(g_structures) do 705 825 debug("appendDevices", "Appending Home/Away ".. v.name ..".") 706 luup.chdev.append(lug_device, g_appendPtr, "nest_home_away_".. v.structure_id, "WWN Home/Away - " .. v.name, DEVICE_TYPES. BINARY_LIGHT, DEVICE_FILES.BINARY_LIGHT, nil, ",category_num=5\n,subcategory_num=3", false)826 luup.chdev.append(lug_device, g_appendPtr, "nest_home_away_".. v.structure_id, "WWN Home/Away - " .. v.name, DEVICE_TYPES.NEST_STRUCTURE, DEVICE_FILES.NEST_STRUCTURE, nil, "", false) 707 827 count = count + 1 708 828 if count > 20 then … … 729 849 local polling_rate = luup.variable_get(SID.NEST, "POLLING_RATE", device) or "" 730 850 if (polling_rate ~= "") then 731 POLLING_RATE = tonumber(polling_rate) 851 polling_rate = tonumber(polling_rate, 10) 852 if polling_rate >= 5 then 853 POLLING_RATE = polling_rate 854 else 855 POLLING_RATE = 5 856 luup.variable_set(SID.NEST, "POLLING_RATE", POLLING_RATE, device) 857 end 732 858 else 733 859 luup.variable_set(SID.NEST, "POLLING_RATE", POLLING_RATE, device) 734 860 end 861 735 862 log("getInfos", "POLLING_RATE = " .. POLLING_RATE ) 736 863 737 864 getTemperatureScale() 738 865 log("getInfos", "Temperature Scale is = " .. temperatureScale) 866 867 local check = checkPackageUpdate() 868 if check then 869 log("getInfos", "No need to check package version ...") 870 else 871 checkPackageVersion() 872 end 739 873 740 874 local auth = luup.variable_get(SID.NEST, "AUTHORIZED", device) or "" … … 754 888 flagError = 2 755 889 elseif code == "default" then 890 g_AUTHORIZATION_CODE = "default" 756 891 flagError = 2 757 892 else … … 777 912 flagError = 3 778 913 luup.variable_set(SID.NEST, "TOKEN", "default", device) 914 luup.variable_set(SID.NEST, "AUTHORIZATION_CODE", "default", device) 779 915 end 780 916 end -
/trunk/D_VeraConnectWWN1.json
r20 r30 1 1 { 2 "default_icon": "http ://download.mios.com/plugin-icons/nest.png",2 "default_icon": "https://download.mios.com/plugin-icons/nest.png", 3 3 "inScene": "0", 4 4 "doc_url": { -
/trunk/S_VeraConnectWWN1.xml
r20 r30 33 33 <name>AutoSetPointHeat</name> 34 34 <dataType>string</dataType> 35 </stateVariable> 36 <stateVariable> 37 <name>StructureValue</name> 38 <dataType>string</dataType> 39 <defaultValue>home</defaultValue> 40 <allowedValueList> 41 <allowedValue>home</allowedValue> 42 <allowedValue>away</allowedValue> 43 <allowedValue>auto-away</allowedValue> 44 <allowedValue>unknown</allowedValue> 45 </allowedValueList> 35 46 </stateVariable> 36 47 </serviceStateTable> … … 71 82 </argumentList> 72 83 </action> 84 <action> 85 <name>SetStructure</name> 86 <argumentList> 87 <argument> 88 <name>newStructureValue</name> 89 <direction>in</direction> 90 <relatedStateVariable>StructureValue</relatedStateVariable> 91 </argument> 92 </argumentList> 93 </action> 73 94 </actionList> 74 95 </scpd> -
/trunk/I_VeraConnectWWN1.xml
r20 r30 21 21 setAutoSetPointCool = nestPlugin.setAutoSetPointCool 22 22 setAutoSetPointHeat = nestPlugin.setAutoSetPointHeat 23 setStructure = nestPlugin.setStructure 23 24 return nestPlugin.Init( lul_device ) 24 25 end … … 96 97 </job> 97 98 </action> 99 100 <action> 101 <serviceId>urn:micasaverde-com:serviceId:VeraConnectWWN1</serviceId> 102 <name>SetStructure</name> 103 <job> 104 setStructure(lul_device, lul_settings.newStructureValue) 105 </job> 106 </action> 98 107 </actionList> 99 108 </implementation>
Note: See TracChangeset
for help on using the changeset viewer.