diff --git a/drivers/SmartThings/matter-thermostat/src/init.lua b/drivers/SmartThings/matter-thermostat/src/init.lua index 5143f4dfd0..5571326297 100644 --- a/drivers/SmartThings/matter-thermostat/src/init.lua +++ b/drivers/SmartThings/matter-thermostat/src/init.lua @@ -720,6 +720,9 @@ end local function temp_event_handler(attribute) return function(driver, device, ib, response) + if ib.data.value == nil then + return + end local unit = "C" -- Only emit the capability for RPC version >= 5, since unit conversion for diff --git a/drivers/SmartThings/virtual-switch/src/init.lua b/drivers/SmartThings/virtual-switch/src/init.lua index 116427a6ad..7f5288a9c4 100644 --- a/drivers/SmartThings/virtual-switch/src/init.lua +++ b/drivers/SmartThings/virtual-switch/src/init.lua @@ -2,10 +2,12 @@ local capabilities = require "st.capabilities" local Driver = require "st.driver" local function force_state_change(device) - if device.preferences["certifiedpreferences.forceStateChange"] then + if device.preferences == nil or device.preferences["certifiedpreferences.forceStateChange"] == nil then return {state_change = true} - else + elseif not device.preferences["certifiedpreferences.forceStateChange"] then return nil + else + return {state_change = true} end end diff --git a/drivers/SmartThings/virtual-switch/src/test/test_virtual_switch.lua b/drivers/SmartThings/virtual-switch/src/test/test_virtual_switch.lua index a42dfc4a1f..651668297b 100644 --- a/drivers/SmartThings/virtual-switch/src/test/test_virtual_switch.lua +++ b/drivers/SmartThings/virtual-switch/src/test/test_virtual_switch.lua @@ -10,8 +10,15 @@ local mock_simple_device = test.mock_device.build_test_generic_device( } ) +local mock_device_no_prefs = test.mock_device.build_test_generic_device( + { + profile = t_utils.get_profile_definition("virtual-dimmer-switch.yml"), + } +) + local function test_init() test.mock_device.add_test_device(mock_simple_device) + test.mock_device.add_test_device(mock_device_no_prefs) end test.set_test_init_function(test_init) @@ -53,6 +60,22 @@ test.register_message_test( } ) +test.register_message_test( + "Reported on off status should be handled: on", + { + { + channel = "capability", + direction = "receive", + message = { mock_device_no_prefs.id, { capability = "switch", component = "main", command = "on", args = {}}} + }, + { + channel = "capability", + direction = "send", + message = mock_device_no_prefs:generate_test_message("main", capabilities.switch.switch.on({state_change=true})) + } + } +) + test.register_message_test( "Reported on off status should be handled: off", { diff --git a/drivers/SmartThings/zigbee-lock/src/init.lua b/drivers/SmartThings/zigbee-lock/src/init.lua index b6465b0729..2271230bdb 100644 --- a/drivers/SmartThings/zigbee-lock/src/init.lua +++ b/drivers/SmartThings/zigbee-lock/src/init.lua @@ -322,11 +322,11 @@ local lock_state_handler = function(driver, device, value, zb_rx) local delay = device:get_field(DELAY_LOCK_EVENT) or 100 if (delay < MAX_DELAY) then device.thread:call_with_delay(delay+.5, function () - device:emit_event_for_endpoint(zb_rx.address_header.src_endpoint.value, LOCK_STATE[value.value]) + device:emit_event_for_endpoint(zb_rx.address_header.src_endpoint.value, LOCK_STATE[value.value] or attr.unknown()) end) else device:set_field(DELAY_LOCK_EVENT, socket.gettime()) - device:emit_event_for_endpoint(zb_rx.address_header.src_endpoint.value, LOCK_STATE[value.value]) + device:emit_event_for_endpoint(zb_rx.address_header.src_endpoint.value, LOCK_STATE[value.value] or attr.unknown()) end end diff --git a/drivers/SmartThings/zigbee-switch/src/aqara-light/init.lua b/drivers/SmartThings/zigbee-switch/src/aqara-light/init.lua index 7225246299..3009cb6d0c 100644 --- a/drivers/SmartThings/zigbee-switch/src/aqara-light/init.lua +++ b/drivers/SmartThings/zigbee-switch/src/aqara-light/init.lua @@ -2,6 +2,7 @@ local clusters = require "st.zigbee.zcl.clusters" local cluster_base = require "st.zigbee.cluster_base" local data_types = require "st.zigbee.data_types" local capabilities = require "st.capabilities" +local preferences = require "preferences" local OnOff = clusters.OnOff local Level = clusters.Level @@ -32,13 +33,15 @@ local function do_refresh(self, device) device:send(ColorControl.attributes.ColorTemperatureMireds:read(device)) end -local function do_configure(self, device) - device:configure() +local function device_added(driver, device, event) device:send(cluster_base.write_manufacturer_specific_attribute(device, PRIVATE_CLUSTER_ID, PRIVATE_ATTRIBUTE_ID, MFG_CODE, data_types.Uint8, 1)) -- private +end + +local function do_configure(self, device) + device:configure() - device:send(Level.attributes.OnTransitionTime:write(device, 0)) - device:send(Level.attributes.OffTransitionTime:write(device, 0)) + preferences.sync_preferences(self, device) device:send(ColorControl.commands.MoveToColorTemperature(device, 200, 0x0000)) do_refresh(self, device) @@ -54,6 +57,7 @@ end local aqara_light_handler = { NAME = "Aqara Light Handler", lifecycle_handlers = { + added = device_added, doConfigure = do_configure }, capability_handlers = { diff --git a/drivers/SmartThings/zigbee-switch/src/preferences.lua b/drivers/SmartThings/zigbee-switch/src/preferences.lua index 64c003eb56..f0170aaf40 100644 --- a/drivers/SmartThings/zigbee-switch/src/preferences.lua +++ b/drivers/SmartThings/zigbee-switch/src/preferences.lua @@ -54,7 +54,19 @@ preferences.update_preferences = function(driver, device, args) local prefs = preferences.get_device_parameters(device) if prefs ~= nil then for id, value in pairs(device.preferences) do - if not (args and args.old_st_store) or (args.old_st_store.preferences[id] ~= value and prefs and prefs[id]) then + if not (args and args.old_st_store and args.old_st_store.preferences) or (args.old_st_store.preferences[id] ~= value and prefs and prefs[id]) then + local message = prefs[id](device, value) + device:send(message) + end + end + end +end + +preferences.sync_preferences = function(driver, device) + local prefs = preferences.get_device_parameters(device) + if prefs ~= nil then + for id, value in pairs(device.preferences) do + if prefs and prefs[id] then local message = prefs[id](device, value) device:send(message) end diff --git a/drivers/SmartThings/zigbee-switch/src/test/test_aqara_led_bulb.lua b/drivers/SmartThings/zigbee-switch/src/test/test_aqara_led_bulb.lua index f3b86453dd..45bc9f3242 100644 --- a/drivers/SmartThings/zigbee-switch/src/test/test_aqara_led_bulb.lua +++ b/drivers/SmartThings/zigbee-switch/src/test/test_aqara_led_bulb.lua @@ -52,21 +52,24 @@ end test.set_test_init_function(test_init) +test.register_coroutine_test( + "Handle added lifecycle", + function() + test.socket.zigbee:__set_channel_ordering("relaxed") + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + + test.socket.zigbee:__expect_send({ + mock_device.id, cluster_base.write_manufacturer_specific_attribute(mock_device, PRIVATE_CLUSTER_ID, + PRIVATE_ATTRIBUTE_ID, MFG_CODE, data_types.Uint8, 1) }) + end +) + test.register_coroutine_test( "Configure should configure all necessary attributes and refresh device", function() test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) test.socket.zigbee:__set_channel_ordering("relaxed") - test.socket.zigbee:__expect_send( - { - mock_device.id, - cluster_base.write_manufacturer_specific_attribute(mock_device, PRIVATE_CLUSTER_ID, PRIVATE_ATTRIBUTE_ID - , MFG_CODE, data_types.Uint8, 1) - } - ) - test.socket.zigbee:__expect_send({ mock_device.id, Level.attributes.OnTransitionTime:write(mock_device, 0) }) - test.socket.zigbee:__expect_send({ mock_device.id, Level.attributes.OffTransitionTime:write(mock_device, 0) }) test.socket.zigbee:__expect_send( { mock_device.id, diff --git a/drivers/SmartThings/zigbee-switch/src/test/test_aqara_light.lua b/drivers/SmartThings/zigbee-switch/src/test/test_aqara_light.lua index a9517ab626..6bd83a7afa 100644 --- a/drivers/SmartThings/zigbee-switch/src/test/test_aqara_light.lua +++ b/drivers/SmartThings/zigbee-switch/src/test/test_aqara_light.lua @@ -33,6 +33,7 @@ local TURN_OFF_INDICATOR_ATTRIBUTE_ID = 0x0203 local mock_device = test.mock_device.build_test_zigbee_device( { profile = t_utils.get_profile_definition("aqara-light.yml"), + preferences = { ["stse.lightFadeInTimeInSec"] = 0, ["stse.lightFadeOutTimeInSec"] = 0 }, fingerprinted_endpoint_id = 0x01, zigbee_endpoints = { [1] = { @@ -53,21 +54,27 @@ end test.set_test_init_function(test_init) +test.register_coroutine_test( + "Handle added lifecycle", + function() + test.socket.zigbee:__set_channel_ordering("relaxed") + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + + test.socket.zigbee:__expect_send({ + mock_device.id, cluster_base.write_manufacturer_specific_attribute(mock_device, PRIVATE_CLUSTER_ID, + PRIVATE_ATTRIBUTE_ID, MFG_CODE, data_types.Uint8, 1) }) + end +) + test.register_coroutine_test( "Configure should configure all necessary attributes and refresh device", function() test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) test.socket.zigbee:__set_channel_ordering("relaxed") - test.socket.zigbee:__expect_send( - { - mock_device.id, - cluster_base.write_manufacturer_specific_attribute(mock_device, PRIVATE_CLUSTER_ID, PRIVATE_ATTRIBUTE_ID - , MFG_CODE, data_types.Uint8, 1) - } - ) test.socket.zigbee:__expect_send({ mock_device.id, Level.attributes.OnTransitionTime:write(mock_device, 0) }) test.socket.zigbee:__expect_send({ mock_device.id, Level.attributes.OffTransitionTime:write(mock_device, 0) }) + test.socket.zigbee:__expect_send( { mock_device.id, diff --git a/drivers/SmartThings/zwave-sensor/src/preferences.lua b/drivers/SmartThings/zwave-sensor/src/preferences.lua index a83f49eeb8..48ee75d78e 100644 --- a/drivers/SmartThings/zwave-sensor/src/preferences.lua +++ b/drivers/SmartThings/zwave-sensor/src/preferences.lua @@ -156,7 +156,7 @@ preferences.update_preferences = function(driver, device, args) local prefs = preferences.get_device_parameters(device) if prefs ~= nil then for id, value in pairs(device.preferences) do - if not (args and args.old_st_store) or (args.old_st_store.preferences[id] ~= value and prefs and prefs[id]) then + if not (args and args.old_st_store and args.old_st_store.preferences) or (args.old_st_store.preferences[id] ~= value and prefs and prefs[id]) then local new_parameter_value = preferences.to_numeric_value(device.preferences[id]) device:send(Configuration:Set({parameter_number = prefs[id].parameter_number, size = prefs[id].size, configuration_value = new_parameter_value})) end diff --git a/drivers/SmartThings/zwave-smoke-alarm/src/fibaro-smoke-sensor/init.lua b/drivers/SmartThings/zwave-smoke-alarm/src/fibaro-smoke-sensor/init.lua index 1e0b456002..a4d62fa1a4 100644 --- a/drivers/SmartThings/zwave-smoke-alarm/src/fibaro-smoke-sensor/init.lua +++ b/drivers/SmartThings/zwave-smoke-alarm/src/fibaro-smoke-sensor/init.lua @@ -77,6 +77,7 @@ local fibaro_smoke_sensor = { }, NAME = "fibaro smoke sensor", can_handle = can_handle_fibaro_smoke_sensor, + health_check = false, } return fibaro_smoke_sensor diff --git a/drivers/SmartThings/zwave-smoke-alarm/src/init.lua b/drivers/SmartThings/zwave-smoke-alarm/src/init.lua index 17f6348474..0d0a5d1bfd 100644 --- a/drivers/SmartThings/zwave-smoke-alarm/src/init.lua +++ b/drivers/SmartThings/zwave-smoke-alarm/src/init.lua @@ -30,7 +30,7 @@ local preferencesMap = require "preferences" local function update_preferences(self, device, args) local preferences = preferencesMap.get_device_parameters(device) for id, value in pairs(device.preferences) do - if not (args and args.old_st_store) or (args.old_st_store.preferences[id] ~= value and preferences and preferences[id]) then + if not (args and args.old_st_store and args.old_st_store.preferences) or (args.old_st_store.preferences[id] ~= value and preferences and preferences[id]) then local new_parameter_value = preferencesMap.to_numeric_value(device.preferences[id]) device:send(Configuration:Set({parameter_number = preferences[id].parameter_number, size = preferences[id].size, configuration_value = new_parameter_value})) end