From 2b858ffc2e931532ed8400369beff26cfc79f458 Mon Sep 17 00:00:00 2001 From: Harrison Carter Date: Fri, 31 Jul 2026 10:07:25 -0500 Subject: [PATCH] Remove auto-migration for Zigbee locks on added --- drivers/SmartThings/zigbee-lock/src/init.lua | 15 +- .../src/test/test_init_lifecycle_handlers.lua | 182 +++++++++--------- 2 files changed, 100 insertions(+), 97 deletions(-) diff --git a/drivers/SmartThings/zigbee-lock/src/init.lua b/drivers/SmartThings/zigbee-lock/src/init.lua index b8b290af4d..a901e420db 100644 --- a/drivers/SmartThings/zigbee-lock/src/init.lua +++ b/drivers/SmartThings/zigbee-lock/src/init.lua @@ -16,13 +16,14 @@ local capability_handlers = require "lock_handlers.capabilities" local LockLifecycle = {} function LockLifecycle.device_added(driver, device) - if device:supports_capability(capabilities.lockCodes) and device._provisioning_state == "TYPED" then - -- set the migrated field to true so new devices use lockCredentials/lockUsers from the start. - -- auto-migration is only run for typed devices, as provisioned devices have already been onboarded, - -- and should be migrated manually by the user. - device:emit_event(capabilities.lockCodes.migrated(true, { visibility = { displayed = false } })) - device:set_field(consts.DRIVER_STATE.SLGA_MIGRATED, true, { persist = true }) -- persist the migration event in the datastore - end + -- Note: We should not auto-migrate for the time being + -- if device:supports_capability(capabilities.lockCodes) and device._provisioning_state == "TYPED" then + -- -- set the migrated field to true so new devices use lockCredentials/lockUsers from the start. + -- -- auto-migration is only run for typed devices, as provisioned devices have already been onboarded, + -- -- and should be migrated manually by the user. + -- device:emit_event(capabilities.lockCodes.migrated(true, { visibility = { displayed = false } })) + -- device:set_field(consts.DRIVER_STATE.SLGA_MIGRATED, true, { persist = true }) -- persist the migration event in the datastore + -- end -- set initial state driver:inject_capability_command(device, { capability = capabilities.refresh.ID, diff --git a/drivers/SmartThings/zigbee-lock/src/test/test_init_lifecycle_handlers.lua b/drivers/SmartThings/zigbee-lock/src/test/test_init_lifecycle_handlers.lua index 1ff448a719..6fae60df4f 100644 --- a/drivers/SmartThings/zigbee-lock/src/test/test_init_lifecycle_handlers.lua +++ b/drivers/SmartThings/zigbee-lock/src/test/test_init_lifecycle_handlers.lua @@ -99,50 +99,51 @@ end -- added (device_added) -- ============================================================================ -test.register_coroutine_test( - "added: TYPED device with lockCodes emits migrated event, persists SLGA_MIGRATED, and injects refresh", - function() - test.socket.device_lifecycle:__queue_receive({ mock_device_typed.id, "added" }) - - -- Migrated event is emitted before the injected refresh - test.socket.capability:__expect_send( - mock_device_typed:generate_test_message("main", - capabilities.lockCodes.migrated(true, { visibility = { displayed = false } })) - ) - -- inject_capability_command calls the refresh handler inline - test.socket.zigbee:__expect_send({ - mock_device_typed.id, - PowerConfiguration.attributes.BatteryPercentageRemaining:read(mock_device_typed), - }) - test.socket.zigbee:__expect_send({ - mock_device_typed.id, - DoorLock.attributes.LockState:read(mock_device_typed), - }) - test.socket.zigbee:__expect_send({ - mock_device_typed.id, - Alarms.attributes.AlarmCount:read(mock_device_typed), - }) - test.socket.zigbee:__expect_send({ - mock_device_typed.id, - DoorLock.attributes.MaxPINCodeLength:read(mock_device_typed), - }) - test.socket.zigbee:__expect_send({ - mock_device_typed.id, - DoorLock.attributes.MinPINCodeLength:read(mock_device_typed), - }) - test.socket.zigbee:__expect_send({ - mock_device_typed.id, - DoorLock.attributes.NumberOfPINUsersSupported:read(mock_device_typed), - }) - test.wait_for_events() - - assert( - mock_device_typed:get_field(constants.DRIVER_STATE.SLGA_MIGRATED) == true, - "SLGA_MIGRATED must be true after added fires for a TYPED device" - ) - end, - { test_init = make_test_init(mock_device_typed) } -) +-- Note: Remove test for the time being, since auto-migration on added is no longer the default behavior +-- test.register_coroutine_test( +-- "added: TYPED device with lockCodes emits migrated event, persists SLGA_MIGRATED, and injects refresh", +-- function() +-- test.socket.device_lifecycle:__queue_receive({ mock_device_typed.id, "added" }) + +-- -- Migrated event is emitted before the injected refresh +-- test.socket.capability:__expect_send( +-- mock_device_typed:generate_test_message("main", +-- capabilities.lockCodes.migrated(true, { visibility = { displayed = false } })) +-- ) +-- -- inject_capability_command calls the refresh handler inline +-- test.socket.zigbee:__expect_send({ +-- mock_device_typed.id, +-- PowerConfiguration.attributes.BatteryPercentageRemaining:read(mock_device_typed), +-- }) +-- test.socket.zigbee:__expect_send({ +-- mock_device_typed.id, +-- DoorLock.attributes.LockState:read(mock_device_typed), +-- }) +-- test.socket.zigbee:__expect_send({ +-- mock_device_typed.id, +-- Alarms.attributes.AlarmCount:read(mock_device_typed), +-- }) +-- test.socket.zigbee:__expect_send({ +-- mock_device_typed.id, +-- DoorLock.attributes.MaxPINCodeLength:read(mock_device_typed), +-- }) +-- test.socket.zigbee:__expect_send({ +-- mock_device_typed.id, +-- DoorLock.attributes.MinPINCodeLength:read(mock_device_typed), +-- }) +-- test.socket.zigbee:__expect_send({ +-- mock_device_typed.id, +-- DoorLock.attributes.NumberOfPINUsersSupported:read(mock_device_typed), +-- }) +-- test.wait_for_events() + +-- assert( +-- mock_device_typed:get_field(constants.DRIVER_STATE.SLGA_MIGRATED) == true, +-- "SLGA_MIGRATED must be true after added fires for a TYPED device" +-- ) +-- end, +-- { test_init = make_test_init(mock_device_typed) } +-- ) test.register_coroutine_test( "added: non-TYPED (PROVISIONED) device with lockCodes does NOT emit migrated but still injects refresh", @@ -433,52 +434,53 @@ test.register_coroutine_test( -- driverSwitched (LockLifecycle.driver_switched) -- ============================================================================ -test.register_coroutine_test( - "driver_switched: device with lockCodes and migrated=true persists SLGA_MIGRATED and updates metadata", - function() - test.socket.device_lifecycle:__queue_receive({ mock_device_typed.id, "added" }) - - -- Migrated event is emitted before the injected refresh - test.socket.capability:__expect_send( - mock_device_typed:generate_test_message("main", - capabilities.lockCodes.migrated(true, { visibility = { displayed = false } })) - ) - -- inject_capability_command calls the refresh handler inline - test.socket.zigbee:__expect_send({ - mock_device_typed.id, - PowerConfiguration.attributes.BatteryPercentageRemaining:read(mock_device_typed), - }) - test.socket.zigbee:__expect_send({ - mock_device_typed.id, - DoorLock.attributes.LockState:read(mock_device_typed), - }) - test.socket.zigbee:__expect_send({ - mock_device_typed.id, - Alarms.attributes.AlarmCount:read(mock_device_typed), - }) - test.socket.zigbee:__expect_send({ - mock_device_typed.id, - DoorLock.attributes.MaxPINCodeLength:read(mock_device_typed), - }) - test.socket.zigbee:__expect_send({ - mock_device_typed.id, - DoorLock.attributes.MinPINCodeLength:read(mock_device_typed), - }) - test.socket.zigbee:__expect_send({ - mock_device_typed.id, - DoorLock.attributes.NumberOfPINUsersSupported:read(mock_device_typed), - }) - test.wait_for_events() - - -- driverSwitched occurs after added, so migrated=true is already set in the capability state cache - test.socket.device_lifecycle:__queue_receive({ mock_device_typed.id, "driver_switched" }) - mock_device_typed:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.wait_for_events() - - assert(mock_device_typed:get_field(constants.DRIVER_STATE.SLGA_MIGRATED) == true) - end, - { test_init = make_test_init(mock_device_typed) } -) +-- Note: Remove test for the time being, since auto-migration on added is no longer the default behavior, and that screws up this test +-- test.register_coroutine_test( +-- "driver_switched: device with lockCodes and migrated=true persists SLGA_MIGRATED and updates metadata", +-- function() +-- test.socket.device_lifecycle:__queue_receive({ mock_device_typed.id, "added" }) + +-- -- Migrated event is emitted before the injected refresh +-- test.socket.capability:__expect_send( +-- mock_device_typed:generate_test_message("main", +-- capabilities.lockCodes.migrated(true, { visibility = { displayed = false } })) +-- ) +-- -- inject_capability_command calls the refresh handler inline +-- test.socket.zigbee:__expect_send({ +-- mock_device_typed.id, +-- PowerConfiguration.attributes.BatteryPercentageRemaining:read(mock_device_typed), +-- }) +-- test.socket.zigbee:__expect_send({ +-- mock_device_typed.id, +-- DoorLock.attributes.LockState:read(mock_device_typed), +-- }) +-- test.socket.zigbee:__expect_send({ +-- mock_device_typed.id, +-- Alarms.attributes.AlarmCount:read(mock_device_typed), +-- }) +-- test.socket.zigbee:__expect_send({ +-- mock_device_typed.id, +-- DoorLock.attributes.MaxPINCodeLength:read(mock_device_typed), +-- }) +-- test.socket.zigbee:__expect_send({ +-- mock_device_typed.id, +-- DoorLock.attributes.MinPINCodeLength:read(mock_device_typed), +-- }) +-- test.socket.zigbee:__expect_send({ +-- mock_device_typed.id, +-- DoorLock.attributes.NumberOfPINUsersSupported:read(mock_device_typed), +-- }) +-- test.wait_for_events() + +-- -- driverSwitched occurs after added, so migrated=true is already set in the capability state cache +-- test.socket.device_lifecycle:__queue_receive({ mock_device_typed.id, "driver_switched" }) +-- mock_device_typed:expect_metadata_update({ provisioning_state = "PROVISIONED" }) +-- test.wait_for_events() + +-- assert(mock_device_typed:get_field(constants.DRIVER_STATE.SLGA_MIGRATED) == true) +-- end, +-- { test_init = make_test_init(mock_device_typed) } +-- ) -- ============================================================================ test.run_registered_tests()