Skip to content

Matter Lock: modular reprofiling should run when the target profile changes, not only when optional capabilities change #2940

@ldeora

Description

@ldeora

Summary

The new-matter-lock sub-driver can detect that a Matter lock supports the DoorLock UNBOLT feature and correctly emits:

"supportedLockValues": ["locked", "unlocked", "unlatched", "not fully locked"],
"supportedLockCommands": ["lock", "unlock", "unlatch"]

However, the device may still remain on a profile that does not expose the unlatch UI, because match_profile_modular() only calls try_update_metadata() when the optional capability list changes.

This means a device can have the correct capability state, but the SmartThings app does not show the unlatch feature because the profile was not updated.

Tested with a real device

This was tested with a real Nuki Smart Lock Ultra.

With the current behavior, the device reported unlatch support in component status, but the SmartThings app did not show the unlatch control because the device remained on the non-unlatch profile.

After applying the proposed reprofiling fix locally, the same real device successfully migrated to:

lock-modular-embedded-unlatch

The SmartThings app then showed the unlatch feature as expected.

Observed behavior

Tested with a Nuki Smart Lock Ultra using the Matter Lock driver.

The device initially used a non-unlatch fallback profile. The driver detected UNBOLT and emitted:

"supportedLockCommands": ["lock", "unlock", "unlatch"]

but the app did not show the unlatch feature until the profile was actually changed to:

lock-modular-embedded-unlatch

The key difference was that try_update_metadata() did not run when only the target profile name changed.

Current code pattern

In drivers/SmartThings/matter-lock/src/new-matter-lock/init.lua, match_profile_modular() determines the correct modular profile name:

modular_profile_name = "lock-modular-embedded-unlatch"

when DoorLock.types.Feature.UNBOLT is supported.

But the metadata update is gated only by:

if lock_utils.optional_capabilities_list_changed(enabled_optional_component_capability_pairs, device.profile.components) then
  device:try_update_metadata({
    profile = modular_profile_name,
    optional_component_capabilities = enabled_optional_component_capability_pairs
  })
end

if lock_utils.optional_capabilities_list_changed(enabled_optional_component_capability_pairs, device.profile.components) then
device:try_update_metadata({profile = modular_profile_name, optional_component_capabilities = enabled_optional_component_capability_pairs})
end

This misses the case where the optional capabilities are unchanged, but the required profile changes from a non-unlatch profile to lock-modular-embedded-unlatch.

Expected behavior

The driver should update metadata when either:

  1. the optional capability list changed, or
  2. the target profile name changed.

Suggested fix

local optional_capabilities_changed = lock_utils.optional_capabilities_list_changed(
  enabled_optional_component_capability_pairs,
  device.profile.components
)

local profile_changed = device.profile.id ~= modular_profile_name and
  device.profile.name ~= modular_profile_name

if profile_changed or optional_capabilities_changed then
  device:try_update_metadata({
    profile = modular_profile_name,
    optional_component_capabilities = enabled_optional_component_capability_pairs
  })
end

Why this matters

The lock-modular-embedded-unlatch profile contains the detail-view push button for the unlatch command. Without the profile migration, the API state can correctly report that unlatch is supported, while the SmartThings app still does not expose the unlatch control.

Notes

This does not require changing the static fingerprint fallback profile. The fallback profile can remain as-is, provided the dynamic reprofiling logic can migrate the device once the DoorLock FeatureMap is known.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions