From 518b4a2f389a42bcf8b8df00221f1d4aaf1a6a35 Mon Sep 17 00:00:00 2001 From: Harrison Carter Date: Mon, 30 Sep 2024 15:53:26 -0500 Subject: [PATCH 1/8] initial: add do configure logic and edit fingerprint --- .../SmartThings/matter-lock/fingerprints.yml | 5 ++++ .../profiles/base-lock-nobattery.yml | 23 ++++++++++++++ drivers/SmartThings/matter-lock/src/init.lua | 30 +++++++++++++++++-- 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100755 drivers/SmartThings/matter-lock/profiles/base-lock-nobattery.yml diff --git a/drivers/SmartThings/matter-lock/fingerprints.yml b/drivers/SmartThings/matter-lock/fingerprints.yml index 30ca4a4352..7d6b329770 100755 --- a/drivers/SmartThings/matter-lock/fingerprints.yml +++ b/drivers/SmartThings/matter-lock/fingerprints.yml @@ -32,6 +32,11 @@ matterManufacturer: vendorId: 0x135d productId: 0xb0 deviceProfileName: lock-nocodes-notamper +#Bridged Devices + - id: "matter/bridged/door-lock" + deviceLabel: Matter Bridged Door Lock + vendorId: 0x0 + deviceProfileName: base-lock-nobattery matterGeneric: - id: "matter/door-lock" deviceLabel: Matter Door Lock diff --git a/drivers/SmartThings/matter-lock/profiles/base-lock-nobattery.yml b/drivers/SmartThings/matter-lock/profiles/base-lock-nobattery.yml new file mode 100755 index 0000000000..769e955219 --- /dev/null +++ b/drivers/SmartThings/matter-lock/profiles/base-lock-nobattery.yml @@ -0,0 +1,23 @@ +name: base-lock-nobattery +components: +- id: main + capabilities: + - id: lock + version: 1 + config: + values: + - key: "lock.value" + enabledValues: + - locked + - unlocked + - not fully locked + - id: lockCodes + version: 1 + - id: tamperAlert + version: 1 + - id: firmwareUpdate + version: 1 + - id: refresh + version: 1 + categories: + - name: SmartLock diff --git a/drivers/SmartThings/matter-lock/src/init.lua b/drivers/SmartThings/matter-lock/src/init.lua index ccb3110c08..f0a2260460 100755 --- a/drivers/SmartThings/matter-lock/src/init.lua +++ b/drivers/SmartThings/matter-lock/src/init.lua @@ -197,6 +197,9 @@ local function set_credential_response_handler(driver, device, ib, response) if device:get_field(lock_utils.NONFUNCTIONAL) and cota_cred_index == credential_index then device.log.info("Successfully set COTA credential after being non-functional") device:set_field(lock_utils.NONFUNCTIONAL, false, {persist = true}) + + -- TODO: Add check here for battery + device:try_update_metadata({profile = "base-lock", provisioning_state = "PROVISIONED"}) end elseif device:get_field(lock_utils.COTA_CRED) and credential_index == device:get_field(lock_utils.COTA_CRED_INDEX) then @@ -519,6 +522,29 @@ local function component_to_endpoint(device, component_name) return find_default_endpoint(device, clusters.DoorLock.ID) end +local function do_configure(driver, device) + local power_source_eps = device:get_endpoints(clusters.PowerSource.ID) + local battery_feature_eps = device:get_endpoints(clusters.PowerSource.ID, {feature_bitmap = clusters.PowerSource.types.PowerSourceFeature.BATTERY}) + local pin_eps = device:get_endpoints(DoorLock.ID, {feature_bitmap = DoorLock.types.DoorLockFeature.CREDENTIALSOTA | DoorLock.types.DoorLockFeature.PIN_CREDENTIALS}) + + local profile_name = "lock" + + -- we need to check if a device is already fingerprinted. + + + -- check for lock codes + if #pin_eps == 0 then + profile_name = profile_name .. "nocodes" + end + + -- check for battery type + if #power_source_eps == 0 then + profile_name = profile_name .. "-nobattery" + elseif #battery_feature_eps == 0 then + profile_name = profile_name .. "-batteryLevel" + end +end + local function device_init(driver, device) device:set_component_to_endpoint_fn(component_to_endpoint) device:subscribe() @@ -536,7 +562,7 @@ local function device_init(driver, device) device:set_field(lock_utils.COTA_READ_INITIALIZED, true, {persist = true}) end end - end +end local function device_added(driver, device) --Note: May want to write OperatingMode to NORMAL, to attempt to ensure remote operation works @@ -638,7 +664,7 @@ local matter_lock_driver = { sub_drivers = { require("new-matter-lock"), }, - lifecycle_handlers = {init = device_init, added = device_added}, + lifecycle_handlers = {init = device_init, added = device_added, doConfigure = do_configure }, } ----------------------------------------------------------------------------------------------------------------------------- From 5b60ef263e75bc2376b75ee96b617626c12b0bdd Mon Sep 17 00:00:00 2001 From: Harrison Carter Date: Tue, 1 Oct 2024 10:50:39 -0500 Subject: [PATCH 2/8] add: logic to not configure wwst devices --- .../SmartThings/matter-lock/fingerprints.yml | 5 - drivers/SmartThings/matter-lock/src/init.lua | 37 ++++--- .../src/test/test_bridged_matter_lock.lua | 102 ++++++++++++++++++ 3 files changed, 125 insertions(+), 19 deletions(-) create mode 100644 drivers/SmartThings/matter-lock/src/test/test_bridged_matter_lock.lua diff --git a/drivers/SmartThings/matter-lock/fingerprints.yml b/drivers/SmartThings/matter-lock/fingerprints.yml index 7d6b329770..30ca4a4352 100755 --- a/drivers/SmartThings/matter-lock/fingerprints.yml +++ b/drivers/SmartThings/matter-lock/fingerprints.yml @@ -32,11 +32,6 @@ matterManufacturer: vendorId: 0x135d productId: 0xb0 deviceProfileName: lock-nocodes-notamper -#Bridged Devices - - id: "matter/bridged/door-lock" - deviceLabel: Matter Bridged Door Lock - vendorId: 0x0 - deviceProfileName: base-lock-nobattery matterGeneric: - id: "matter/door-lock" deviceLabel: Matter Door Lock diff --git a/drivers/SmartThings/matter-lock/src/init.lua b/drivers/SmartThings/matter-lock/src/init.lua index f0a2260460..9fc744012d 100755 --- a/drivers/SmartThings/matter-lock/src/init.lua +++ b/drivers/SmartThings/matter-lock/src/init.lua @@ -197,9 +197,6 @@ local function set_credential_response_handler(driver, device, ib, response) if device:get_field(lock_utils.NONFUNCTIONAL) and cota_cred_index == credential_index then device.log.info("Successfully set COTA credential after being non-functional") device:set_field(lock_utils.NONFUNCTIONAL, false, {persist = true}) - - -- TODO: Add check here for battery - device:try_update_metadata({profile = "base-lock", provisioning_state = "PROVISIONED"}) end elseif device:get_field(lock_utils.COTA_CRED) and credential_index == device:get_field(lock_utils.COTA_CRED_INDEX) then @@ -523,26 +520,38 @@ local function component_to_endpoint(device, component_name) end local function do_configure(driver, device) - local power_source_eps = device:get_endpoints(clusters.PowerSource.ID) - local battery_feature_eps = device:get_endpoints(clusters.PowerSource.ID, {feature_bitmap = clusters.PowerSource.types.PowerSourceFeature.BATTERY}) - local pin_eps = device:get_endpoints(DoorLock.ID, {feature_bitmap = DoorLock.types.DoorLockFeature.CREDENTIALSOTA | DoorLock.types.DoorLockFeature.PIN_CREDENTIALS}) - - local profile_name = "lock" - - -- we need to check if a device is already fingerprinted. - + local fingerprinted_devices = { + { vendor_id = 0x115F, product_id = 0x2802 }, -- Aqara Smart Lock U200 + { vendor_id = 0x115F, product_id = 0x2801 }, -- Aqara Smart Lock U300 + { vendor_id = 0x129F, product_id = 0x0001 }, -- Level Lock Plus (Matter) + { vendor_id = 0x135d, product_id = 0xb1 }, -- Nuki Smart Lock Pro + { vendor_id = 0x135d, product_id = 0xb0 }, -- Nuki Smart Lock + } - -- check for lock codes - if #pin_eps == 0 then - profile_name = profile_name .. "nocodes" + -- check if device has a wwst fingerprint + if device.manufacturer_info ~= nil then + for _, fingerprint in ipairs(fingerprinted_devices) do + if device.manufacturer_info.vendor_id == fingerprint.vendor_id and + device.manufacturer_info.product_id == fingerprint.product_id then + return + end + end end + -- if not fingerprinted, dynamically configure base-lock profile based on Power Source cluster checks + local power_source_eps = device:get_endpoints(clusters.PowerSource.ID) + local battery_feature_eps = device:get_endpoints(clusters.PowerSource.ID, {feature_bitmap = clusters.PowerSource.types.PowerSourceFeature.BATTERY}) + local profile_name = "base-lock" + -- check for battery type if #power_source_eps == 0 then profile_name = profile_name .. "-nobattery" elseif #battery_feature_eps == 0 then profile_name = profile_name .. "-batteryLevel" end + + device.log.info_with({hub_logs=true}, string.format("Updating device profile to %s.", profile_name)) + device:try_update_metadata({profile = profile_name}) end local function device_init(driver, device) diff --git a/drivers/SmartThings/matter-lock/src/test/test_bridged_matter_lock.lua b/drivers/SmartThings/matter-lock/src/test/test_bridged_matter_lock.lua new file mode 100644 index 0000000000..4f041019fd --- /dev/null +++ b/drivers/SmartThings/matter-lock/src/test/test_bridged_matter_lock.lua @@ -0,0 +1,102 @@ +-- 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 test = require "integration_test" +local capabilities = require "st.capabilities" +test.add_package_capability("lockAlarm.yml") +local t_utils = require "integration_test.utils" +local clusters = require "st.matter.clusters" + +local mock_device_record = { + profile = t_utils.get_profile_definition("base-lock-nobattery.yml"), + manufacturer_info = {vendor_id = 0, product_id = 0}, + endpoints = { + { + endpoint_id = 2, + clusters = { + {cluster_id = clusters.Basic.ID, cluster_type = "SERVER"}, + }, + device_types = { + device_type_id = 0x0016, device_type_revision = 1, -- RootNode + } + }, + { + endpoint_id = 10, + clusters = { + {cluster_id = clusters.DoorLock.ID, cluster_type = "SERVER", feature_map = 0x0000}, + }, + }, + }, +} +local mock_device = test.mock_device.build_test_matter_device(mock_device_record) + +local mock_device_record_aqara = { + profile = t_utils.get_profile_definition("base-lock-nobattery.yml"), + manufacturer_info = {vendor_id = 0x115F, product_id = 0x2801}, -- Aqara Smart Lock U300 + endpoints = { + { + endpoint_id = 2, + clusters = { + {cluster_id = clusters.Basic.ID, cluster_type = "SERVER"}, + }, + device_types = { + device_type_id = 0x0016, device_type_revision = 1, -- RootNode + } + }, + { + endpoint_id = 10, + clusters = { + {cluster_id = clusters.DoorLock.ID, cluster_type = "SERVER", feature_map = 0x0000}, + }, + }, + }, +} + +local mock_device_aqara = test.mock_device.build_test_matter_device(mock_device_record_aqara) + +local function test_init() + local subscribe_request = clusters.DoorLock.attributes.LockState:subscribe(mock_device) + subscribe_request:merge(clusters.DoorLock.events.DoorLockAlarm:subscribe(mock_device)) + subscribe_request:merge(clusters.DoorLock.events.LockOperation:subscribe(mock_device)) + subscribe_request:merge(clusters.DoorLock.events.LockUserChange:subscribe(mock_device)) + test.socket["matter"]:__expect_send({mock_device.id, subscribe_request}) + test.mock_device.add_test_device(mock_device) + + local subscribe_request = clusters.DoorLock.attributes.LockState:subscribe(mock_device_aqara) + subscribe_request:merge(clusters.DoorLock.events.DoorLockAlarm:subscribe(mock_device_aqara)) + subscribe_request:merge(clusters.DoorLock.events.LockOperation:subscribe(mock_device_aqara)) + subscribe_request:merge(clusters.DoorLock.events.LockUserChange:subscribe(mock_device_aqara)) + test.socket["matter"]:__expect_send({mock_device_aqara.id, subscribe_request}) + test.mock_device.add_test_device(mock_device_aqara) +end +test.set_test_init_function(test_init) + +test.register_coroutine_test( + "doConfigure lifecycle event for base-lock-nobattery", + function() + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) + mock_device:expect_metadata_update({ profile = "base-lock-nobattery" }) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + end +) + +test.register_coroutine_test( + "doConfigure lifecycle event for aqara lock", + function() + test.socket.device_lifecycle:__queue_receive({ mock_device_aqara.id, "doConfigure" }) + mock_device_aqara:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + end +) + +test.run_registered_tests() From e255c96127809d438594fe6d7fc15a01bbb82f19 Mon Sep 17 00:00:00 2001 From: Harrison Carter Date: Tue, 1 Oct 2024 10:57:12 -0500 Subject: [PATCH 3/8] remove: unused capability definition --- .../matter-lock/src/test/test_bridged_matter_lock.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/SmartThings/matter-lock/src/test/test_bridged_matter_lock.lua b/drivers/SmartThings/matter-lock/src/test/test_bridged_matter_lock.lua index 4f041019fd..516b475638 100644 --- a/drivers/SmartThings/matter-lock/src/test/test_bridged_matter_lock.lua +++ b/drivers/SmartThings/matter-lock/src/test/test_bridged_matter_lock.lua @@ -13,7 +13,6 @@ -- limitations under the License. local test = require "integration_test" -local capabilities = require "st.capabilities" test.add_package_capability("lockAlarm.yml") local t_utils = require "integration_test.utils" local clusters = require "st.matter.clusters" From cebeaf48686085ea082c598b2f0e45f4783385f1 Mon Sep 17 00:00:00 2001 From: Harrison Carter Date: Tue, 1 Oct 2024 14:21:37 -0500 Subject: [PATCH 4/8] add: newest fingerprint device --- drivers/SmartThings/matter-lock/src/init.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/SmartThings/matter-lock/src/init.lua b/drivers/SmartThings/matter-lock/src/init.lua index 9fc744012d..19b887d730 100755 --- a/drivers/SmartThings/matter-lock/src/init.lua +++ b/drivers/SmartThings/matter-lock/src/init.lua @@ -524,6 +524,7 @@ local function do_configure(driver, device) { vendor_id = 0x115F, product_id = 0x2802 }, -- Aqara Smart Lock U200 { vendor_id = 0x115F, product_id = 0x2801 }, -- Aqara Smart Lock U300 { vendor_id = 0x129F, product_id = 0x0001 }, -- Level Lock Plus (Matter) + { vendor_id = 0x129F, product_id = 0x0003 }, -- Level Bolt (Matter) { vendor_id = 0x135d, product_id = 0xb1 }, -- Nuki Smart Lock Pro { vendor_id = 0x135d, product_id = 0xb0 }, -- Nuki Smart Lock } From 43a966dbbcb295aa146ccb216d025667ad833589 Mon Sep 17 00:00:00 2001 From: Harrison Carter Date: Tue, 1 Oct 2024 15:19:21 -0500 Subject: [PATCH 5/8] implement: check for capabilities of base-lock --- drivers/SmartThings/matter-lock/src/init.lua | 25 ++++++------------- .../src/test/test_bridged_matter_lock.lua | 8 +++--- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/drivers/SmartThings/matter-lock/src/init.lua b/drivers/SmartThings/matter-lock/src/init.lua index 19b887d730..96643b967f 100755 --- a/drivers/SmartThings/matter-lock/src/init.lua +++ b/drivers/SmartThings/matter-lock/src/init.lua @@ -520,23 +520,14 @@ local function component_to_endpoint(device, component_name) end local function do_configure(driver, device) - local fingerprinted_devices = { - { vendor_id = 0x115F, product_id = 0x2802 }, -- Aqara Smart Lock U200 - { vendor_id = 0x115F, product_id = 0x2801 }, -- Aqara Smart Lock U300 - { vendor_id = 0x129F, product_id = 0x0001 }, -- Level Lock Plus (Matter) - { vendor_id = 0x129F, product_id = 0x0003 }, -- Level Bolt (Matter) - { vendor_id = 0x135d, product_id = 0xb1 }, -- Nuki Smart Lock Pro - { vendor_id = 0x135d, product_id = 0xb0 }, -- Nuki Smart Lock - } - - -- check if device has a wwst fingerprint - if device.manufacturer_info ~= nil then - for _, fingerprint in ipairs(fingerprinted_devices) do - if device.manufacturer_info.vendor_id == fingerprint.vendor_id and - device.manufacturer_info.product_id == fingerprint.product_id then - return - end - end + -- check if the device is NOT currently profiled as base-lock + -- by ANDing a query for every capability in the base-lock profiles. + -- If it does not use base-lock, it is WWST and does not need re-profiling. + if not (device:supports_capability(capabilities.lock) and + device:supports_capability(capabilities.lockCodes) and + device:supports_capability(capabilities.tamperAlert) and + device:supports_capability(capabilities.battery)) then + return end -- if not fingerprinted, dynamically configure base-lock profile based on Power Source cluster checks diff --git a/drivers/SmartThings/matter-lock/src/test/test_bridged_matter_lock.lua b/drivers/SmartThings/matter-lock/src/test/test_bridged_matter_lock.lua index 516b475638..b98e94ee84 100644 --- a/drivers/SmartThings/matter-lock/src/test/test_bridged_matter_lock.lua +++ b/drivers/SmartThings/matter-lock/src/test/test_bridged_matter_lock.lua @@ -18,7 +18,7 @@ local t_utils = require "integration_test.utils" local clusters = require "st.matter.clusters" local mock_device_record = { - profile = t_utils.get_profile_definition("base-lock-nobattery.yml"), + profile = t_utils.get_profile_definition("base-lock.yml"), manufacturer_info = {vendor_id = 0, product_id = 0}, endpoints = { { @@ -33,7 +33,7 @@ local mock_device_record = { { endpoint_id = 10, clusters = { - {cluster_id = clusters.DoorLock.ID, cluster_type = "SERVER", feature_map = 0x0000}, + {cluster_id = clusters.DoorLock.ID, cluster_type = "SERVER", feature_map = 0x0101}, }, }, }, @@ -41,7 +41,7 @@ local mock_device_record = { local mock_device = test.mock_device.build_test_matter_device(mock_device_record) local mock_device_record_aqara = { - profile = t_utils.get_profile_definition("base-lock-nobattery.yml"), + profile = t_utils.get_profile_definition("lock-lockalarm-nobattery.yml"), manufacturer_info = {vendor_id = 0x115F, product_id = 0x2801}, -- Aqara Smart Lock U300 endpoints = { { @@ -74,8 +74,6 @@ local function test_init() local subscribe_request = clusters.DoorLock.attributes.LockState:subscribe(mock_device_aqara) subscribe_request:merge(clusters.DoorLock.events.DoorLockAlarm:subscribe(mock_device_aqara)) - subscribe_request:merge(clusters.DoorLock.events.LockOperation:subscribe(mock_device_aqara)) - subscribe_request:merge(clusters.DoorLock.events.LockUserChange:subscribe(mock_device_aqara)) test.socket["matter"]:__expect_send({mock_device_aqara.id, subscribe_request}) test.mock_device.add_test_device(mock_device_aqara) end From b3c94b350a110a0c5e92b54a0455e41e0b4003c3 Mon Sep 17 00:00:00 2001 From: Harrison Carter Date: Tue, 1 Oct 2024 15:57:04 -0500 Subject: [PATCH 6/8] add: new profile, updated battery check logic --- .../profiles/lock-without-codes-nobattery.yml | 21 ++++++++++++++++++ drivers/SmartThings/matter-lock/src/init.lua | 22 ++++++++++++++++--- .../matter-lock/src/test/test_matter_lock.lua | 2 +- .../src/test/test_matter_lock_cota.lua | 2 +- 4 files changed, 42 insertions(+), 5 deletions(-) create mode 100755 drivers/SmartThings/matter-lock/profiles/lock-without-codes-nobattery.yml diff --git a/drivers/SmartThings/matter-lock/profiles/lock-without-codes-nobattery.yml b/drivers/SmartThings/matter-lock/profiles/lock-without-codes-nobattery.yml new file mode 100755 index 0000000000..8de4bb1a5c --- /dev/null +++ b/drivers/SmartThings/matter-lock/profiles/lock-without-codes-nobattery.yml @@ -0,0 +1,21 @@ +name: lock-without-codes-nobattery +components: +- id: main + capabilities: + - id: lock + version: 1 + config: + values: + - key: "lock.value" + enabledValues: + - locked + - unlocked + - not fully locked + - id: tamperAlert + version: 1 + - id: firmwareUpdate + version: 1 + - id: refresh + version: 1 + categories: + - name: SmartLock diff --git a/drivers/SmartThings/matter-lock/src/init.lua b/drivers/SmartThings/matter-lock/src/init.lua index 96643b967f..34bc216b42 100755 --- a/drivers/SmartThings/matter-lock/src/init.lua +++ b/drivers/SmartThings/matter-lock/src/init.lua @@ -197,7 +197,15 @@ local function set_credential_response_handler(driver, device, ib, response) if device:get_field(lock_utils.NONFUNCTIONAL) and cota_cred_index == credential_index then device.log.info("Successfully set COTA credential after being non-functional") device:set_field(lock_utils.NONFUNCTIONAL, false, {persist = true}) - device:try_update_metadata({profile = "base-lock", provisioning_state = "PROVISIONED"}) + local power_source_eps = device:get_endpoints(clusters.PowerSource.ID) + local battery_feature_eps = device:get_endpoints(clusters.PowerSource.ID, {feature_bitmap = clusters.PowerSource.types.PowerSourceFeature.BATTERY}) + local profile_name = "base-lock" + if #power_source_eps == 0 then + profile_name = profile_name .. "-nobattery" + elseif #battery_feature_eps == 0 then + profile_name = profile_name .. "-batteryLevel" + end + device:try_update_metadata({profile = profile_name, provisioning_state = "PROVISIONED"}) end elseif device:get_field(lock_utils.COTA_CRED) and credential_index == device:get_field(lock_utils.COTA_CRED_INDEX) then -- Handle failure to set a COTA credential @@ -530,7 +538,7 @@ local function do_configure(driver, device) return end - -- if not fingerprinted, dynamically configure base-lock profile based on Power Source cluster checks + -- if not fingerprinted, dynamically configure base-lock profile based on Power Source cluster checks local power_source_eps = device:get_endpoints(clusters.PowerSource.ID) local battery_feature_eps = device:get_endpoints(clusters.PowerSource.ID, {feature_bitmap = clusters.PowerSource.types.PowerSourceFeature.BATTERY}) local profile_name = "base-lock" @@ -573,7 +581,15 @@ local function device_added(driver, device) if #eps == 0 then if device:supports_capability_by_id(capabilities.tamperAlert.ID) then device.log.debug("Device does not support lockCodes. Switching profile.") - device:try_update_metadata({profile = "lock-without-codes"}) + local power_source_eps = device:get_endpoints(clusters.PowerSource.ID) + local battery_feature_eps = device:get_endpoints(clusters.PowerSource.ID, {feature_bitmap = clusters.PowerSource.types.PowerSourceFeature.BATTERY}) + local profile_name = "lock-without-codes" + if #power_source_eps == 0 then + profile_name = profile_name .. "-nobattery" + elseif #battery_feature_eps == 0 then + profile_name = profile_name .. "-batteryLevel" + end + device:try_update_metadata({profile = profile_name}) else device.log.debug("Device supports neither lock codes nor tamper. Unable to switch profile.") end diff --git a/drivers/SmartThings/matter-lock/src/test/test_matter_lock.lua b/drivers/SmartThings/matter-lock/src/test/test_matter_lock.lua index 30e74e9a3c..7701d5a90c 100644 --- a/drivers/SmartThings/matter-lock/src/test/test_matter_lock.lua +++ b/drivers/SmartThings/matter-lock/src/test/test_matter_lock.lua @@ -35,7 +35,7 @@ local mock_device_record = { endpoint_id = 10, clusters = { {cluster_id = clusters.DoorLock.ID, cluster_type = "SERVER", feature_map = 0x0000}, - {cluster_id = clusters.PowerSource.ID, cluster_type = "SERVER"}, + {cluster_id = clusters.PowerSource.ID, cluster_type = "SERVER", feature_map = 10}, }, }, }, diff --git a/drivers/SmartThings/matter-lock/src/test/test_matter_lock_cota.lua b/drivers/SmartThings/matter-lock/src/test/test_matter_lock_cota.lua index fce2dcdc87..55eca597e6 100644 --- a/drivers/SmartThings/matter-lock/src/test/test_matter_lock_cota.lua +++ b/drivers/SmartThings/matter-lock/src/test/test_matter_lock_cota.lua @@ -56,7 +56,7 @@ local mock_device_record = { cluster_type = "SERVER", feature_map = 0x0181, -- PIN & USR & COTA }, - {cluster_id = clusters.PowerSource.ID, cluster_type = "SERVER"}, + {cluster_id = clusters.PowerSource.ID, cluster_type = "SERVER", feature_map = 10}, }, }, }, From ed1dd1b8cb90ef2615a5d4f2993f3aa6221e3577 Mon Sep 17 00:00:00 2001 From: Harrison Carter Date: Thu, 3 Oct 2024 09:37:33 -0500 Subject: [PATCH 7/8] add: info_changed event --- drivers/SmartThings/matter-lock/src/init.lua | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/SmartThings/matter-lock/src/init.lua b/drivers/SmartThings/matter-lock/src/init.lua index 34bc216b42..ffc3709289 100755 --- a/drivers/SmartThings/matter-lock/src/init.lua +++ b/drivers/SmartThings/matter-lock/src/init.lua @@ -527,6 +527,12 @@ local function component_to_endpoint(device, component_name) return find_default_endpoint(device, clusters.DoorLock.ID) end +local function info_changed(driver, device, event, args) + if device.profile.id ~= args.old_st_store.profile.id then + device:subscribe() + end +end + local function do_configure(driver, device) -- check if the device is NOT currently profiled as base-lock -- by ANDing a query for every capability in the base-lock profiles. @@ -681,7 +687,12 @@ local matter_lock_driver = { sub_drivers = { require("new-matter-lock"), }, - lifecycle_handlers = {init = device_init, added = device_added, doConfigure = do_configure }, + lifecycle_handlers = { + init = device_init, + added = device_added, + doConfigure = do_configure, + infoChanged = info_changed, + }, } ----------------------------------------------------------------------------------------------------------------------------- From e0179b24d3abe851cf16a81a25de581e48ce2829 Mon Sep 17 00:00:00 2001 From: Harrison Carter Date: Mon, 21 Oct 2024 10:51:23 -0500 Subject: [PATCH 8/8] fix test, remove aqara references --- .../src/test/test_bridged_matter_lock.lua | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/SmartThings/matter-lock/src/test/test_bridged_matter_lock.lua b/drivers/SmartThings/matter-lock/src/test/test_bridged_matter_lock.lua index b98e94ee84..3c95216dc5 100644 --- a/drivers/SmartThings/matter-lock/src/test/test_bridged_matter_lock.lua +++ b/drivers/SmartThings/matter-lock/src/test/test_bridged_matter_lock.lua @@ -40,9 +40,9 @@ local mock_device_record = { } local mock_device = test.mock_device.build_test_matter_device(mock_device_record) -local mock_device_record_aqara = { - profile = t_utils.get_profile_definition("lock-lockalarm-nobattery.yml"), - manufacturer_info = {vendor_id = 0x115F, product_id = 0x2801}, -- Aqara Smart Lock U300 +local mock_device_record_level = { + profile = t_utils.get_profile_definition("lock-nocodes-notamper-batteryLevel.yml"), + manufacturer_info = {vendor_id = 0x129F, product_id = 0x0001}, -- Level Lock Plus endpoints = { { endpoint_id = 2, @@ -62,7 +62,7 @@ local mock_device_record_aqara = { }, } -local mock_device_aqara = test.mock_device.build_test_matter_device(mock_device_record_aqara) +local mock_device_level = test.mock_device.build_test_matter_device(mock_device_record_level) local function test_init() local subscribe_request = clusters.DoorLock.attributes.LockState:subscribe(mock_device) @@ -72,10 +72,9 @@ local function test_init() test.socket["matter"]:__expect_send({mock_device.id, subscribe_request}) test.mock_device.add_test_device(mock_device) - local subscribe_request = clusters.DoorLock.attributes.LockState:subscribe(mock_device_aqara) - subscribe_request:merge(clusters.DoorLock.events.DoorLockAlarm:subscribe(mock_device_aqara)) - test.socket["matter"]:__expect_send({mock_device_aqara.id, subscribe_request}) - test.mock_device.add_test_device(mock_device_aqara) + local subscribe_request_level = clusters.DoorLock.attributes.LockState:subscribe(mock_device_level) + test.socket["matter"]:__expect_send({mock_device_level.id, subscribe_request_level}) + test.mock_device.add_test_device(mock_device_level) end test.set_test_init_function(test_init) @@ -89,10 +88,10 @@ test.register_coroutine_test( ) test.register_coroutine_test( - "doConfigure lifecycle event for aqara lock", + "doConfigure lifecycle event for Level Lock Plus profile", function() - test.socket.device_lifecycle:__queue_receive({ mock_device_aqara.id, "doConfigure" }) - mock_device_aqara:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + test.socket.device_lifecycle:__queue_receive({ mock_device_level.id, "doConfigure" }) + mock_device_level:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end )