From 6f52833e95d2695c7b8da025d1561613b1c8186e Mon Sep 17 00:00:00 2001 From: rafale77 Date: Mon, 30 Mar 2020 19:19:34 -0700 Subject: [PATCH 01/12] Fixed Window Covering Service --- L_ZWay2.lua | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/L_ZWay2.lua b/L_ZWay2.lua index d04d490..38bb559 100644 --- a/L_ZWay2.lua +++ b/L_ZWay2.lua @@ -2,7 +2,7 @@ module (..., package.seeall) ABOUT = { NAME = "L_ZWay2", - VERSION = "2020.03.29", + VERSION = "2020.03.30", DESCRIPTION = "Z-Way interface for openLuup", AUTHOR = "@akbooer", COPYRIGHT = "(c) 2013-2020 AKBooer", @@ -49,7 +49,6 @@ ABOUT = { -- 2020.03.23 improve thermostat recognition (thanks @ronluna) -- 2020.03.29 fix handling of missing class #67 in thermostats (thanks @ronluna) - local json = require "openLuup.json" local chdev = require "openLuup.chdev" -- NOT the same as the luup.chdev module! (special create fct) local async = require "openLuup.http_async" @@ -283,10 +282,10 @@ local KnownSID = { -- list of all implemented serviceIds "urn:micasaverde-com:serviceId:SceneController1", "urn:micasaverde-com:serviceId:SceneControllerLED1", "urn:micasaverde-com:serviceId:SecuritySensor1", - "urn:micasaverde-com:serviceId:WindowCovering1", "urn:micasaverde-com:serviceId:ZWaveNetwork1", "urn:upnp-org:serviceId:Dimming1", + "urn:upnp-org:serviceId:WindowCovering1", "urn:upnp-org:serviceId:FanSpeed1", "urn:upnp-org:serviceId:HVAC_FanOperatingMode1", "urn:upnp-org:serviceId:HVAC_UserOperatingMode1", @@ -613,36 +612,30 @@ SRV.WindowCovering = { -- 2020.03.25 rafale77 Additions -- Up = function (d) - --- local off = level == '0' - local class = "-38" - luup.variable_set (SID.SwitchPower, "Target", '1', d) luup.variable_set (SID.Dimming, "LoadLevelTarget", "100", d) local altid = luup.devices[d].id - altid = altid: match (NIaltid) and altid..class or altid + altid = altid: match (NIaltid) and altid.."-38" or altid Z.command (altid, "up") end, Down = function (d) - local class = "-38" luup.variable_set (SID.SwitchPower, "Target", '0', d) luup.variable_set (SID.Dimming, "LoadLevelTarget", '0', d) local altid = luup.devices[d].id - altid = altid: match (NIaltid) and altid..class or altid + altid = altid: match (NIaltid) and altid.."-38" or altid Z.command (altid, "down") end, Stop = function (d) - local class = "-38" luup.variable_set (SID.SwitchPower, "Target", '1', d) local val = luup.variable_get (SID.Dimming, "LoadLevelStatus", d) luup.variable_set (SID.Dimming, "LoadLevelTarget", val, d) local altid = luup.devices[d].id - altid = altid: match (NIaltid) and altid..class or altid + altid = altid: match (NIaltid) and altid.."-38" or altid Z.command (altid, "stop") end, From 88151546bc6297750352767ea01faccb2f1651dc Mon Sep 17 00:00:00 2001 From: akbooer Date: Wed, 1 Apr 2020 15:42:16 +0100 Subject: [PATCH 02/12] 2020.03.31 - fix 1 or 0 for DoorLock action - thanks @DesT --- L_ZWay2.lua | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/L_ZWay2.lua b/L_ZWay2.lua index 38bb559..d892433 100644 --- a/L_ZWay2.lua +++ b/L_ZWay2.lua @@ -2,7 +2,7 @@ module (..., package.seeall) ABOUT = { NAME = "L_ZWay2", - VERSION = "2020.03.30", + VERSION = "2020.03.31", DESCRIPTION = "Z-Way interface for openLuup", AUTHOR = "@akbooer", COPYRIGHT = "(c) 2013-2020 AKBooer", @@ -48,6 +48,9 @@ ABOUT = { -- 2020.03.16 continued refactoring ... including asynchronous HTTP requests -- 2020.03.23 improve thermostat recognition (thanks @ronluna) -- 2020.03.29 fix handling of missing class #67 in thermostats (thanks @ronluna) +-- 2020.03.30 @rafale77, pull request#24, fix Window Covering Service +-- 2020.03.31 fix x_or_y() functions to work with 1 or 0 as well as '1' or '0' (thanks @DesT) + local json = require "openLuup.json" local chdev = require "openLuup.chdev" -- NOT the same as the luup.chdev module! (special create fct) @@ -77,7 +80,6 @@ end local function ZWayAPI (ip, sid) local cookie = "ZWAYSession=" .. (sid or '') --- local ok, err = async.request (url, VeraBridge_async_callback) local function build_request (url, body, response_body) return { @@ -385,25 +387,35 @@ end -- given "on" or "off" or "1" or "0" -- return "1" or "0" or "on" or "off" local function on_or_off (x) - local y = {["on"] = "1", ["off"] = "0", ["1"] = "on", ["0"] = "off", [true] = "on"} + local y = { + ["on"] = "1", ["off"] = "0", + ["1"] = "on", ["0"] = "off", + [1] = "on", [0] = "off", + [true] = "on"} local z = tonumber (x) local on = z and z > 0 return y[on or x] or x end local function open_or_close (x) - local y = {["open"] = "0", ["close"] = "1", ["0"] = "open", ["1"] = "close"} + local y = { + ["open"] = "0", ["close"] = "1", + ["0"] = "open", ["1"] = "close", + [0] = "open", [1] = "close"} return y[x] or x end local function rev_open_or_close (x) - local y = {["open"] = "1", ["close"] = "0", ["1"] = "open", ["0"] = "close"} + local y = { + ["open"] = "1", ["close"] = "0", + ["1"] = "open", ["0"] = "close", + [1] = "open", [0] = "close"} return y[x] or x end -- make either "1" or "true" or true work the same way local function is_true (flag) - local y = {["true"] = true, ["1"] = true, [true] = true} + local y = {["true"] = true, ["1"] = true, [1] = true, [true] = true} return y [flag] end From fc00be3cd74bc208a70fe7617136ce3687cff3bf Mon Sep 17 00:00:00 2001 From: rafale77 Date: Sun, 5 Apr 2020 08:24:42 -0700 Subject: [PATCH 03/12] ControllerLED handling individual per button control --- L_ZWay2.lua | 48 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/L_ZWay2.lua b/L_ZWay2.lua index d892433..26a4eba 100644 --- a/L_ZWay2.lua +++ b/L_ZWay2.lua @@ -2,7 +2,7 @@ module (..., package.seeall) ABOUT = { NAME = "L_ZWay2", - VERSION = "2020.03.31", + VERSION = "2020.04.05", DESCRIPTION = "Z-Way interface for openLuup", AUTHOR = "@akbooer", COPYRIGHT = "(c) 2013-2020 AKBooer", @@ -57,7 +57,7 @@ local chdev = require "openLuup.chdev" -- NOT the same as the luup.chdev local async = require "openLuup.http_async" local http = require "socket.http" local ltn12 = require "ltn12" - +local bit = require "bit" local empty = setmetatable ({}, {__newindex = function() error ("read-only", 2) end}) local function _log(text, level) @@ -388,9 +388,9 @@ end -- return "1" or "0" or "on" or "off" local function on_or_off (x) local y = { - ["on"] = "1", ["off"] = "0", - ["1"] = "on", ["0"] = "off", - [1] = "on", [0] = "off", + ["on"] = "1", ["off"] = "0", + ["1"] = "on", ["0"] = "off", + [1] = "on", [0] = "off", [true] = "on"} local z = tonumber (x) local on = z and z > 0 @@ -399,7 +399,7 @@ end local function open_or_close (x) local y = { - ["open"] = "0", ["close"] = "1", + ["open"] = "0", ["close"] = "1", ["0"] = "open", ["1"] = "close", [0] = "open", [1] = "close"} return y[x] or x @@ -407,7 +407,7 @@ end local function rev_open_or_close (x) local y = { - ["open"] = "1", ["close"] = "0", + ["open"] = "1", ["close"] = "0", ["1"] = "open", ["0"] = "close", [1] = "open", [0] = "close"} return y[x] or x @@ -595,6 +595,23 @@ SRV.GenericSensor = { } SRV.HumiditySensor = { } SRV.LightSensor = { } +local function btn_val(button, color) + local tot = 0 + for i=0,16 do + if (bit.band(2^i, color) ~= 0) then tot = tot + (2 ^ (button-1) * 2 ^ (4*(i))) end + end + return tot +end + +local function ledbitval(ls, button) + for v=3,1,-1 do + b = btn_val(button,v) + local val = bit.band(b, ls) + if val == b then return val end + end + return 0 +end + SRV.SceneControllerLED = { SetLight = function (d, args) @@ -602,18 +619,17 @@ SRV.SceneControllerLED = { local id = altid: match (NIaltid) local cc = 145 --command class local color = tonumber(args.newValue) - local indicator = args.Indicator + local indicator = tonumber(args.Indicator) local data = "[%s,0,29,13,1,255,%s,0,0,10]" - local ItoL = {["1"] = 1, ["2"] = 2, ["3"] = 4, ["4"] = 8, ["5"] = 15} - local led = ItoL[indicator] - if led then - local bit_lshift_led = led * 16 --bit.lshift(led,4) - if color == 2 then led = bit_lshift_led - elseif color == 3 then led = led + bit_lshift_led - elseif color == 0 then led = 0 - end + local curled = luup.variable_get(SID.SceneControllerLED, "LightSettings", d) or 0 + local oldledv = ledbitval(curled,indicator) + local newledv = btn_val(indicator, color) + local led = curled-oldledv+newledv + if indicator == 5 then led = btn_val(1, color)+btn_val(2, color)+btn_val(3, color)+btn_val(4, color) end + if led <= 255 then data = data: format(cc,led) Z.zwsend(id,data) + luup.variable_set(SID.SceneControllerLED, "LightSettings", led, d) end end, From def7d6f28c7e06a9757424ad307fa45de05744bf Mon Sep 17 00:00:00 2001 From: akbooer Date: Sun, 5 Apr 2020 19:00:36 +0100 Subject: [PATCH 04/12] 2020.04.05b - scene controller LED handling - thanks @rafale77 --- L_ZWay2.lua | 81 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 33 deletions(-) diff --git a/L_ZWay2.lua b/L_ZWay2.lua index 26a4eba..6fe6522 100644 --- a/L_ZWay2.lua +++ b/L_ZWay2.lua @@ -2,7 +2,7 @@ module (..., package.seeall) ABOUT = { NAME = "L_ZWay2", - VERSION = "2020.04.05", + VERSION = "2020.04.05b", DESCRIPTION = "Z-Way interface for openLuup", AUTHOR = "@akbooer", COPYRIGHT = "(c) 2013-2020 AKBooer", @@ -50,6 +50,7 @@ ABOUT = { -- 2020.03.29 fix handling of missing class #67 in thermostats (thanks @ronluna) -- 2020.03.30 @rafale77, pull request#24, fix Window Covering Service -- 2020.03.31 fix x_or_y() functions to work with 1 or 0 as well as '1' or '0' (thanks @DesT) +-- 2020.04.05 @rafale77, pull request #27, controller LED handling local json = require "openLuup.json" @@ -57,7 +58,7 @@ local chdev = require "openLuup.chdev" -- NOT the same as the luup.chdev local async = require "openLuup.http_async" local http = require "socket.http" local ltn12 = require "ltn12" -local bit = require "bit" + local empty = setmetatable ({}, {__newindex = function() error ("read-only", 2) end}) local function _log(text, level) @@ -199,10 +200,16 @@ local function ZWayAPI (ip, sid) local status, response = request "/ZWaveAPI/Run/zway.controller" return status, json.decode (response) end, + command = zwcommand, + send = zwsend, + }, -- Virtual Device API - vDevAPI = {}, + vDevAPI = { + command = command, + status = status, + }, -- JavaScript API JSAPI = {}, @@ -388,9 +395,9 @@ end -- return "1" or "0" or "on" or "off" local function on_or_off (x) local y = { - ["on"] = "1", ["off"] = "0", - ["1"] = "on", ["0"] = "off", - [1] = "on", [0] = "off", + ["on"] = "1", ["off"] = "0", + ["1"] = "on", ["0"] = "off", + [1] = "on", [0] = "off", [true] = "on"} local z = tonumber (x) local on = z and z > 0 @@ -399,7 +406,7 @@ end local function open_or_close (x) local y = { - ["open"] = "0", ["close"] = "1", + ["open"] = "0", ["close"] = "1", ["0"] = "open", ["1"] = "close", [0] = "open", [1] = "close"} return y[x] or x @@ -407,7 +414,7 @@ end local function rev_open_or_close (x) local y = { - ["open"] = "1", ["close"] = "0", + ["open"] = "1", ["close"] = "0", ["1"] = "open", ["0"] = "close", [1] = "open", [0] = "close"} return y[x] or x @@ -595,46 +602,54 @@ SRV.GenericSensor = { } SRV.HumiditySensor = { } SRV.LightSensor = { } -local function btn_val(button, color) - local tot = 0 - for i=0,16 do - if (bit.band(2^i, color) ~= 0) then tot = tot + (2 ^ (button-1) * 2 ^ (4*(i))) end - end - return tot + +-- returns the first n bits of the binary representation of x +local function num2bits (x, n) + local b = {} + for i = 1,n do b[i] = x % 2; x = (x - b[i]) / 2 end + return b end -local function ledbitval(ls, button) - for v=3,1,-1 do - b = btn_val(button,v) - local val = bit.band(b, ls) - if val == b then return val end - end - return 0 +-- assemble number from binary array representation +local function bits2num (b) + local d = 0 + for i = #b,1,-1 do d = d + d + b[i] end + return d end SRV.SceneControllerLED = { +-- newValue = 0,1,2 or 3 where 0=off, 1=green, 2=red, 3=orange (red and green) +-- Indicator = 1-4, or 5 to set all to same colour +-- LightSettings bits are arranged as: MSB RRRRGGGG LSB +-- 43214321 corresponding button number +-- 2020.04.05 thanks to @rafale77 for explaining how this works! SetLight = function (d, args) + local curled = luup.variable_get(SID.SceneControllerLED, "LightSettings", d) or 0 + + local curbit = num2bits (curled, 8) -- extract 8 LSBs + local colbit = num2bits (args.newValue, 2) -- extract 2 LSBs + local indicator = tonumber(args.Indicator) + + for _, lamp in ipairs (indicator==5 and {1,2,3,4} or {indicator}) do + curbit[lamp] = colbit[1] -- green LED + curbit[lamp + 4] = colbit[2] -- red LED + end + + local led = bits2num(curbit) + luup.variable_set(SID.SceneControllerLED, "LightSettings", led, d) + local altid = luup.devices[d].id local id = altid: match (NIaltid) local cc = 145 --command class - local color = tonumber(args.newValue) - local indicator = tonumber(args.Indicator) local data = "[%s,0,29,13,1,255,%s,0,0,10]" - local curled = luup.variable_get(SID.SceneControllerLED, "LightSettings", d) or 0 - local oldledv = ledbitval(curled,indicator) - local newledv = btn_val(indicator, color) - local led = curled-oldledv+newledv - if indicator == 5 then led = btn_val(1, color)+btn_val(2, color)+btn_val(3, color)+btn_val(4, color) end - if led <= 255 then - data = data: format(cc,led) - Z.zwsend(id,data) - luup.variable_set(SID.SceneControllerLED, "LightSettings", led, d) - end + data = data: format(cc,led) + Z.zwsend(id,data) end, } + SRV.WindowCovering = { --------------- -- 2020.03.25 rafale77 Additions From 012d70c0d2c33913f70999047d806a63ed9f7df8 Mon Sep 17 00:00:00 2001 From: akbooer Date: Wed, 13 May 2020 13:02:28 +0100 Subject: [PATCH 05/12] 2020.05.12 - don't disable devices in Room101 - add command class 1 updater --- L_ZWay2.lua | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/L_ZWay2.lua b/L_ZWay2.lua index 6fe6522..a29f90a 100644 --- a/L_ZWay2.lua +++ b/L_ZWay2.lua @@ -2,7 +2,7 @@ module (..., package.seeall) ABOUT = { NAME = "L_ZWay2", - VERSION = "2020.04.05b", + VERSION = "2020.05.12", DESCRIPTION = "Z-Way interface for openLuup", AUTHOR = "@akbooer", COPYRIGHT = "(c) 2013-2020 AKBooer", @@ -35,6 +35,10 @@ ABOUT = { -- 2020.02.10 fixed meter variable names, thanks @rafale77 -- ditto, CurrentSetpoint in command class 67 -- see: https://community.getvera.com/t/zway-plugin/212312/40 +-- 2020.05.11 don't disable devices in Room101 (because they weren't enabled when restored. Thanks @kfxo) +-- see: https://smarthome.community/topic/111/all-z-way-devices-disabled-attribute-is-set-to-1 +-- 2020.05.12 add command class 1 updater for ZWave.me battery switch, thanks @ArcherS +-- see: https://smarthome.community/topic/113/changing-device-type-for-wall-controller ----------------- @@ -50,7 +54,9 @@ ABOUT = { -- 2020.03.29 fix handling of missing class #67 in thermostats (thanks @ronluna) -- 2020.03.30 @rafale77, pull request#24, fix Window Covering Service -- 2020.03.31 fix x_or_y() functions to work with 1 or 0 as well as '1' or '0' (thanks @DesT) --- 2020.04.05 @rafale77, pull request #27, controller LED handling +-- 2020.04.05 @rafale77, pull request #27, scene controller LED handling (Leviton 4-button) +-- 2020.05.11 stop disabling devices in room 101 (they stayed that way when restored! Thanks @) +-- 2020.05.12 add updater for CC #1 (dumb switch / scene controller) local json = require "openLuup.json" @@ -617,6 +623,8 @@ local function bits2num (b) return d end +-- see: https://community.getvera.com/t/leviton-scene-controller-questions/172155 +-- also: http://wiki.micasaverde.com/index.php/Leviton_LED_Debugging SRV.SceneControllerLED = { -- newValue = 0,1,2 or 3 where 0=off, 1=green, 2=red, 3=orange (red and green) @@ -843,7 +851,7 @@ end local CC = { -- command class object - -- catch-all + -- scene controller, also used for CC ["1"] ["0"] = { updater = function (d, inst, meta) local dev = luup.devices[d] @@ -853,7 +861,7 @@ local CC = { -- command class object local click = inst.updateTime if click ~= meta.click then -- force variable updates local scene = meta.scale - local time = os.time() -- "◷" == json.decode [["\u25F7"]] + local time = os.time() luup.variable_set (SID.SceneController, "sl_SceneActivated", scene, d) luup.variable_set (SID.SceneController, "LastSceneTime",time, d) @@ -862,6 +870,7 @@ local CC = { -- command class object end else + -- catch-all -- local message = "no update for device %d [%s] %s %s" -- log (message: format (d, inst.id, inst.deviceType or '?', (inst.metrics or {}).icon or '')) --... @@ -870,6 +879,13 @@ local CC = { -- command class object files = { nil, SID.HaDevice }, -- device, service, json files }, + + -- dumb switch, like ZWave.me battery switch + ["1"] = { + updater = function () end, -- dummy stub to be assigned at end of CC table + + files = { nil, SID.HaDevice }, + }, -- binary switch ["37"] = { @@ -1173,6 +1189,8 @@ local CC = { -- command class object } + +CC ["1"].updater = CC ["0"].updater -- dumb switch / controller CC ["113"].updater = CC ["48"].updater -- alarm CC ["156"].updater = CC ["48"].updater -- tamper switch (deprecated) @@ -1287,14 +1305,14 @@ local function move_to_room_101 (devices) local dev = luup.devices[n] _log (table.concat {"Room 101: [", n, "] ", dev.description}) dev: rename (nil, 101) -- move to Room 101 - dev: attr_set ("disabled", 1) -- and make sure it can't run +-- dev: attr_set ("disabled", 1) -- and make sure it can't run end end -- index list of vDevs by command class, saving altids of occurrences local dont_count = { ["0"] = true, -- generic - ["1"] = true, -- ??? + ["1"] = true, -- button of some sort ??? ["50"] = true, -- power ["51"] = true, -- switch colour ["128"] = true, -- batteries @@ -1360,6 +1378,14 @@ local function configureDevice (id, name, ldv, child) add_updater (button) -- should work for Minimote, at least end + elseif classes.n == 0 and classes["1"] and #classes["1"] > 0 then -- just buttons? + upnp_file = DEV.controller + name = classes["1"][1].metrics.title +-- print ("CC1", id, name) + for _,button in ipairs (classes["1"]) do + add_updater (button) -- should work for ZWave.me battery switch + end + elseif classes.n <= 1 then -- a singleton device local vDev = ldv[1] -- there may be a better choice selected below for _,v in ipairs (ldv) do @@ -1630,6 +1656,7 @@ local function updateChildren (vDevs) local id = vtype .. altid if getVar (id, sid, zDevNo) then -- fast update of existing variable values (this really does make a difference) + -- NB. this means that you CAN'T trigger, watch, or log these variables local vars = zDev.services[sid].variables vars[id].value = inst.metrics.level vars[id .. "_LastUpdate"].value = inst.updateTime From 4c58d7dd65e92a768c13ff70ddd5081eef3884b8 Mon Sep 17 00:00:00 2001 From: akbooer Date: Mon, 13 Jul 2020 13:10:56 +0100 Subject: [PATCH 06/12] 2020.07.12 - add CC91, Central Scene - for Remotec ZRC90 - thanks @CatmanV2, @ArcherS --- L_ZWay2.lua | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/L_ZWay2.lua b/L_ZWay2.lua index a29f90a..cad2207 100644 --- a/L_ZWay2.lua +++ b/L_ZWay2.lua @@ -2,7 +2,7 @@ module (..., package.seeall) ABOUT = { NAME = "L_ZWay2", - VERSION = "2020.05.12", + VERSION = "2020.07.12", DESCRIPTION = "Z-Way interface for openLuup", AUTHOR = "@akbooer", COPYRIGHT = "(c) 2013-2020 AKBooer", @@ -35,10 +35,6 @@ ABOUT = { -- 2020.02.10 fixed meter variable names, thanks @rafale77 -- ditto, CurrentSetpoint in command class 67 -- see: https://community.getvera.com/t/zway-plugin/212312/40 --- 2020.05.11 don't disable devices in Room101 (because they weren't enabled when restored. Thanks @kfxo) --- see: https://smarthome.community/topic/111/all-z-way-devices-disabled-attribute-is-set-to-1 --- 2020.05.12 add command class 1 updater for ZWave.me battery switch, thanks @ArcherS --- see: https://smarthome.community/topic/113/changing-device-type-for-wall-controller ----------------- @@ -55,8 +51,12 @@ ABOUT = { -- 2020.03.30 @rafale77, pull request#24, fix Window Covering Service -- 2020.03.31 fix x_or_y() functions to work with 1 or 0 as well as '1' or '0' (thanks @DesT) -- 2020.04.05 @rafale77, pull request #27, scene controller LED handling (Leviton 4-button) --- 2020.05.11 stop disabling devices in room 101 (they stayed that way when restored! Thanks @) --- 2020.05.12 add updater for CC #1 (dumb switch / scene controller) +-- 2020.05.11 don't disable devices in Room101 (because they weren't enabled when restored. Thanks @kfxo) +-- see: https://smarthome.community/topic/111/all-z-way-devices-disabled-attribute-is-set-to-1 +-- 2020.05.12 add command class 1 updater for ZWave.me battery switch, thanks @ArcherS +-- see: https://smarthome.community/topic/113/changing-device-type-for-wall-controller +-- 2020.07.12 add CC 91, Central Scene for Remotec ZRC90 (and others?) +-- see: https://smarthome.community/topic/171/remotec-zrc90 local json = require "openLuup.json" @@ -850,7 +850,7 @@ end -- local CC = { -- command class object - + -- scene controller, also used for CC ["1"] ["0"] = { updater = function (d, inst, meta) @@ -1110,7 +1110,26 @@ local CC = { -- command class object files = {nil, SID.HVAC_FanOperatingMode}, }, + + --central scene + ["91"] = { + updater = function (d, inst, meta) + local dev = luup.devices[d] + local click = inst.updateTime + if click ~= meta.click then -- force variable updates + local scene = meta.scale + local time = os.time() + + luup.variable_set (SID.SceneController, "sl_CentralSceneUpdates", scene, d) + luup.variable_set (SID.SceneController, "LastSceneTime",time, d) + + meta.click = click + end + end, + files = { DEV.controller, SID.SceneController }, + }, + -- door lock ["98"] = { updater = function (d, inst) @@ -1453,6 +1472,10 @@ local function configureDevice (id, name, ldv, child) name = v.metrics.title -- updaters are set at the end of this if-then-elseif statement + elseif classes["91"] and #classes["91"] == 1 then -- central scene + local v = classes["91"][1] + upnp_file, json_file, name = add_updater (v) + elseif classes["102"] and #classes["102"] == 1 then -- door lock (barrier) local v = classes["102"][1] upnp_file, json_file, name = add_updater (v) From 1f27547fd982270417330e0eb4120d04671d4202 Mon Sep 17 00:00:00 2001 From: akbooer Date: Tue, 14 Jul 2020 07:48:00 +0100 Subject: [PATCH 07/12] 2020.07.14 - correct Central Scene updater - use sl_CentralScene variable --- L_ZWay2.lua | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/L_ZWay2.lua b/L_ZWay2.lua index cad2207..16bbb5b 100644 --- a/L_ZWay2.lua +++ b/L_ZWay2.lua @@ -2,7 +2,7 @@ module (..., package.seeall) ABOUT = { NAME = "L_ZWay2", - VERSION = "2020.07.12", + VERSION = "2020.07.14", DESCRIPTION = "Z-Way interface for openLuup", AUTHOR = "@akbooer", COPYRIGHT = "(c) 2013-2020 AKBooer", @@ -1114,15 +1114,12 @@ local CC = { -- command class object --central scene ["91"] = { updater = function (d, inst, meta) - local dev = luup.devices[d] local click = inst.updateTime if click ~= meta.click then -- force variable updates - local scene = meta.scale + local button = inst.metrics.level local time = os.time() - - luup.variable_set (SID.SceneController, "sl_CentralSceneUpdates", scene, d) + luup.variable_set (SID.SceneController, "sl_CentralScene", button, d) luup.variable_set (SID.SceneController, "LastSceneTime",time, d) - meta.click = click end end, From 1326a56556f30015b84af133d6d69c205f5ed227 Mon Sep 17 00:00:00 2001 From: akbooer Date: Tue, 24 Nov 2020 15:45:00 +0000 Subject: [PATCH 08/12] 2020.11.24 - add category_num to devices --- L_ZWay2.lua | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/L_ZWay2.lua b/L_ZWay2.lua index 16bbb5b..d2be227 100644 --- a/L_ZWay2.lua +++ b/L_ZWay2.lua @@ -2,7 +2,7 @@ module (..., package.seeall) ABOUT = { NAME = "L_ZWay2", - VERSION = "2020.07.14", + VERSION = "2020.11.24", DESCRIPTION = "Z-Way interface for openLuup", AUTHOR = "@akbooer", COPYRIGHT = "(c) 2013-2020 AKBooer", @@ -57,11 +57,13 @@ ABOUT = { -- see: https://smarthome.community/topic/113/changing-device-type-for-wall-controller -- 2020.07.12 add CC 91, Central Scene for Remotec ZRC90 (and others?) -- see: https://smarthome.community/topic/171/remotec-zrc90 +-- 2020.11.24 add category_num, if not set already, when checking devices local json = require "openLuup.json" local chdev = require "openLuup.chdev" -- NOT the same as the luup.chdev module! (special create fct) local async = require "openLuup.http_async" +local loader = require "openLuup.loader" local http = require "socket.http" local ltn12 = require "ltn12" @@ -1583,7 +1585,15 @@ local function createChildren (bridgeDevNo, vDevs, room, OFFSET) dev = createZwaveDevice (parent, id, name, altid, upnp_file, json_file, room) end dev.handle_children = true -- ensure that any child devices are handled - dev.attributes.host = "Z-Way" -- flag as Z-Way hosted device [+luup.variable_set()] + local attr = dev.attributes + -- 2020.11.24 add category num, if not set already + local dt = attr.device_type + local cn = attr.category_num or 0 + if cn == 0 then + attr.category_num = loader.cat_by_dev[dt] or 0 + end + -- + attr.host = "Z-Way" -- flag as Z-Way hosted device [+luup.variable_set()] if CLONEROOMS then dev: rename (nil, room) end -- force to given room name if dev.room_num == 101 then dev: rename (nil, room) end -- ensure it's not in Room 101!! list[#list+1] = id -- add to new list From 057e0add33980b0f5fd3ea5c6f6944e27d16e2b9 Mon Sep 17 00:00:00 2001 From: akbooer Date: Tue, 19 Jan 2021 16:14:29 +0000 Subject: [PATCH 09/12] 2021.01.19 - flag authorisation failure during synchronous or asynchronous requests - thanks @PerH --- L_ZWay2.lua | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/L_ZWay2.lua b/L_ZWay2.lua index d2be227..91fd5e2 100644 --- a/L_ZWay2.lua +++ b/L_ZWay2.lua @@ -2,14 +2,14 @@ module (..., package.seeall) ABOUT = { NAME = "L_ZWay2", - VERSION = "2020.11.24", + VERSION = "2021.01.19", DESCRIPTION = "Z-Way interface for openLuup", AUTHOR = "@akbooer", - COPYRIGHT = "(c) 2013-2020 AKBooer", + COPYRIGHT = "(c) 2013-2021 AKBooer", DOCUMENTATION = "https://community.getvera.com/t/openluup-zway-plugin-for-zwave-me-hardware/193746", DEBUG = false, LICENSE = [[ - Copyright 2013-2020 AK Booer + Copyright 2013-2021 AK Booer Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -59,6 +59,8 @@ ABOUT = { -- see: https://smarthome.community/topic/171/remotec-zrc90 -- 2020.11.24 add category_num, if not set already, when checking devices +-- 2021.01.19 flag authorisation failure during synchronous or asynchronous requests (thanks @PerH) + local json = require "openLuup.json" local chdev = require "openLuup.chdev" -- NOT the same as the luup.chdev module! (special create fct) @@ -145,8 +147,8 @@ local function ZWayAPI (ip, sid) local function devices () local url = "http://%s:8083/ZAutomation/api/v1/devices" - local _, d = HTTP_request_json (url: format (ip)) - return d and d.data and d.data.devices or empty + local status, d = HTTP_request_json (url: format (ip)) + return d and d.data and d.data.devices or empty, status end -- send a command @@ -434,6 +436,11 @@ local function is_true (flag) return y [flag] end +-- 2021.01.19 flag authorisation failure +local function authentication_failure() + luup.set_failure (2) + setVar ("DisplayLine1", 'Login required', SID.AltUI) +end ---------------------------------------------------- -- @@ -535,6 +542,14 @@ SRV.HaDevice = { local id, inst = altid: match (NIaltid) Z.zwcommand(id, inst, cc, data) end, + + GetConfig = { + run = function() + -- do whatever you need to get the status into ZWay_ZWaveCONFIG + ZWay_ZWaveCONFIG = 42 + end, + extra_returns = {Config = function () return ZWay_ZWaveCONFIG end} + }, } @@ -1743,9 +1758,13 @@ do -- original synchronous polling function _G.ZWay_delay_callback () - local vDevs = Z.devices() - if vDevs then updateChildren (vDevs) end - luup.call_delay ("ZWay_delay_callback", POLLRATE) + local vDevs, status = Z.devices() + if status == 401 then + authentication_failure() + else + if vDevs then updateChildren (vDevs) end + luup.call_delay ("ZWay_delay_callback", POLLRATE) + end end -- asynchronous polling @@ -1778,6 +1797,8 @@ do updateChildren (vDevs) end -- delay = POLL_MINIMUM end -- yes, ask for another one soon... -- init = '' -- ... without initialising data version + elseif status == 401 then + authentication_failure() else luup.log (log: format (status or '?', #(response or ''))) end @@ -1936,8 +1957,7 @@ function init (lul_device) luup.set_failure (0) -- all's well with the world else - luup.set_failure (2, devNo) -- authorisation failure - setVar ("DisplayLine1", 'Login required', SID.AltUI) + authentication_failure() status, comment = false, "Failed to authenticate" end From b44629583727feb4e7ed54d83854546ed8b3f5b1 Mon Sep 17 00:00:00 2001 From: rafale77 Date: Tue, 9 Feb 2021 20:56:27 -0800 Subject: [PATCH 10/12] Add GetConfig --- L_ZWay2.lua | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/L_ZWay2.lua b/L_ZWay2.lua index 91fd5e2..e1d24ea 100644 --- a/L_ZWay2.lua +++ b/L_ZWay2.lua @@ -60,6 +60,7 @@ ABOUT = { -- 2020.11.24 add category_num, if not set already, when checking devices -- 2021.01.19 flag authorisation failure during synchronous or asynchronous requests (thanks @PerH) +-- 2021.02.09 Add GetConfig action to poll device and report back configuration settings local json = require "openLuup.json" @@ -532,6 +533,22 @@ SRV.HaDevice = { local id, inst = altid: match (NIaltid) Z.zwcommand(id, inst, cc, cmd) end, + + GetConfig = { + run = function (d,args) + local cc = 112 + local par = args.parameter + local data = "Get(%s)" + local data2 = "data[%s].val.value" + local altid = luup.devices[d].id + local id, inst = altid: match (NIaltid) + data = data: format(par) + data2 = data2: format(par) + Z.zwcommand(id, inst, cc, data) + ret, conf = Z.zwcommand(id, inst, cc, data2) + end, + extra_returns = {Config = function () return conf end} + }, SendConfig = function (d,args) local cc = 112 @@ -543,13 +560,6 @@ SRV.HaDevice = { Z.zwcommand(id, inst, cc, data) end, - GetConfig = { - run = function() - -- do whatever you need to get the status into ZWay_ZWaveCONFIG - ZWay_ZWaveCONFIG = 42 - end, - extra_returns = {Config = function () return ZWay_ZWaveCONFIG end} - }, } From 799e4d55633f886ea085d978d0d831880456cdb2 Mon Sep 17 00:00:00 2001 From: rafale77 Date: Sat, 24 Jul 2021 18:08:56 -0700 Subject: [PATCH 11/12] Update L_ZWay2.lua --- L_ZWay2.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/L_ZWay2.lua b/L_ZWay2.lua index e1d24ea..2bad8e8 100644 --- a/L_ZWay2.lua +++ b/L_ZWay2.lua @@ -2,7 +2,7 @@ module (..., package.seeall) ABOUT = { NAME = "L_ZWay2", - VERSION = "2021.01.19", + VERSION = "2021.07.24", DESCRIPTION = "Z-Way interface for openLuup", AUTHOR = "@akbooer", COPYRIGHT = "(c) 2013-2021 AKBooer", @@ -61,7 +61,7 @@ ABOUT = { -- 2021.01.19 flag authorisation failure during synchronous or asynchronous requests (thanks @PerH) -- 2021.02.09 Add GetConfig action to poll device and report back configuration settings - +-- 2021.07.24 Add support for Fibaro TRV heater device as a thermostat local json = require "openLuup.json" local chdev = require "openLuup.chdev" -- NOT the same as the luup.chdev module! (special create fct) @@ -1466,6 +1466,10 @@ local function configureDevice (id, name, ldv, child) local temp = classes["49"] add_updater(temp[1]) + elseif classes["64"] and classes["67"] then -- a fibaro heater with temperature in another instance + upnp_file, json_file, name = add_updater (classes["64"][1]) + upnp_file, json_file, name = add_updater (classes["67"][1]) + elseif ((classes["37"] and #classes["37"] == 1) -- ... just one switch or (classes["38"] and #classes["38"] == 1) ) then -- ... OR just one dimmer -- @rafale77, pull request #17 was for DesT’s GE combo device From 7d6fc3d24556ff383959173db215bad048bbed18 Mon Sep 17 00:00:00 2001 From: akbooer Date: Thu, 22 Feb 2024 20:22:15 +0000 Subject: [PATCH 12/12] 2024.02.22 - global device table access - ...for external scripting --- L_ZWay2.lua | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/L_ZWay2.lua b/L_ZWay2.lua index 2bad8e8..1320d57 100644 --- a/L_ZWay2.lua +++ b/L_ZWay2.lua @@ -2,14 +2,14 @@ module (..., package.seeall) ABOUT = { NAME = "L_ZWay2", - VERSION = "2021.07.24", + VERSION = "2024.02.22", DESCRIPTION = "Z-Way interface for openLuup", AUTHOR = "@akbooer", - COPYRIGHT = "(c) 2013-2021 AKBooer", + COPYRIGHT = "(c) 2013-2024 AKBooer", DOCUMENTATION = "https://community.getvera.com/t/openluup-zway-plugin-for-zwave-me-hardware/193746", DEBUG = false, LICENSE = [[ - Copyright 2013-2021 AK Booer + Copyright 2013-2024 AK Booer Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -61,7 +61,10 @@ ABOUT = { -- 2021.01.19 flag authorisation failure during synchronous or asynchronous requests (thanks @PerH) -- 2021.02.09 Add GetConfig action to poll device and report back configuration settings --- 2021.07.24 Add support for Fibaro TRV heater device as a thermostat +-- 2021.07.24 @rafale77, pull request #31, add support for Fibaro TRV heater device as a thermostat + +-- 2024.02.22 put devices data into global environment to allow external access (room/device nremae for @DesT) + local json = require "openLuup.json" local chdev = require "openLuup.chdev" -- NOT the same as the luup.chdev module! (special create fct) @@ -88,6 +91,8 @@ end -- Z-WayVDev() API -- +_G["DEVS"] = {"empty"} -- 2024.02.22 global device table access + local function ZWayAPI (ip, sid) @@ -1703,6 +1708,7 @@ local D = {} -- latest device structure ---- this needs to be as fast as possible, since all vDevs are cycled through every update local function updateChildren (vDevs) + DEVS = vDevs -- 2024.02.22 allow global access for scripting local sid = SID.ZWay local failed = {} for _,inst in pairs (vDevs) do