From 71129df0f43cbf8d0e2a8cb966807148e5391697 Mon Sep 17 00:00:00 2001 From: Steven Green Date: Mon, 18 Nov 2024 16:44:54 -0800 Subject: [PATCH 01/14] CHAD-14369 Add ezex valve sub-driver Old version of this valve use the IAS Zone Status to report low battery and do not otherwise support the PowerConfiguration cluster, which is usually used for reporting the battery. The porting work done for the DTH missed this behavior because it was removed. This adds back in the old behavior, but only for devices that do not support PowerConfiguration, which should be rare, as the old behavior is not ideal. --- .../zigbee-valve/src/ezex/init.lua | 80 +++++ drivers/SmartThings/zigbee-valve/src/init.lua | 3 +- .../zigbee-valve/src/test/test_ezex_valve.lua | 321 ++++++++++++++++++ 3 files changed, 403 insertions(+), 1 deletion(-) create mode 100644 drivers/SmartThings/zigbee-valve/src/ezex/init.lua create mode 100644 drivers/SmartThings/zigbee-valve/src/test/test_ezex_valve.lua diff --git a/drivers/SmartThings/zigbee-valve/src/ezex/init.lua b/drivers/SmartThings/zigbee-valve/src/ezex/init.lua new file mode 100644 index 0000000000..53eddb5a1c --- /dev/null +++ b/drivers/SmartThings/zigbee-valve/src/ezex/init.lua @@ -0,0 +1,80 @@ +-- Copyright 2024 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 clusters = require "st.zigbee.zcl.clusters" +local capabilities = require "st.capabilities" + +local IASZone = clusters.IASZone +local Basic = clusters.Basic +local OnOff = clusters.OnOff + +local configuration = { + { + cluster = IASZone.ID, + attribute = IASZone.attributes.ZoneStatus.ID, + minimum_interval = 0, + maximum_interval = 3600, + data_type = IASZone.attributes.ZoneStatus.base_type, + reportable_change = 1 + }, + { + cluster = Basic.ID, + attribute = Basic.attributes.PowerSource.ID, + minimum_interval = 30, + maximum_interval = 21600, + data_type = Basic.attributes.PowerSource.base_type, + }, + { + cluster = OnOff.ID, + attribute = OnOff.attributes.OnOff.ID, + minimum_interval = 0, + maximum_interval = 600, + data_type = OnOff.attributes.OnOff.base_type + } +} + +local function ias_zone_status_attr_handler(driver, device, zone_status, zb_rx) + -- this is cribbed from the DTH + if zone_status:is_battery_low_set() then + device:emit_event(capabilities.battery.battery(5)) + else + device:emit_event(capabilities.battery.battery(50)) + end +end + +local function device_init(driver, device) + for _, attribute in ipairs(configuration) do + device:add_configured_attribute(attribute) + device:add_monitored_attribute(attribute) + end +end + +local ezex_valve = { + NAME = "Ezex Valve", + zigbee_handlers = { + attr = { + [IASZone.ID] = { + [IASZone.attributes.ZoneStatus.ID] = ias_zone_status_attr_handler + }, + } + }, + lifecycle_handlers = { + init = device_init + }, + can_handle = function(opts, driver, device, ...) + return device:get_model() == "E253-KR0B0ZX-HA" and not device:supports_server_cluster(clusters.PowerConfiguration.ID) + end +} + +return ezex_valve diff --git a/drivers/SmartThings/zigbee-valve/src/init.lua b/drivers/SmartThings/zigbee-valve/src/init.lua index 693a0cf311..bc2059522d 100644 --- a/drivers/SmartThings/zigbee-valve/src/init.lua +++ b/drivers/SmartThings/zigbee-valve/src/init.lua @@ -52,7 +52,8 @@ local zigbee_valve_driver_template = { added = device_added }, sub_drivers = { - require("sinope") + require("sinope"), + require("ezex") } } diff --git a/drivers/SmartThings/zigbee-valve/src/test/test_ezex_valve.lua b/drivers/SmartThings/zigbee-valve/src/test/test_ezex_valve.lua new file mode 100644 index 0000000000..60db8c2535 --- /dev/null +++ b/drivers/SmartThings/zigbee-valve/src/test/test_ezex_valve.lua @@ -0,0 +1,321 @@ +-- Copyright 2024 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. + +-- Mock out globals +local test = require "integration_test" +local clusters = require "st.zigbee.zcl.clusters" +local Basic = clusters.Basic +local OnOff = clusters.OnOff +local IASZone = clusters.IASZone +local capabilities = require "st.capabilities" +local zigbee_test_utils = require "integration_test.zigbee_test_utils" +local t_utils = require "integration_test.utils" + +local mock_device = test.mock_device.build_test_zigbee_device( + { profile = t_utils.get_profile_definition("valve-battery-powerSource.yml"), + zigbee_endpoints = { + [1] = { + id = 1, + manufacturer = "", + model = "E253-KR0B0ZX-HA", + server_clusters = {0x0000, 0x0006, 0x0500} + } + } + } +) + +zigbee_test_utils.prepare_zigbee_env_info() +local function test_init() + test.mock_device.add_test_device(mock_device) + zigbee_test_utils.init_noop_health_check_timer() +end + +test.set_test_init_function(test_init) + +test.register_message_test( + "OnOff(on) reporting should be handled", + { + { + channel = "zigbee", + direction = "receive", + message = { mock_device.id, OnOff.attributes.OnOff:build_test_attr_report(mock_device, + true) } + }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("main", capabilities.valve.valve.open()) + } + } +) + + +test.register_message_test( + "OnOff(off) reporting should be handled", + { + { + channel = "zigbee", + direction = "receive", + message = { mock_device.id, OnOff.attributes.OnOff:build_test_attr_report(mock_device, + false) } + }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("main", capabilities.valve.valve.closed()) + } + } +) + +test.register_message_test( + "Battery percentage report should be handled", + { + { + channel = "zigbee", + direction = "receive", + message = { mock_device.id, IASZone.attributes.ZoneStatus:build_test_attr_report(mock_device, 0x0008) } + }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("main", capabilities.battery.battery(5)) + } + } +) + +test.register_message_test( + "PowerSource(unknown) reporting should be handled", + { + { + channel = "zigbee", + direction = "receive", + message = { mock_device.id, Basic.attributes.PowerSource:build_test_attr_report(mock_device, + 0x00) } + }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("main", capabilities.powerSource.powerSource.unknown()) + } + } +) + +test.register_message_test( + "PowerSource(mains) reporting should be handled", + { + { + channel = "zigbee", + direction = "receive", + message = { mock_device.id, Basic.attributes.PowerSource:build_test_attr_report(mock_device, + 0x01) } + }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("main", capabilities.powerSource.powerSource.mains()) + } + } +) + +test.register_message_test( + "PowerSource(battery) reporting should be handled", + { + { + channel = "zigbee", + direction = "receive", + message = { mock_device.id, Basic.attributes.PowerSource:build_test_attr_report(mock_device, + 0x03) } + }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("main", capabilities.powerSource.powerSource.battery()) + } + } +) + +test.register_message_test( + "PowerSource(dc) reporting should be handled", + { + { + channel = "zigbee", + direction = "receive", + message = { mock_device.id, Basic.attributes.PowerSource:build_test_attr_report(mock_device, + 0x04) } + }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("main", capabilities.powerSource.powerSource.dc()) + } + } +) + +test.register_message_test( + "Capability(valve) command(open) on should be handled", + { + { + channel = "capability", + direction = "receive", + message = { mock_device.id, { capability = "valve", component = "main", command = "open", args = { } } } + }, + { + channel = "zigbee", + direction = "send", + message = { mock_device.id, OnOff.server.commands.On(mock_device) } + } + } +) + +test.register_message_test( + "Capability(valve) command(off) on should be handled", + { + { + channel = "capability", + direction = "receive", + message = { mock_device.id, { capability = "valve", component = "main", command = "close", args = { } } } + }, + { + channel = "zigbee", + direction = "send", + message = { mock_device.id, OnOff.server.commands.Off(mock_device) } + } + } +) + +test.register_coroutine_test( + "doConfigure lifecycle should configure device", + function () + -- test.socket.zigbee:__set_channel_ordering("relaxed") + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) + test.socket.zigbee:__expect_send({ + mock_device.id, + Basic.attributes.PowerSource:read(mock_device) + }) + test.socket.zigbee:__expect_send({ + mock_device.id, + OnOff.attributes.OnOff:read(mock_device) + }) + test.socket.zigbee:__expect_send({ + mock_device.id, + IASZone.attributes.ZoneStatus:read(mock_device) + }) + test.socket.zigbee:__expect_send({ + mock_device.id, + zigbee_test_utils.build_bind_request(mock_device, zigbee_test_utils.mock_hub_eui, Basic.ID) + }) + test.socket.zigbee:__expect_send({ + mock_device.id, + Basic.attributes.PowerSource:configure_reporting(mock_device, 30, 21600) + }) + test.socket.zigbee:__expect_send({ + mock_device.id, + zigbee_test_utils.build_bind_request(mock_device, zigbee_test_utils.mock_hub_eui, OnOff.ID) + }) + test.socket.zigbee:__expect_send({ + mock_device.id, + OnOff.attributes.OnOff:configure_reporting(mock_device, 0, 600, 0) + }) + test.socket.zigbee:__expect_send({ + mock_device.id, + zigbee_test_utils.build_bind_request(mock_device, zigbee_test_utils.mock_hub_eui, IASZone.ID) + }) + test.socket.zigbee:__expect_send({ + mock_device.id, + IASZone.attributes.ZoneStatus:configure_reporting(mock_device, 0, 3600, 1) + }) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + end +) + +test.register_message_test( + "Refresh should read all necessary attributes", + { + { + channel = "capability", + direction = "receive", + message = { + mock_device.id, + { capability = "refresh", component = "main", command = "refresh", args = {} } + } + }, + { + channel = "zigbee", + direction = "send", + message = { + mock_device.id, + Basic.attributes.PowerSource:read(mock_device) + } + }, + { + channel = "zigbee", + direction = "send", + message = { + mock_device.id, + OnOff.attributes.OnOff:read(mock_device) + } + }, + { + channel = "zigbee", + direction = "send", + message = { + mock_device.id, + IASZone.attributes.ZoneStatus:read(mock_device) + } + } + }, + { + inner_block_ordering = "relaxed" + } +) + +test.register_message_test( + "Device added event should refresh device states", + { + { + channel = "device_lifecycle", + direction = "receive", + message = { mock_device.id, "added" }, + }, + { + channel = "zigbee", + direction = "send", + message = { + mock_device.id, + Basic.attributes.PowerSource:read(mock_device) + } + }, + { + channel = "zigbee", + direction = "send", + message = { + mock_device.id, + OnOff.attributes.OnOff:read(mock_device) + } + }, + { + channel = "zigbee", + direction = "send", + message = { + mock_device.id, + IASZone.attributes.ZoneStatus:read(mock_device) + } + } + }, + { + inner_block_ordering = "relaxed" + } +) + +test.run_registered_tests() From a45711ce0efea097e36d4d84fdfb8c0f7542cb38 Mon Sep 17 00:00:00 2001 From: nickolas-deboom <158304111+nickolas-deboom@users.noreply.github.com> Date: Wed, 20 Nov 2024 13:47:41 -0600 Subject: [PATCH 02/14] Add Sonoff M5-2C to child profile override list (#1755) --- drivers/SmartThings/matter-switch/src/init.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/SmartThings/matter-switch/src/init.lua b/drivers/SmartThings/matter-switch/src/init.lua index bb19b6a5fd..3fab77fa3a 100644 --- a/drivers/SmartThings/matter-switch/src/init.lua +++ b/drivers/SmartThings/matter-switch/src/init.lua @@ -151,6 +151,7 @@ local device_type_attribute_map = { } local child_device_profile_overrides = { + { vendor_id = 0x1321, product_id = 0x000C, child_profile = "switch-binary" }, { vendor_id = 0x1321, product_id = 0x000D, child_profile = "switch-binary" }, } From 3d6c57d32a2862a594dd6d835416bcc61a023d8a Mon Sep 17 00:00:00 2001 From: Alissa Dornbos <79465613+lelandblue@users.noreply.github.com> Date: Thu, 21 Nov 2024 11:27:19 -0500 Subject: [PATCH 03/14] Adding fingerprint for US03 U Tech device (#1767) PID: 0004 VID: 147F --- drivers/SmartThings/matter-switch/fingerprints.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/SmartThings/matter-switch/fingerprints.yml b/drivers/SmartThings/matter-switch/fingerprints.yml index 7ff7ca1672..c1b57ecf8b 100644 --- a/drivers/SmartThings/matter-switch/fingerprints.yml +++ b/drivers/SmartThings/matter-switch/fingerprints.yml @@ -532,6 +532,11 @@ matterManufacturer: vendorId: 0x147F productId: 0x0003 deviceProfileName: plug-binary + - id: "5247/4" + deviceLabel: U-tec Smart Matter Switch + vendorId: 0x147F + productId: 0x0004 + deviceProfileName: switch-binary #WiZ - id: "WiZ A19" deviceLabel: WiZ A19 From e6ace5d60269d240fdb3a02f723d68e1e8f43d82 Mon Sep 17 00:00:00 2001 From: cjswedes Date: Mon, 25 Nov 2024 11:12:54 -0600 Subject: [PATCH 04/14] Update github dawidd6/action-download-artifact for security advisory See https://github.com/SmartThingsCommunity/SmartThingsEdgeDrivers/security/dependabot/5 --- .github/workflows/create-channel.yml | 4 ++-- .github/workflows/duplicate-profiles-comment.yml | 2 +- .github/workflows/publish-test-results.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/create-channel.yml b/.github/workflows/create-channel.yml index e86e4fc6d5..f3a287748c 100644 --- a/.github/workflows/create-channel.yml +++ b/.github/workflows/create-channel.yml @@ -14,7 +14,7 @@ jobs: head_ref: ${{ steps.head_ref.outputs.head_ref }} steps: - name: Download artifacts - uses: dawidd6/action-download-artifact@v2 + uses: dawidd6/action-download-artifact@v6 with: workflow: upload-driver-packages.yml run_id: ${{ github.event.workflow_run.id }} @@ -90,7 +90,7 @@ jobs: driver: ${{ fromJSON(needs.download-artifacts.outputs.drivers) }} steps: - name: Download artifacts - uses: dawidd6/action-download-artifact@v2 + uses: dawidd6/action-download-artifact@v6 with: workflow: upload-driver-packages.yml name: ${{ matrix.driver }} diff --git a/.github/workflows/duplicate-profiles-comment.yml b/.github/workflows/duplicate-profiles-comment.yml index 9d1ed8aea3..478b4cbd15 100644 --- a/.github/workflows/duplicate-profiles-comment.yml +++ b/.github/workflows/duplicate-profiles-comment.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Download comment artifact - uses: dawidd6/action-download-artifact@v2 + uses: dawidd6/action-download-artifact@v6 with: workflow: duplicate-profiles.yml run_id: ${{ github.event.workflow_run.id }} diff --git a/.github/workflows/publish-test-results.yml b/.github/workflows/publish-test-results.yml index 02d4da0005..57c8812913 100644 --- a/.github/workflows/publish-test-results.yml +++ b/.github/workflows/publish-test-results.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Download artifacts - uses: dawidd6/action-download-artifact@v2 + uses: dawidd6/action-download-artifact@v6 with: workflow: run-tests.yml run_id: ${{ github.event.workflow_run.id }} From dd3d1cde9cca6b87eed01c10dc137978b48c2b3b Mon Sep 17 00:00:00 2001 From: cjswedes Date: Mon, 25 Nov 2024 09:13:37 -0600 Subject: [PATCH 05/14] Disable default healthcheck functionality for zigbee-valve This monitoring is not necessary to keep these devices online. Tested with leaksmart valves. --- drivers/SmartThings/zwave-valve/src/init.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/SmartThings/zwave-valve/src/init.lua b/drivers/SmartThings/zwave-valve/src/init.lua index 7392f1cbe1..36d6c65ea8 100644 --- a/drivers/SmartThings/zwave-valve/src/init.lua +++ b/drivers/SmartThings/zwave-valve/src/init.lua @@ -29,7 +29,8 @@ local driver_template = { sub_drivers = { -- Fortrezz and Zooz valves treat open as "off" and close as "on" require("inverse_valve") - } + }, + health_check = false, } defaults.register_for_default_handlers(driver_template, driver_template.supported_capabilities) From e2547bee72beea90bec7b9c3f5c753379b331296 Mon Sep 17 00:00:00 2001 From: cjswedes Date: Mon, 25 Nov 2024 10:30:23 -0600 Subject: [PATCH 06/14] Remove healthcheck functionality from zigbee-dimmer-remote This functionality is not needed to keep the device online. When testing with the sengled dimmer remote it was discovered that the device needs a faster battery reporting interval than what is default to stay online (even with healthcheck enabled) --- .../zigbee-dimmer-remote/src/init.lua | 20 +++++++++++++++++- .../test_zigbee_battery_accessory_dimmer.lua | Bin 20954 -> 22479 bytes .../CentraliteSystems/init.lua | 20 +++++++++++++++++- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/drivers/SmartThings/zigbee-dimmer-remote/src/init.lua b/drivers/SmartThings/zigbee-dimmer-remote/src/init.lua index 1ee1a1e2b2..9e45b9dbad 100644 --- a/drivers/SmartThings/zigbee-dimmer-remote/src/init.lua +++ b/drivers/SmartThings/zigbee-dimmer-remote/src/init.lua @@ -15,6 +15,20 @@ local capabilities = require "st.capabilities" local ZigbeeDriver = require "st.zigbee" local defaults = require "st.zigbee.defaults" +local zcl_clusters = require "st.zigbee.zcl.clusters" + +local battery_attribute_configuration = { + cluster = zcl_clusters.PowerConfiguration.ID, + attribute = zcl_clusters.PowerConfiguration.attributes.BatteryPercentageRemaining.ID, + minimum_interval = 30, + maximum_interval = 14300, -- ~4hrs + data_type = zcl_clusters.PowerConfiguration.attributes.BatteryPercentageRemaining.base_type, + reportable_change = 1 +} + +local function device_init(driver, device) + device:add_configured_attribute(battery_attribute_configuration) +end local zigbee_dimmer_remote_driver_template = { supported_capabilities = { @@ -23,7 +37,11 @@ local zigbee_dimmer_remote_driver_template = { capabilities.switch, capabilities.switchLevel }, - sub_drivers = { require("zigbee-accessory-dimmer"), require("zigbee-battery-accessory-dimmer")} + lifecycle_handlers = { + init = device_init, + }, + sub_drivers = { require("zigbee-accessory-dimmer"), require("zigbee-battery-accessory-dimmer")}, + health_check = false, } defaults.register_for_default_handlers(zigbee_dimmer_remote_driver_template, zigbee_dimmer_remote_driver_template.supported_capabilities) diff --git a/drivers/SmartThings/zigbee-dimmer-remote/src/test/test_zigbee_battery_accessory_dimmer.lua b/drivers/SmartThings/zigbee-dimmer-remote/src/test/test_zigbee_battery_accessory_dimmer.lua index bcb7ea5b9836bfd3d76cdb12fde30d10f9b06b91..b16fe8cd11536c8bf2e155496b8b72e4c2497dc6 100644 GIT binary patch delta 233 zcmcb$nDP92#tnyAC$n(Min}=*8rJG?DZoK;PG)Le$>fc!CX70hd)f6i3$qD&a~PT! z8yM&)7*1yNH=GIyYRcpqj|r3Csc;J^D5c~(=jWwmrk56_ zDk;=za!r=?oj+MYLS(YEo5JKeKcUIoUhf!GvdXogX(NT)_c<)yX;B sA}mFzi7AsW3dl_6^lw0yoctv~0b~N7j)F1BQK)X?0V-#oTpXAV0D?G2B>(^b delta 42 zcmV+_0M-A`uL0Vl0kFdblL-bQlWhqclkf);vswlbO9L`7Hj^J$LX)sjTa&q07Ew+P A`2YX_ diff --git a/drivers/SmartThings/zigbee-dimmer-remote/src/zigbee-battery-accessory-dimmer/CentraliteSystems/init.lua b/drivers/SmartThings/zigbee-dimmer-remote/src/zigbee-battery-accessory-dimmer/CentraliteSystems/init.lua index 85afaa3b40..0734bf57e8 100644 --- a/drivers/SmartThings/zigbee-dimmer-remote/src/zigbee-battery-accessory-dimmer/CentraliteSystems/init.lua +++ b/drivers/SmartThings/zigbee-dimmer-remote/src/zigbee-battery-accessory-dimmer/CentraliteSystems/init.lua @@ -87,6 +87,24 @@ local is_centralite_systems = function(opts, driver, device) return false end +local voltage_configuration = { + cluster = zcl_clusters.PowerConfiguration.ID, + attribute = zcl_clusters.PowerConfiguration.attributes.BatteryVoltage.ID, + minimum_interval = 30, + maximum_interval = 14300, + data_type = zcl_clusters.PowerConfiguration.attributes.BatteryVoltage.base_type, + reportable_change = 1 +} + +local function device_init(driver, device) + device:add_configured_attribute(voltage_configuration) + device:add_monitored_attribute(voltage_configuration) + device:remove_monitored_attribute(zcl_clusters.PowerConfiguration.ID, zcl_clusters.PowerConfiguration.attributes.BatteryPercentageRemaining.ID) + device:remove_configured_attribute(zcl_clusters.PowerConfiguration.ID, zcl_clusters.PowerConfiguration.attributes.BatteryPercentageRemaining.ID) + device:set_field(battery_defaults.DEVICE_MIN_VOLTAGE_KEY, 2.3) + device:set_field(battery_defaults.DEVICE_MAX_VOLTAGE_KEY, 3.0) +end + local centralite_systems = { NAME = "centralite systems", zigbee_handlers = { @@ -98,7 +116,7 @@ local centralite_systems = { } }, lifecycle_handlers = { - init = battery_defaults.build_linear_voltage_init(2.3, 3.0), + init = device_init, doConfigure = do_configure }, can_handle = is_centralite_systems From f16a00919746fa771c5db1105cdb0378d8e80867 Mon Sep 17 00:00:00 2001 From: cjswedes Date: Mon, 25 Nov 2024 10:33:48 -0600 Subject: [PATCH 07/14] Remove health check functionality from zigbee-sound-sensor This functionality is not needed to keep devices online. Tested with the Ecolink Sound sensor --- drivers/SmartThings/zigbee-sound-sensor/src/init.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/SmartThings/zigbee-sound-sensor/src/init.lua b/drivers/SmartThings/zigbee-sound-sensor/src/init.lua index fb972bd5b5..f5b4d0d07f 100644 --- a/drivers/SmartThings/zigbee-sound-sensor/src/init.lua +++ b/drivers/SmartThings/zigbee-sound-sensor/src/init.lua @@ -126,7 +126,8 @@ local zigbee_sound_sensor_driver_template = { added = added_handler, doConfigure = do_configure, init = battery_defaults.build_linear_voltage_init(2.2, 3.0) - } + }, + health_check = false, } defaults.register_for_default_handlers(zigbee_sound_sensor_driver_template, zigbee_sound_sensor_driver_template.supported_capabilities) From 973308e456f9cf595c085ab35beabd4a3d96edc8 Mon Sep 17 00:00:00 2001 From: hdlee27 <54927573+hdlee27@users.noreply.github.com> Date: Mon, 2 Dec 2024 22:58:57 +0900 Subject: [PATCH 08/14] Fp2:Stabilization of connection and addition of convenience functions (#1764) * fp2: add get_credential failure handling Signed-off-by: hdlee27 <54927573+hdlee27@users.noreply.github.com> * fp2: add nil check in eventsource Signed-off-by: hdlee27 <54927573+hdlee27@users.noreply.github.com> * fp2: Label change for easy distinction Signed-off-by: hdlee27 <54927573+hdlee27@users.noreply.github.com> * Offline event after reconnection attempt to prevent fake offline * fp2: remove socket connection for fp2 resource Signed-off-by: hdlee27 <54927573+hdlee27@users.noreply.github.com> * fp2: update status when sse reconnect Signed-off-by: hdlee27 <54927573+hdlee27@users.noreply.github.com> * fp2: remove unused function Signed-off-by: hdlee27 <54927573+hdlee27@users.noreply.github.com> * fp2: manage online/offline by using SSE Signed-off-by: hdlee27 <54927573+hdlee27@users.noreply.github.com> * fp2: Change function order for fast response speed Signed-off-by: hdlee27 <54927573+hdlee27@users.noreply.github.com> * fp2: add error handling for status_update Signed-off-by: hdlee27 <54927573+hdlee27@users.noreply.github.com> * fp2: check sse connection before rest api check Signed-off-by: hdlee27 <54927573+hdlee27@users.noreply.github.com> --------- Signed-off-by: hdlee27 <54927573+hdlee27@users.noreply.github.com> --- .../aqara-presence-sensor/src/discovery.lua | 9 +++- .../aqara-presence-sensor/src/fp2/api.lua | 12 +---- .../src/fp2/device_manager.lua | 1 + .../src/fp2/discovery_helper.lua | 9 +++- .../Aqara/aqara-presence-sensor/src/init.lua | 51 ++++++++++--------- .../src/lunchbox/rest.lua | 1 + .../src/lunchbox/sse/eventsource.lua | 18 ++++--- 7 files changed, 58 insertions(+), 43 deletions(-) diff --git a/drivers/Aqara/aqara-presence-sensor/src/discovery.lua b/drivers/Aqara/aqara-presence-sensor/src/discovery.lua index 88779fe6e5..fd68872679 100644 --- a/drivers/Aqara/aqara-presence-sensor/src/discovery.lua +++ b/drivers/Aqara/aqara-presence-sensor/src/discovery.lua @@ -11,9 +11,12 @@ function discovery.set_device_field(driver, device) -- persistent fields if device_cache_value ~= nil then + log.info_with({ hub_logs = true }, string.format("device found in cache. dni= %s", device.device_network_id)) device:set_field(fields.CREDENTIAL, device_cache_value.credential, { persist = true }) device:set_field(fields.DEVICE_IPV4, device_cache_value.ip, { persist = true }) device:set_field(fields.DEVICE_INFO, device_cache_value.device_info, { persist = true }) + else + log.error_with({ hub_logs = true }, string.format("device not found in cache. dni= %s", device.device_network_id)) end driver.datastore.discovery_cache[device.device_network_id] = nil @@ -40,7 +43,7 @@ local function try_add_device(driver, device_dni, device_ip) if driver.datastore.discovery_cache[device_dni] and driver.datastore.discovery_cache[device_dni].credential then log.info(string.format("use stored credential. This may have expired. dni= %s, ip= %s", device_dni, device_ip)) else - log.error(string.format("Failed to get credential. dni= %s, ip= %s", device_dni, device_ip)) + log.error_with({ hub_logs = true }, string.format("Failed to get credential. The device appears to have already generated a credential. In that case, a device reset is needed to generate a new credential. dni= %s, ip= %s", device_dni, device_ip)) return "credential not found" end else @@ -48,13 +51,14 @@ local function try_add_device(driver, device_dni, device_ip) driver.datastore.discovery_cache[device_dni].credential = credential end - log.info(string.format("try_create_device. dni= %s, ip= %s", device_dni, device_ip)) + log.info_with({ hub_logs = true }, string.format("try_create_device. dni= %s, ip= %s", device_dni, device_ip)) processing_devices[device_dni] = true driver:try_create_device(create_device_msg) return nil end function discovery.device_added(driver, device) + log.info_with({ hub_logs = true }, string.format("device_added. dni= %s", device.device_network_id)) discovery.set_device_field(driver, device) processing_devices[device.device_network_id] = nil driver.lifecycle_handlers.init(driver, device) @@ -96,6 +100,7 @@ local function discovery_device(driver) end function discovery.do_network_discovery(driver, _, should_continue) + log.info_with({ hub_logs = true }, string.format("discovery start for Aqara FP2")) while should_continue() do discovery_device(driver) socket.sleep(1) diff --git a/drivers/Aqara/aqara-presence-sensor/src/fp2/api.lua b/drivers/Aqara/aqara-presence-sensor/src/fp2/api.lua index 1c0a2ebb2b..4f27a277a3 100644 --- a/drivers/Aqara/aqara-presence-sensor/src/fp2/api.lua +++ b/drivers/Aqara/aqara-presence-sensor/src/fp2/api.lua @@ -39,16 +39,8 @@ local function process_rest_response(response, err, partial) end end -local function retry_fn(retry_attempts) - local count = 0 - return function() - count = count + 1 - return count < retry_attempts - end -end - local function do_get(api_instance, path) - return process_rest_response(api_instance.client:get(path, api_instance.headers, retry_fn(5))) + return process_rest_response(RestClient.one_shot_get(api_instance.base_url .. path, api_instance.headers, api_instance.socket_builder)) end function fp2_api.new_device_manager(device_ip, bridge_info, socket_builder) @@ -57,7 +49,7 @@ function fp2_api.new_device_manager(device_ip, bridge_info, socket_builder) return setmetatable( { headers = ADDITIONAL_HEADERS, - client = RestClient.new(base_url, socket_builder), + socket_builder = socket_builder, base_url = base_url, }, fp2_api ) diff --git a/drivers/Aqara/aqara-presence-sensor/src/fp2/device_manager.lua b/drivers/Aqara/aqara-presence-sensor/src/fp2/device_manager.lua index 1e678d80c9..66d4e8ac6c 100644 --- a/drivers/Aqara/aqara-presence-sensor/src/fp2/device_manager.lua +++ b/drivers/Aqara/aqara-presence-sensor/src/fp2/device_manager.lua @@ -256,6 +256,7 @@ function device_manager.is_valid_connection(driver, device, conn_info) device.device_network_id)) return false end + local _, err, status = conn_info:get_attr() if err or status ~= 200 then log.warn(string.format( diff --git a/drivers/Aqara/aqara-presence-sensor/src/fp2/discovery_helper.lua b/drivers/Aqara/aqara-presence-sensor/src/fp2/discovery_helper.lua index 7a0e28917a..dcc24b61dd 100644 --- a/drivers/Aqara/aqara-presence-sensor/src/fp2/discovery_helper.lua +++ b/drivers/Aqara/aqara-presence-sensor/src/fp2/discovery_helper.lua @@ -33,10 +33,17 @@ function discovery_helper.get_device_create_msg(driver, device_dni, device_ip) return nil end + local device_label = device_info.label or "Aqara-FP2" + if device_dni then + -- To make it easier to distinguish devices, add the last four letters of dni to the label + -- for example, if device_info.label is "Aqara-FP2" and device_dni is "00:11:22:33:44:55", then device_label will be "Aqara-FP2 (4455)" + device_label = string.format("%s (%s)", device_label, string.sub(string.gsub(tostring(device_dni), ":", ""), -4)) + end + local create_device_msg = { type = "LAN", device_network_id = device_dni, - label = device_info.label, + label = device_label, profile = "aqara-fp2-zoneDetection", manufacturer = device_info.manufacturerName, model = device_info.modelName, diff --git a/drivers/Aqara/aqara-presence-sensor/src/init.lua b/drivers/Aqara/aqara-presence-sensor/src/init.lua index 4080650618..c0d0e953b9 100644 --- a/drivers/Aqara/aqara-presence-sensor/src/init.lua +++ b/drivers/Aqara/aqara-presence-sensor/src/init.lua @@ -20,32 +20,27 @@ local function status_update(driver, device) local conn_info = device:get_field(fields.CONN_INFO) if not conn_info then log.warn(string.format("refresh : failed to find conn_info, dni = %s", device.device_network_id)) + return false, "failed to find conn_info" else local resp, err, status = conn_info:get_attr() if err or status ~= 200 then log.error(string.format("refresh : failed to get attr, dni= %s, err= %s, status= %s", device.device_network_id, err, status)) - if status == 404 then - device:offline() - end + return false, "failed to get attr" else driver.device_manager.handle_status(driver, device, resp) end end + return true end local function create_sse(driver, device, credential) local conn_info = device:get_field(fields.CONN_INFO) - if not driver.device_manager.is_valid_connection(driver, device, conn_info) then - log.warn("create_sse : invalid connection") - return - end - local sse_url = driver.device_manager.get_sse_url(driver, device, conn_info) if not sse_url then - log.error("failed to get sse_url") + log.error_with({ hub_logs = true }, "failed to get sse_url") else log.trace(string.format("Creating SSE EventSource for %s, sse_url= %s", device.device_network_id, sse_url)) local label = string.format("%s-SSE", device.device_network_id) @@ -64,7 +59,16 @@ local function create_sse(driver, device, credential) end eventsource.onopen = function() + log.info_with({ hub_logs = true }, string.format("Eventsource open: dni= %s", device.device_network_id)) device:online() + local success, err = status_update(driver, device) + if not success then + log.warn(string.format("Failed to status_update during eventsource.onopen, err = %s dni= %s", err, device.device_network_id)) + success, err = status_update(driver, device) + if not success then + log.error_with({ hub_logs = true }, string.format("Failed to status_update during eventsource.onopen again, err = %s dni= %s", err, device.device_network_id)) + end + end end local old_eventsource = device:get_field(fields.EVENT_SOURCE) @@ -104,14 +108,11 @@ end local function check_and_update_connection(driver, device) local conn_info = device:get_field(fields.CONN_INFO) - if not driver.device_manager.is_valid_connection(driver, device, conn_info) then - device:offline() + local eventsource = device:get_field(fields.EVENT_SOURCE) + if eventsource and eventsource.ready_state == eventsource.ReadyStates.OPEN then + log.info(string.format("SSE connection is being maintained well, dni = %s", device.device_network_id)) + elseif not driver.device_manager.is_valid_connection(driver, device, conn_info) then find_new_connection(driver, device) - conn_info = device:get_field(fields.CONN_INFO) - end - - if driver.device_manager.is_valid_connection(driver, device, conn_info) then - device:online() end end @@ -132,8 +133,11 @@ end local function do_refresh(driver, device, cmd) - check_and_update_connection(driver, device) - status_update(driver, device) + local success, err = status_update(driver, device) + if not success then + log.info(string.format("Failed to status_update during do_refresh, err = %s dni= %s", err, device.device_network_id)) + check_and_update_connection(driver, device) + end driver.device_manager.init_presence(driver, device) driver.device_manager.init_movement(driver, device) driver.device_manager.init_activity(driver, device) @@ -163,6 +167,7 @@ local function device_init(driver, device) if device:get_field(fields._INIT) then return end + device:set_field(fields._INIT, true, { persist = false }) local device_dni = device.device_network_id driver.controlled_devices[device_dni] = device @@ -177,19 +182,19 @@ local function device_init(driver, device) local credential = device:get_field(fields.CREDENTIAL) if not credential then - log.error("failed to find credential.") + log.error_with({ hub_logs = true }, "failed to find credential.") device:offline() return end + driver.device_manager.set_zone_info_to_latest_state(driver, device) + log.trace(string.format("Creating device monitoring for %s", device.device_network_id)) create_monitoring_thread(driver, device, device_info) - update_connection(driver, device, device_ip, device_info) - driver.device_manager.set_zone_info_to_latest_state(driver, device) + update_connection(driver, device, device_ip, device_info) do_refresh(driver, device, nil) - device:set_field(fields._INIT, true, { persist = false }) end local function device_info_changed(driver, device, event, args) @@ -210,8 +215,6 @@ local lan_driver = Driver("aqara-fp2", [capabilities.refresh.commands.refresh.NAME] = do_refresh, }, [multipleZonePresence.id] = { - [multipleZonePresence.commands.createZone.name] = multipleZonePresence.commands.createZone.handler, - [multipleZonePresence.commands.deleteZone.name] = multipleZonePresence.commands.deleteZone.handler, [multipleZonePresence.commands.updateZoneName.name] = multipleZonePresence.commands.updateZoneName.handler, } }, diff --git a/drivers/Aqara/aqara-presence-sensor/src/lunchbox/rest.lua b/drivers/Aqara/aqara-presence-sensor/src/lunchbox/rest.lua index e79507ef73..dec3a28a37 100644 --- a/drivers/Aqara/aqara-presence-sensor/src/lunchbox/rest.lua +++ b/drivers/Aqara/aqara-presence-sensor/src/lunchbox/rest.lua @@ -182,6 +182,7 @@ local function handle_response(sock) if api_version >= 9 then local response, err = Response.tcp_source(sock) if err or (not response) then return response, (err or "unknown error") end + if response.status == 403 then return response, "403 Forbidden" end return response, response:fill_body() end -- called select right before passing in so we receive immediately diff --git a/drivers/Aqara/aqara-presence-sensor/src/lunchbox/sse/eventsource.lua b/drivers/Aqara/aqara-presence-sensor/src/lunchbox/sse/eventsource.lua index 0b5244bcd1..5afc79fc98 100644 --- a/drivers/Aqara/aqara-presence-sensor/src/lunchbox/sse/eventsource.lua +++ b/drivers/Aqara/aqara-presence-sensor/src/lunchbox/sse/eventsource.lua @@ -343,8 +343,10 @@ local function open_action(source) return else --- real error, close the connection. - source._sock:close() - source._sock = nil + if source._sock ~= nil then + source._sock:close() + source._sock = nil + end source.ready_state = EventSource.ReadyStates.CLOSED return nil, err, partial end @@ -360,8 +362,10 @@ local function open_action(source) return else --- real error, close the connection. - source._sock:close() - source._sock = nil + if source._sock ~= nil then + source._sock:close() + source._sock = nil + end source.ready_state = EventSource.ReadyStates.CLOSED return nil, err, partial end @@ -373,8 +377,10 @@ local function open_action(source) return else --- real error, close the connection. - source._sock:close() - source._sock = nil + if source._sock ~= nil then + source._sock:close() + source._sock = nil + end source.ready_state = EventSource.ReadyStates.CLOSED return nil, err, partial end From 714c1ed23cda2c323a198625bcf97ce0c98abf67 Mon Sep 17 00:00:00 2001 From: iris-wy Date: Mon, 2 Dec 2024 22:11:42 +0800 Subject: [PATCH 09/14] Add Zemismart ZM25C multiple language support (#1765) --- tools/localizations/cn.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/localizations/cn.csv b/tools/localizations/cn.csv index 87378d7013..2f51db2f6e 100644 --- a/tools/localizations/cn.csv +++ b/tools/localizations/cn.csv @@ -79,3 +79,4 @@ Aqara Wireless Mini Switch T1,Aqara 无线开关 T1 "WallHero Switch (8 Way)",八位智能开关/场景面板 "WallHero Outlet",智能墙面五孔插座 "WallHero Remote Control (4-Inch)",语音场景(4寸)面板 +"Zemismart ZM25C Smart Curtain",Zemismart ZM25C 智能窗帘 From f1502823a959d9a6ba406d4b5966b755eaae730f Mon Sep 17 00:00:00 2001 From: iris-wy Date: Mon, 2 Dec 2024 22:12:22 +0800 Subject: [PATCH 10/14] Add Zemismart ZM25C Curtain Motor (#1750) Signed-off-by: ying21-wang --- drivers/SmartThings/matter-window-covering/fingerprints.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/SmartThings/matter-window-covering/fingerprints.yml b/drivers/SmartThings/matter-window-covering/fingerprints.yml index 94b51d1c76..59aa93e896 100644 --- a/drivers/SmartThings/matter-window-covering/fingerprints.yml +++ b/drivers/SmartThings/matter-window-covering/fingerprints.yml @@ -26,6 +26,11 @@ matterManufacturer: vendorId: 0x139C productId: 0xFF15 deviceProfileName: window-covering + - id: "5020/64017" + deviceLabel: Zemismart ZM25C Smart Curtain + vendorId: 0x139C + productId: 0xFA11 + deviceProfileName: window-covering matterGeneric: - id: "windowcovering" deviceLabel: Matter Window Covering From 46bff8d53cac8d9448ef9b641366ebac998e3cbc Mon Sep 17 00:00:00 2001 From: SiHAS <71238736+shinasys@users.noreply.github.com> Date: Tue, 3 Dec 2024 12:43:36 +0900 Subject: [PATCH 11/14] Add shinasystem's full buttons switch for wwst (#1748) - SQM300Z4, SQM300Z6 --- drivers/SmartThings/zigbee-switch/fingerprints.yml | 10 ++++++++++ .../zigbee-switch/src/multi-switch-no-master/init.lua | 2 ++ 2 files changed, 12 insertions(+) diff --git a/drivers/SmartThings/zigbee-switch/fingerprints.yml b/drivers/SmartThings/zigbee-switch/fingerprints.yml index ffd5c26971..bedbc33b91 100644 --- a/drivers/SmartThings/zigbee-switch/fingerprints.yml +++ b/drivers/SmartThings/zigbee-switch/fingerprints.yml @@ -1120,6 +1120,16 @@ zigbeeManufacturer: manufacturer: ShinaSystem model: SQM300Z3 deviceProfileName: basic-switch + - id: ShinaSystem/SQM300Z4 + deviceLabel: SiHAS Switch 1 + manufacturer: ShinaSystem + model: SQM300Z4 + deviceProfileName: basic-switch + - id: ShinaSystem/SQM300Z6 + deviceLabel: SiHAS Switch 1 + manufacturer: ShinaSystem + model: SQM300Z6 + deviceProfileName: basic-switch - id: Samsung/SAMSUNG-ITM-Z-002 deviceLabel: Samsung Light manufacturer: Samsung Electronics diff --git a/drivers/SmartThings/zigbee-switch/src/multi-switch-no-master/init.lua b/drivers/SmartThings/zigbee-switch/src/multi-switch-no-master/init.lua index 98317c0e73..e39be7593f 100644 --- a/drivers/SmartThings/zigbee-switch/src/multi-switch-no-master/init.lua +++ b/drivers/SmartThings/zigbee-switch/src/multi-switch-no-master/init.lua @@ -48,6 +48,8 @@ local MULTI_SWITCH_NO_MASTER_FINGERPRINTS = { { mfr = "ShinaSystem", model = "SBM300Z6", children = 5 }, { mfr = "ShinaSystem", model = "SQM300Z2", children = 1 }, { mfr = "ShinaSystem", model = "SQM300Z3", children = 2 }, + { mfr = "ShinaSystem", model = "SQM300Z4", children = 3 }, + { mfr = "ShinaSystem", model = "SQM300Z6", children = 5 }, { model = "E220-KR2N0Z0-HA", children = 1 }, { model = "E220-KR3N0Z0-HA", children = 2 }, { model = "E220-KR4N0Z0-HA", children = 3 }, From ff3a213cd134b0ec0de879a8aa75e4da62aaeb81 Mon Sep 17 00:00:00 2001 From: Alissa Dornbos <79465613+lelandblue@users.noreply.github.com> Date: Tue, 3 Dec 2024 11:00:49 -0500 Subject: [PATCH 12/14] New Device (Matter Switch) Cync Reveal Full Color A21 (#1788) * new-device-cync-A21 * Update device label to A21 * Update decimal number for "id:" --- drivers/SmartThings/matter-switch/fingerprints.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/SmartThings/matter-switch/fingerprints.yml b/drivers/SmartThings/matter-switch/fingerprints.yml index c1b57ecf8b..ca1e21831d 100644 --- a/drivers/SmartThings/matter-switch/fingerprints.yml +++ b/drivers/SmartThings/matter-switch/fingerprints.yml @@ -165,6 +165,11 @@ matterManufacturer: vendorId: 0x1339 productId: 0x007B deviceProfileName: light-color-level-2000K-7000K + - id: "4921/109" + deviceLabel: Cync Reveal Full Color A21 + vendorId: 0x1339 + productId: 0x006D + deviceProfileName: light-color-level-2000K-7000K - id: "4921/111" deviceLabel: Cync Outdoor Plug vendorId: 0x1339 From e355080ba1f3cb108145f812e197c38000aa8cab Mon Sep 17 00:00:00 2001 From: FrankSpringfield Date: Wed, 4 Dec 2024 23:12:39 +0800 Subject: [PATCH 13/14] Add fingerprints for TOTEM S50V/S93/W31V and sort fingerprints for TOTEM alphabetically (#1775) * Add fingerprints for TOTEM S50V/S93/W31V Signed-off-by: frank-huang * Sort fingerprints for TOTEM alphabetically Signed-off-by: frank-huang --------- Signed-off-by: frank-huang --- .../SmartThings/zigbee-lock/fingerprints.yml | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/SmartThings/zigbee-lock/fingerprints.yml b/drivers/SmartThings/zigbee-lock/fingerprints.yml index aa93618497..00e8dd0f51 100644 --- a/drivers/SmartThings/zigbee-lock/fingerprints.yml +++ b/drivers/SmartThings/zigbee-lock/fingerprints.yml @@ -145,6 +145,16 @@ zigbeeManufacturer: manufacturer: TOTEM model: P30 deviceProfileName: lock-battery + - id: TOTEM/P70 + deviceLabel: TOTEM Door Lock + manufacturer: TOTEM + model: P70 + deviceProfileName: lock-battery + - id: TOTEM/P90 + deviceLabel: TOTEM Door Lock + manufacturer: TOTEM + model: P90 + deviceProfileName: lock-battery - id: TOTEM/Q30 deviceLabel: TOTEM Door Lock manufacturer: TOTEM @@ -165,15 +175,20 @@ zigbeeManufacturer: manufacturer: TOTEM model: R71 deviceProfileName: lock-battery - - id: TOTEM/P70 + - id: TOTEM/S50V deviceLabel: TOTEM Door Lock manufacturer: TOTEM - model: P70 + model: S50V deviceProfileName: lock-battery - - id: TOTEM/P90 + - id: TOTEM/S93 deviceLabel: TOTEM Door Lock manufacturer: TOTEM - model: P90 + model: S93 + deviceProfileName: lock-battery + - id: TOTEM/W31V + deviceLabel: TOTEM Door Lock + manufacturer: TOTEM + model: W31V deviceProfileName: lock-battery zigbeeGeneric: - id: "genericLock" From 76da639b204f17a414f65c3eb87f31b4c3856773 Mon Sep 17 00:00:00 2001 From: Alissa Dornbos <79465613+lelandblue@users.noreply.github.com> Date: Wed, 4 Dec 2024 16:23:18 -0500 Subject: [PATCH 14/14] New Devices (Matter Switch + Matter Sensor) 1 Heiman Co Sensor and 2 Zemismart Devices (#1794) * new-devices-Zemismart-Heiman * Adding fingerprint --- drivers/SmartThings/matter-sensor/fingerprints.yml | 5 +++++ drivers/SmartThings/matter-switch/fingerprints.yml | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/drivers/SmartThings/matter-sensor/fingerprints.yml b/drivers/SmartThings/matter-sensor/fingerprints.yml index b270332b6d..7e4a3ae4b6 100644 --- a/drivers/SmartThings/matter-sensor/fingerprints.yml +++ b/drivers/SmartThings/matter-sensor/fingerprints.yml @@ -58,6 +58,11 @@ matterManufacturer: vendorId: 0x120B productId: 0x1003 deviceProfileName: smoke + - id: "4619/4103" + deviceLabel: Smart co sensor + vendorId: 0x120B + productId: 0x1007 + deviceProfileName: co # Legrand - id: "Legrand/Netatmo/Smart-2-in-1-Sensor" deviceLabel: Netatmo Smart 2-in-1 Sensor diff --git a/drivers/SmartThings/matter-switch/fingerprints.yml b/drivers/SmartThings/matter-switch/fingerprints.yml index ca1e21831d..1dd9b85c53 100644 --- a/drivers/SmartThings/matter-switch/fingerprints.yml +++ b/drivers/SmartThings/matter-switch/fingerprints.yml @@ -2359,6 +2359,11 @@ matterManufacturer: vendorId: 0x139C productId: 0xD003 deviceProfileName: light-color-level + - id: "5020/43784" + deviceLabel: Zemismart WiFi Smart Switch + vendorId: 0x139C + productId: 0xAB08 + deviceProfileName: switch-binary - id: "5020/43825" deviceLabel: Zemismart WiFi Smart Switch vendorId: 0x139C @@ -2374,6 +2379,11 @@ matterManufacturer: vendorId: 0x139C productId: 0xAB01 deviceProfileName: switch-binary + - id: "5020/43843" + deviceLabel: Zemismart WiFi Smart Switch + vendorId: 0x139C + productId: 0xAB43 + deviceProfileName: switch-binary #TUO - id: "5150/1" deviceLabel: "TUO Smart Button"