From 77e05ceebe8b53b378db92cea69e1db9c94c5a53 Mon Sep 17 00:00:00 2001 From: Hunsup Jung Date: Tue, 10 Dec 2024 16:54:05 +0900 Subject: [PATCH 1/6] Update matter-lock driver for U-tec Signed-off-by: Hunsup Jung --- .../profiles/lock-user-pin-battery.yml | 29 +++++++ .../profiles/lock-user-pin-batteryLevel.yml | 29 +++++++ .../lock-user-pin-schedule-battery.yml | 31 ++++++++ .../matter-lock/src/new-matter-lock/init.lua | 75 ++++++++++++++++++- 4 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 drivers/SmartThings/matter-lock/profiles/lock-user-pin-battery.yml create mode 100644 drivers/SmartThings/matter-lock/profiles/lock-user-pin-batteryLevel.yml create mode 100644 drivers/SmartThings/matter-lock/profiles/lock-user-pin-schedule-battery.yml diff --git a/drivers/SmartThings/matter-lock/profiles/lock-user-pin-battery.yml b/drivers/SmartThings/matter-lock/profiles/lock-user-pin-battery.yml new file mode 100644 index 0000000000..2401c4119e --- /dev/null +++ b/drivers/SmartThings/matter-lock/profiles/lock-user-pin-battery.yml @@ -0,0 +1,29 @@ +name: lock-user-pin-battery +components: +- id: main + capabilities: + - id: lock + version: 1 + config: + values: + - key: "lock.value" + enabledValues: + - locked + - unlocked + - not fully locked + - id: lockAlarm + version: 1 + - id: remoteControlStatus + version: 1 + - id: lockUsers + version: 1 + - id: lockCredentials + version: 1 + - id: battery + version: 1 + - id: firmwareUpdate + version: 1 + - id: refresh + version: 1 + categories: + - name: SmartLock diff --git a/drivers/SmartThings/matter-lock/profiles/lock-user-pin-batteryLevel.yml b/drivers/SmartThings/matter-lock/profiles/lock-user-pin-batteryLevel.yml new file mode 100644 index 0000000000..582fcd3975 --- /dev/null +++ b/drivers/SmartThings/matter-lock/profiles/lock-user-pin-batteryLevel.yml @@ -0,0 +1,29 @@ +name: lock-user-pin-batteryLevel +components: +- id: main + capabilities: + - id: lock + version: 1 + config: + values: + - key: "lock.value" + enabledValues: + - locked + - unlocked + - not fully locked + - id: lockAlarm + version: 1 + - id: remoteControlStatus + version: 1 + - id: lockUsers + version: 1 + - id: lockCredentials + version: 1 + - id: batteryLevel + version: 1 + - id: firmwareUpdate + version: 1 + - id: refresh + version: 1 + categories: + - name: SmartLock diff --git a/drivers/SmartThings/matter-lock/profiles/lock-user-pin-schedule-battery.yml b/drivers/SmartThings/matter-lock/profiles/lock-user-pin-schedule-battery.yml new file mode 100644 index 0000000000..ac52c839fa --- /dev/null +++ b/drivers/SmartThings/matter-lock/profiles/lock-user-pin-schedule-battery.yml @@ -0,0 +1,31 @@ +name: lock-user-pin-schedule-battery +components: +- id: main + capabilities: + - id: lock + version: 1 + config: + values: + - key: "lock.value" + enabledValues: + - locked + - unlocked + - not fully locked + - id: lockAlarm + version: 1 + - id: remoteControlStatus + version: 1 + - id: lockUsers + version: 1 + - id: lockCredentials + version: 1 + - id: lockSchedules + version: 1 + - id: battery + version: 1 + - id: firmwareUpdate + version: 1 + - id: refresh + version: 1 + categories: + - name: SmartLock diff --git a/drivers/SmartThings/matter-lock/src/new-matter-lock/init.lua b/drivers/SmartThings/matter-lock/src/new-matter-lock/init.lua index 83db28279c..d0d0f1bd49 100644 --- a/drivers/SmartThings/matter-lock/src/new-matter-lock/init.lua +++ b/drivers/SmartThings/matter-lock/src/new-matter-lock/init.lua @@ -25,15 +25,19 @@ if version.api < 10 then end local DoorLock = clusters.DoorLock +local PowerSource = clusters.PowerSource local INITIAL_COTA_INDEX = 1 local ALL_INDEX = 0xFFFE local NEW_MATTER_LOCK_PRODUCTS = { {0x115f, 0x2802}, -- AQARA, U200 {0x115f, 0x2801}, -- AQARA, U300 + {0x147F, 0x0001}, -- U-tec {0x10E1, 0x2002} -- VDA } +local PROFILE_BASE_NAME = "__profile_base_name" + local subscribed_attributes = { [capabilities.lock.ID] = { DoorLock.attributes.LockState @@ -53,6 +57,12 @@ local subscribed_attributes = { [capabilities.lockSchedules.ID] = { DoorLock.attributes.NumberOfWeekDaySchedulesSupportedPerUser, DoorLock.attributes.NumberOfYearDaySchedulesSupportedPerUser + }, + [capabilities.battery.ID] = { + PowerSource.attributes.BatPercentRemaining + }, + [capabilities.batteryLevel.ID] = { + PowerSource.attributes.BatChargeLevel } } @@ -127,6 +137,7 @@ local function do_configure(driver, device) local week_schedule_eps = device:get_endpoints(DoorLock.ID, {feature_bitmap = DoorLock.types.Feature.WEEK_DAY_ACCESS_SCHEDULES}) local year_schedule_eps = device:get_endpoints(DoorLock.ID, {feature_bitmap = DoorLock.types.Feature.YEAR_DAY_ACCESS_SCHEDULES}) local unbolt_eps = device:get_endpoints(DoorLock.ID, {feature_bitmap = DoorLock.types.Feature.UNBOLT}) + local battery_eps = device:get_endpoints(PowerSource.ID, {feature_bitmap = PowerSource.types.PowerSourceFeature.BATTERY}) local profile_name = "lock" if #user_eps > 0 then @@ -144,8 +155,15 @@ local function do_configure(driver, device) else device:emit_event(capabilities.lock.supportedLockCommands({"lock", "unlock"}, {visibility = {displayed = false}})) end - device.log.info(string.format("Updating device profile to %s.", profile_name)) - device:try_update_metadata({profile = profile_name}) + if #battery_eps > 0 then + device:set_field(PROFILE_BASE_NAME, profile_name, {persist = true}) + local req = im.InteractionRequest(im.InteractionRequest.RequestType.READ, {}) + req:merge(clusters.PowerSource.attributes.AttributeList:read()) + device:send(req) + else + device.log.info(string.format("Updating device profile to %s.", profile_name)) + device:try_update_metadata({profile = profile_name}) + end end local function info_changed(driver, device, event, args) @@ -353,6 +371,49 @@ local function max_year_schedule_of_user_handler(driver, device, ib, response) device:emit_event(capabilities.lockSchedules.yearDaySchedulesPerUser(ib.data.value, {visibility = {displayed = false}})) end +--------------------------------- +-- Power Source Attribute List -- +--------------------------------- +local function handle_power_source_attribute_list(driver, device, ib, response) + local support_battery_percentage = false + for _, attr in ipairs(ib.data.elements) do + -- Re-profile the device if BatPercentRemaining (Attribute ID 0x0C) is present. + if attr.value == 0x0C then + support_battery_percentage = true + end + end + local profile_name = device:get_field(PROFILE_BASE_NAME) + if support_battery_percentage then + profile_name = profile_name .. "-battery" + else + profile_name = profile_name .. "-batteryLevel" + end + device.log.info(string.format("Updating device profile to %s.", profile_name)) + device:try_update_metadata({profile = profile_name}) +end + +------------------------------- +-- Battery Percent Remaining -- +------------------------------- +local function handle_battery_percent_remaining(driver, device, ib, response) + if ib.data.value ~= nil then + device:emit_event(capabilities.battery.battery(math.floor(ib.data.value / 2.0 + 0.5))) + end +end + +-------------------------- +-- Battery Charge Level -- +-------------------------- +local function handle_battery_charge_level(driver, device, ib, response) + if ib.data.value == PowerSource.types.BatChargeLevelEnum.OK then + device:emit_event(capabilities.batteryLevel.battery.normal()) + elseif ib.data.value == PowerSource.types.BatChargeLevelEnum.WARNING then + device:emit_event(capabilities.batteryLevel.battery.warning()) + elseif ib.data.value == PowerSource.types.BatChargeLevelEnum.CRITICAL then + device:emit_event(capabilities.batteryLevel.battery.critical()) + end +end + -- Capability Handler ----------------- -- Lock/Unlock -- @@ -1671,6 +1732,11 @@ local new_matter_lock_handler = { [DoorLock.attributes.RequirePINforRemoteOperation.ID] = require_remote_pin_handler, [DoorLock.attributes.NumberOfWeekDaySchedulesSupportedPerUser.ID] = max_week_schedule_of_user_handler, [DoorLock.attributes.NumberOfYearDaySchedulesSupportedPerUser.ID] = max_year_schedule_of_user_handler, + }, + [PowerSource.ID] = { + [PowerSource.attributes.AttributeList.ID] = handle_power_source_attribute_list, + [PowerSource.attributes.BatPercentRemaining.ID] = handle_battery_percent_remaining, + [PowerSource.attributes.BatChargeLevel.ID] = handle_battery_charge_level, } }, event = { @@ -1723,7 +1789,10 @@ local new_matter_lock_handler = { capabilities.lock, capabilities.lockUsers, capabilities.lockCredentials, - capabilities.lockSchedules + capabilities.lockSchedules, + capabilities.remoteControlStatus, + capabilities.battery, + capabilities.batteryLevel }, can_handle = is_new_matter_lock_products } From 5ac5f2e68df908a24ed56f25233752a67891f2cb Mon Sep 17 00:00:00 2001 From: Hunsup Jung Date: Fri, 20 Dec 2024 16:48:12 +0900 Subject: [PATCH 2/6] Update test cases for matter-lock Signed-off-by: Hunsup Jung --- .../matter-lock/src/new-matter-lock/init.lua | 2 +- .../src/test/test_new_matter_lock_battery.lua | 144 ++++++++++++++++++ 2 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 drivers/SmartThings/matter-lock/src/test/test_new_matter_lock_battery.lua diff --git a/drivers/SmartThings/matter-lock/src/new-matter-lock/init.lua b/drivers/SmartThings/matter-lock/src/new-matter-lock/init.lua index d0d0f1bd49..9f7a606b86 100644 --- a/drivers/SmartThings/matter-lock/src/new-matter-lock/init.lua +++ b/drivers/SmartThings/matter-lock/src/new-matter-lock/init.lua @@ -33,7 +33,7 @@ local NEW_MATTER_LOCK_PRODUCTS = { {0x115f, 0x2802}, -- AQARA, U200 {0x115f, 0x2801}, -- AQARA, U300 {0x147F, 0x0001}, -- U-tec - {0x10E1, 0x2002} -- VDA + {0x10E1, 0x2002} -- VDA } local PROFILE_BASE_NAME = "__profile_base_name" diff --git a/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock_battery.lua b/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock_battery.lua new file mode 100644 index 0000000000..fcf17e42e1 --- /dev/null +++ b/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock_battery.lua @@ -0,0 +1,144 @@ +-- Copyright 2023 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" +test.add_package_capability("lockAlarm.yml") +local clusters = require "st.matter.clusters" +local t_utils = require "integration_test.utils" +local uint32 = require "st.matter.data_types.Uint32" + +local DoorLock = clusters.DoorLock + +local mock_device = test.mock_device.build_test_matter_device({ + profile = t_utils.get_profile_definition("lock-user-pin.yml"), + manufacturer_info = { + vendor_id = 0x147F, + product_id = 0x0001, + }, + endpoints = { + { + endpoint_id = 0, + clusters = { + { cluster_id = clusters.Basic.ID, cluster_type = "SERVER" }, + }, + device_types = { + { device_type_id = 0x0016, device_type_revision = 1 } -- RootNode + } + }, + { + endpoint_id = 1, + clusters = { + { + cluster_id = DoorLock.ID, + cluster_type = "SERVER", + cluster_revision = 1, + feature_map = 0x0181, -- PIN & USR & COTA + }, + { + cluster_id = clusters.PowerSource.ID, + cluster_type = "SERVER", + feature_map = 10 + }, + }, + device_types = { + { device_type_id = 0x000A, device_type_revision = 1 } -- Door Lock + } + } + } +}) + +local function test_init() + local subscribe_request = DoorLock.attributes.LockState:subscribe(mock_device) + subscribe_request:merge(DoorLock.attributes.OperatingMode:subscribe(mock_device)) + subscribe_request:merge(DoorLock.attributes.NumberOfTotalUsersSupported:subscribe(mock_device)) + subscribe_request:merge(DoorLock.attributes.NumberOfPINUsersSupported:subscribe(mock_device)) + subscribe_request:merge(DoorLock.attributes.MaxPINCodeLength:subscribe(mock_device)) + subscribe_request:merge(DoorLock.attributes.MinPINCodeLength:subscribe(mock_device)) + subscribe_request:merge(DoorLock.attributes.RequirePINforRemoteOperation:subscribe(mock_device)) + subscribe_request:merge(DoorLock.events.LockOperation:subscribe(mock_device)) + subscribe_request:merge(DoorLock.events.DoorLockAlarm:subscribe(mock_device)) + subscribe_request:merge(DoorLock.events.LockUserChange:subscribe(mock_device)) + test.socket["matter"]:__expect_send({mock_device.id, subscribe_request}) + test.mock_device.add_test_device(mock_device) +end +test.set_test_init_function(test_init) + +test.register_coroutine_test( + "Test profile change when battery percent remaining attribute (attribute ID 12) is available", + function() + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + test.socket.matter:__expect_send( + { + mock_device.id, + clusters.PowerSource.attributes.AttributeList:read() + } + ) + test.wait_for_events() + test.socket.matter:__queue_receive( + { + mock_device.id, + clusters.PowerSource.attributes.AttributeList:build_test_report_data(mock_device, 1, + { + uint32(0), + uint32(1), + uint32(2), + uint32(12), + uint32(31), + uint32(65528), + uint32(65529), + uint32(65531), + uint32(65532), + uint32(65533), + }) + } + ) + mock_device:expect_metadata_update({ profile = "lock-user-pin-battery" }) + end +) + +test.register_coroutine_test( + "Test profile change when battery percent remaining attribute is not available", + function() + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + test.socket.matter:__expect_send( + { + mock_device.id, + clusters.PowerSource.attributes.AttributeList:read() + } + ) + test.wait_for_events() + test.socket.matter:__queue_receive( + { + mock_device.id, + clusters.PowerSource.attributes.AttributeList:build_test_report_data(mock_device, 1, + { + uint32(0), + uint32(1), + uint32(2), + uint32(31), + uint32(65528), + uint32(65529), + uint32(65531), + uint32(65532), + uint32(65533), + }) + } + ) + mock_device:expect_metadata_update({ profile = "lock-user-pin-batteryLevel" }) + end +) + +test.run_registered_tests() From 5002f41bdea72318be86b82de12e6897657288ff Mon Sep 17 00:00:00 2001 From: Hunsup Jung Date: Tue, 24 Dec 2024 14:02:20 +0900 Subject: [PATCH 3/6] Update handle_power_source_attribute_list function Signed-off-by: Hunsup Jung --- .../matter-lock/src/new-matter-lock/init.lua | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/SmartThings/matter-lock/src/new-matter-lock/init.lua b/drivers/SmartThings/matter-lock/src/new-matter-lock/init.lua index 9f7a606b86..f7adcf40c6 100644 --- a/drivers/SmartThings/matter-lock/src/new-matter-lock/init.lua +++ b/drivers/SmartThings/matter-lock/src/new-matter-lock/init.lua @@ -376,20 +376,26 @@ end --------------------------------- local function handle_power_source_attribute_list(driver, device, ib, response) local support_battery_percentage = false + local support_battery_level = false for _, attr in ipairs(ib.data.elements) do -- Re-profile the device if BatPercentRemaining (Attribute ID 0x0C) is present. if attr.value == 0x0C then support_battery_percentage = true end + if attr.value == 0x0E then + support_battery_level = true + end end local profile_name = device:get_field(PROFILE_BASE_NAME) - if support_battery_percentage then - profile_name = profile_name .. "-battery" - else - profile_name = profile_name .. "-batteryLevel" + if profile_name ~= nil then + if support_battery_percentage then + profile_name = profile_name .. "-battery" + elseif support_battery_level then + profile_name = profile_name .. "-batteryLevel" + end + device.log.info(string.format("Updating device profile to %s.", profile_name)) + device:try_update_metadata({profile = profile_name}) end - device.log.info(string.format("Updating device profile to %s.", profile_name)) - device:try_update_metadata({profile = profile_name}) end ------------------------------- @@ -1790,7 +1796,6 @@ local new_matter_lock_handler = { capabilities.lockUsers, capabilities.lockCredentials, capabilities.lockSchedules, - capabilities.remoteControlStatus, capabilities.battery, capabilities.batteryLevel }, From 49a5c7143c1715a83ec4a0f0ddb5764d08e4d744 Mon Sep 17 00:00:00 2001 From: Hunsup Jung Date: Tue, 24 Dec 2024 14:25:36 +0900 Subject: [PATCH 4/6] Add test cases for matter-lock driver Signed-off-by: Hunsup Jung --- .../src/test/test_new_matter_lock_battery.lua | 43 +++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock_battery.lua b/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock_battery.lua index fcf17e42e1..f13041a1e6 100644 --- a/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock_battery.lua +++ b/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock_battery.lua @@ -75,7 +75,7 @@ end test.set_test_init_function(test_init) test.register_coroutine_test( - "Test profile change when battery percent remaining attribute (attribute ID 12) is available", + "Test profile change when attributes related to BAT feature is not available.", function() test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) @@ -94,7 +94,6 @@ test.register_coroutine_test( uint32(0), uint32(1), uint32(2), - uint32(12), uint32(31), uint32(65528), uint32(65529), @@ -104,12 +103,12 @@ test.register_coroutine_test( }) } ) - mock_device:expect_metadata_update({ profile = "lock-user-pin-battery" }) + mock_device:expect_metadata_update({ profile = "lock-user-pin" }) end ) test.register_coroutine_test( - "Test profile change when battery percent remaining attribute is not available", + "Test profile change when BatChargeLevel attribute is available", function() test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) @@ -128,6 +127,7 @@ test.register_coroutine_test( uint32(0), uint32(1), uint32(2), + uint32(14), -- BatChargeLevel uint32(31), uint32(65528), uint32(65529), @@ -141,4 +141,39 @@ test.register_coroutine_test( end ) +test.register_coroutine_test( + "Test profile change when BatChargeLevel and BatPercentRemaining attributes are available", + function() + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + test.socket.matter:__expect_send( + { + mock_device.id, + clusters.PowerSource.attributes.AttributeList:read() + } + ) + test.wait_for_events() + test.socket.matter:__queue_receive( + { + mock_device.id, + clusters.PowerSource.attributes.AttributeList:build_test_report_data(mock_device, 1, + { + uint32(0), + uint32(1), + uint32(2), + uint32(12), -- BatPercentRemaining + uint32(14), -- BatChargeLevel + uint32(31), + uint32(65528), + uint32(65529), + uint32(65531), + uint32(65532), + uint32(65533), + }) + } + ) + mock_device:expect_metadata_update({ profile = "lock-user-pin-battery" }) + end +) + test.run_registered_tests() From 0cd0746a4e536af4fa7935acc01094b4e036a73f Mon Sep 17 00:00:00 2001 From: Hunsup Jung Date: Mon, 30 Dec 2024 10:13:37 +0900 Subject: [PATCH 5/6] Add lock-user-pin-batteryLevel profile Signed-off-by: Hunsup Jung --- .../lock-user-pin-schedule-batteryLevel.yml | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 drivers/SmartThings/matter-lock/profiles/lock-user-pin-schedule-batteryLevel.yml diff --git a/drivers/SmartThings/matter-lock/profiles/lock-user-pin-schedule-batteryLevel.yml b/drivers/SmartThings/matter-lock/profiles/lock-user-pin-schedule-batteryLevel.yml new file mode 100644 index 0000000000..d1b8ce8a13 --- /dev/null +++ b/drivers/SmartThings/matter-lock/profiles/lock-user-pin-schedule-batteryLevel.yml @@ -0,0 +1,31 @@ +name: lock-user-pin-schedule-batteryLevel +components: +- id: main + capabilities: + - id: lock + version: 1 + config: + values: + - key: "lock.value" + enabledValues: + - locked + - unlocked + - not fully locked + - id: lockAlarm + version: 1 + - id: remoteControlStatus + version: 1 + - id: lockUsers + version: 1 + - id: lockCredentials + version: 1 + - id: lockSchedules + version: 1 + - id: batteryLevel + version: 1 + - id: firmwareUpdate + version: 1 + - id: refresh + version: 1 + categories: + - name: SmartLock From 94dfd14ae406024f38c70f89b7bdcdd0b97a7d2a Mon Sep 17 00:00:00 2001 From: Hunsup Jung Date: Tue, 7 Jan 2025 14:46:56 +0900 Subject: [PATCH 6/6] Modify test_new_matter_lock_battery file Signed-off-by: Hunsup Jung --- .../src/test/test_new_matter_lock_battery.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock_battery.lua b/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock_battery.lua index f13041a1e6..1565b37799 100644 --- a/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock_battery.lua +++ b/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock_battery.lua @@ -13,6 +13,7 @@ -- limitations under the License. local test = require "integration_test" +local capabilities = require "st.capabilities" test.add_package_capability("lockAlarm.yml") local clusters = require "st.matter.clusters" local t_utils = require "integration_test.utils" @@ -79,6 +80,9 @@ test.register_coroutine_test( function() test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + test.socket.capability:__expect_send( + mock_device:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock"}, {visibility = {displayed = false}})) + ) test.socket.matter:__expect_send( { mock_device.id, @@ -112,6 +116,9 @@ test.register_coroutine_test( function() test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + test.socket.capability:__expect_send( + mock_device:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock"}, {visibility = {displayed = false}})) + ) test.socket.matter:__expect_send( { mock_device.id, @@ -146,6 +153,9 @@ test.register_coroutine_test( function() test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + test.socket.capability:__expect_send( + mock_device:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock"}, {visibility = {displayed = false}})) + ) test.socket.matter:__expect_send( { mock_device.id,