diff --git a/drivers/SmartThings/zigbee-switch/src/init.lua b/drivers/SmartThings/zigbee-switch/src/init.lua index 4d5295b3d0..15241cd004 100644 --- a/drivers/SmartThings/zigbee-switch/src/init.lua +++ b/drivers/SmartThings/zigbee-switch/src/init.lua @@ -140,6 +140,7 @@ local zigbee_switch_driver_template = { capabilities.motionSensor }, sub_drivers = { + lazy_load_if_possible("non_zigbee_devices"), lazy_load_if_possible("hanssem"), lazy_load_if_possible("aqara"), lazy_load_if_possible("aqara-light"), diff --git a/drivers/SmartThings/zigbee-switch/src/non_zigbee_devices/init.lua b/drivers/SmartThings/zigbee-switch/src/non_zigbee_devices/init.lua new file mode 100644 index 0000000000..bc6caa8580 --- /dev/null +++ b/drivers/SmartThings/zigbee-switch/src/non_zigbee_devices/init.lua @@ -0,0 +1,57 @@ +-- Copyright 2025 SmartThings +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + +-- This is a patch for the zigbee-switch driver to fix https://smartthings.atlassian.net/browse/CHAD-16558 +-- Several hubs were found that had zigbee switch drivers hosting zwave devices. +-- This patch works around it until hubcore 0.59 is released with +-- https://smartthings.atlassian.net/browse/CHAD-16552 + +local st_device = require "st.device" +local log = require "log" + +local function can_handle(opts, driver, device) + if device.network_type ~= st_device.NETWORK_TYPE_ZIGBEE and device.network_type ~= st_device.NETWORK_TYPE_CHILD then + return true, require("non_zigbee_devices") + end + return false +end + +local function device_added(driver, device, event) + log.info(string.format("Non zigbee device added: %s", device)) +end + +local function device_init(driver, device, event) + log.info(string.format("Non zigbee device init: %s", device)) +end + +local function do_configure(driver, device) + log.info(string.format("Non zigbee do configure: %s", device)) +end + +local function info_changed(driver, device, event, args) + log.info(string.format("Non zigbee infoChanged: %s", device)) +end + +local non_zigbee_devices = { + NAME = "non zigbee devices filter", + lifecycle_handlers = { + init = device_init, + added = device_added, + doConfigure = do_configure, + infoChanged = info_changed + }, + can_handle = can_handle +} + +return non_zigbee_devices \ No newline at end of file diff --git a/drivers/SmartThings/zigbee-switch/src/test/test_bad_device_kind.lua b/drivers/SmartThings/zigbee-switch/src/test/test_bad_device_kind.lua new file mode 100644 index 0000000000..3f66d675c9 --- /dev/null +++ b/drivers/SmartThings/zigbee-switch/src/test/test_bad_device_kind.lua @@ -0,0 +1,58 @@ +-- Copyright 2025 SmartThings +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + +local test = require "integration_test" +local t_utils = require "integration_test.utils" +local dkjson = require 'dkjson' + +-- This test attempts to add a zwave device to this zigbee switch driver +-- Once the monkey-patch is removed with hubcore 59 is released with: +-- https://smartthings.atlassian.net/browse/CHAD-16552 +local mock_device = test.mock_device.build_test_zwave_device({ + profile = t_utils.get_profile_definition("on-off-level.yml"), +}) + +local function test_init() + test.mock_device.add_test_device(mock_device) +end + +test.set_test_init_function(test_init) + +-- Just validating that the driver doesn't crash is enough to validate +-- that the work-around is effective in ignoring the incorrect device kind +test.register_coroutine_test("zwave_device_handled", function() + test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.wait_for_events() + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + test.wait_for_events() + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) + mock_device:expect_metadata_update({provisioning_state = "PROVISIONED"}) + test.wait_for_events() + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "infoChanged", dkjson.encode(mock_device.raw_st_data) }) + test.wait_for_events() + end, + nil +) + +test.register_message_test( + "Capability command for incorrect protocol", + { + channel = "capability", + direction = "receive", + message = { mock_device.id, { capability = "switch", component = "main", command = "on", args = { } } } + } +) + +test.run_registered_tests()