Summary
The Matter Lock driver currently does not expose the Matter Door Lock DoorState attribute through the SmartThings doorState capability.
For Matter locks that support the Door Lock DOOR_POSITION_SENSOR feature, the driver should expose the door position as a read-only doorState capability. This allows SmartThings to distinguish between the lock state and the actual door state.
Example:
Lock state: locked / unlocked / unlatched / not fully locked
Door state: open / closed / ajar / jammed / forcedOpen / unspecifiedError
These are separate concepts and both are useful for locks such as the Nuki Smart Lock Ultra.
Tested device
This was tested with a real Nuki Smart Lock Ultra paired to SmartThings via Matter.
The device reports Door Lock FeatureMap support for the relevant functionality and can provide a valid DoorState value. With a local implementation, SmartThings component status correctly reported:
"doorState": {
"doorState": {
"value": "closed"
},
"supportedDoorStates": {
"value": [
"open",
"closed",
"jammed",
"forcedOpen",
"unspecifiedError",
"ajar"
]
}
}
The doorState capability also became available as a Routine condition when added to the generated presentation.
Current driver behavior
The current Matter Lock driver handles LockState, OperatingMode, battery-related PowerSource attributes, lock users, lock credentials, schedules, Aliro, and lock alarms.
However, it does not currently expose DoorLock.attributes.DoorState through the doorState capability.
As a result, the device can support door-position information at the Matter layer, but SmartThings does not expose it to the user or to Routines.
Why this matters
For a door lock, lock state and door state are different and both are important.
Examples:
- A lock can be locked while the door is physically closed.
- A lock can be unlocked while the door is still closed.
- A door can be open while the lock state is not sufficient to describe the physical situation.
- Automations often need to know whether the door is actually closed before locking.
- Users may want Routines such as “notify me if the door is open” or “only lock if the door is closed.”
For devices such as the Nuki Smart Lock Ultra, exposing DoorState makes SmartThings a better Matter controller because it can represent the full lock/door state instead of only the lock actuator state.
Expected behavior
For Matter locks whose Door Lock cluster supports DOOR_POSITION_SENSOR, the driver should:
- Add
doorState as an optional capability to the relevant modular lock profiles.
- Enable the optional
doorState capability only when the Matter Door Lock FeatureMap indicates Door Position Sensor support.
- Subscribe to
DoorLock.attributes.DoorState.
- Map Matter
DoorStateEnum values to SmartThings doorState values.
- Emit a fixed, safe
supportedDoorStates list when the capability is active.
- Read
DoorState during refresh when the capability is supported.
- Avoid using
contactSensor as a workaround; this should use the standard doorState capability.
Suggested mapping
The Matter Door Lock DoorStateEnum values should map to SmartThings doorState values as follows:
| Matter DoorStateEnum |
SmartThings doorState |
DOOR_OPEN |
open |
DOOR_CLOSED |
closed |
DOOR_JAMMED |
jammed |
DOOR_FORCED_OPEN |
forcedOpen |
DOOR_UNSPECIFIED_ERROR |
unspecifiedError |
DOOR_AJAR |
ajar |
Unknown or unsupported values should fall back conservatively to unspecifiedError.
Important implementation note
supportedDoorStates should not be built as a history of observed door-state reports.
A safe implementation should emit a fixed list such as:
local SUPPORTED_DOOR_STATES = {
"open",
"closed",
"jammed",
"forcedOpen",
"unspecifiedError",
"ajar",
}
and then emit only the current state separately:
device:emit_event(capabilities.doorState.doorState.closed())
This is important because supportedDoorStates is metadata. It should not grow over time as repeated open / closed reports arrive.
Suggested implementation approach
1. Add a profiling field
local profiling_data = {
BATTERY_SUPPORT = "__BATTERY_SUPPORT",
ENABLE_DOOR_STATE = "__ENABLE_DOOR_STATE",
}
2. Add DoorState to subscribed attributes
[capabilities.doorState.ID] = {
DoorLock.attributes.DoorState
},
3. Enable the optional capability only when supported
In match_profile_modular(), add doorState only when Door Position Sensor support has been detected:
if device:get_field(profiling_data.ENABLE_DOOR_STATE) then
table.insert(main_component_capabilities, capabilities.doorState.ID)
end
The ENABLE_DOOR_STATE field can be set from the Door Lock FeatureMap:
if ib.data.value & DoorLock.types.Feature.DOOR_POSITION_SENSOR == 0 then
device:set_field(profiling_data.ENABLE_DOOR_STATE, false, {persist = true})
else
device:set_field(profiling_data.ENABLE_DOOR_STATE, true, {persist = true})
end
After updating that field, the driver should run the profile matching logic so the optional capability can be enabled.
4. Add a DoorState handler
local SUPPORTED_DOOR_STATES = {
"open",
"closed",
"jammed",
"forcedOpen",
"unspecifiedError",
"ajar",
}
local function emit_supported_door_states_if_needed(device)
if device:supports_capability_by_id(capabilities.doorState.ID) and
device:get_latest_state("main", capabilities.doorState.ID, capabilities.doorState.supportedDoorStates.NAME) == nil then
device:emit_event(capabilities.doorState.supportedDoorStates(
SUPPORTED_DOOR_STATES,
{visibility = {displayed = false}}
))
end
end
local function door_state_handler(driver, device, ib, response)
if ib.data.value == nil then
return
end
if not device:supports_capability_by_id(capabilities.doorState.ID) then
return
end
emit_supported_door_states_if_needed(device)
local DoorStateEnum = DoorLock.types.DoorStateEnum
local door_state = capabilities.doorState.doorState
local DOOR_STATE_MAP = {
[DoorStateEnum.DOOR_OPEN] = door_state.open,
[DoorStateEnum.DOOR_CLOSED] = door_state.closed,
[DoorStateEnum.DOOR_JAMMED] = door_state.jammed,
[DoorStateEnum.DOOR_FORCED_OPEN] = door_state.forcedOpen,
[DoorStateEnum.DOOR_UNSPECIFIED_ERROR] = door_state.unspecifiedError,
[DoorStateEnum.DOOR_AJAR] = door_state.ajar,
}
local event_factory = DOOR_STATE_MAP[ib.data.value] or door_state.unspecifiedError
device:emit_event(event_factory())
end
5. Register the attribute handler
[DoorLock.attributes.DoorState.ID] = door_state_handler,
6. Add doorState to modular profiles
The relevant modular lock profiles should declare doorState as optional:
- id: doorState
version: 1
optional: true
At minimum, this is needed for:
lock-modular.yml
lock-modular-embedded-unlatch.yml
7. Add DoorState to presentation / automations
For profiles with embedded deviceConfig, doorState should be included as a read-only state in detailView and as an automation condition.
Example:
detailView:
- component: main
capability: doorState
version: 1
automation:
conditions:
- component: main
capability: doorState
version: 1
It should not be added as an automation action or as a dashboard action because doorState is read-only.
Local test result
With a local implementation on a real Nuki Smart Lock Ultra:
- The device migrated to
lock-modular-embedded-unlatch.
- The
doorState capability was enabled.
- Component status reported
doorState.closed.
supportedDoorStates remained a fixed list and did not grow.
doorState appeared as a Routine condition.
- Lock/unlock/unlatch command behavior was not changed.
App UI note
The generated device presentation can include doorState in detailView and automation.conditions.
In testing, doorState appeared in Routines as a condition. The SmartThings app detail screen for the lock may still use a specialized Smart Lock UI/plugin that does not render every generated detail-view item. If so, the app detail UI may require separate handling. However, the driver-side capability state and Routine condition support work correctly once doorState is exposed.
Suggested tests
Recommended tests:
- Matter lock with
DOOR_POSITION_SENSOR support enables optional doorState.
- Matter lock without
DOOR_POSITION_SENSOR support does not enable doorState.
- DoorState reports map correctly:
- open
- closed
- ajar
- jammed
- forcedOpen
- unspecifiedError
- Repeated open/closed reports do not append duplicate values to
supportedDoorStates.
- Refresh reads
DoorState only when the device supports the doorState capability.
- Routines expose
doorState as a condition.
- No changes are made to lock/unlock/unlatch command semantics.
Summary
The Matter Lock driver currently does not expose the Matter Door Lock
DoorStateattribute through the SmartThingsdoorStatecapability.For Matter locks that support the Door Lock
DOOR_POSITION_SENSORfeature, the driver should expose the door position as a read-onlydoorStatecapability. This allows SmartThings to distinguish between the lock state and the actual door state.Example:
These are separate concepts and both are useful for locks such as the Nuki Smart Lock Ultra.
Tested device
This was tested with a real Nuki Smart Lock Ultra paired to SmartThings via Matter.
The device reports Door Lock FeatureMap support for the relevant functionality and can provide a valid
DoorStatevalue. With a local implementation, SmartThings component status correctly reported:The
doorStatecapability also became available as a Routine condition when added to the generated presentation.Current driver behavior
The current Matter Lock driver handles
LockState,OperatingMode, battery-related PowerSource attributes, lock users, lock credentials, schedules, Aliro, and lock alarms.However, it does not currently expose
DoorLock.attributes.DoorStatethrough thedoorStatecapability.As a result, the device can support door-position information at the Matter layer, but SmartThings does not expose it to the user or to Routines.
Why this matters
For a door lock, lock state and door state are different and both are important.
Examples:
For devices such as the Nuki Smart Lock Ultra, exposing DoorState makes SmartThings a better Matter controller because it can represent the full lock/door state instead of only the lock actuator state.
Expected behavior
For Matter locks whose Door Lock cluster supports
DOOR_POSITION_SENSOR, the driver should:doorStateas an optional capability to the relevant modular lock profiles.doorStatecapability only when the Matter Door Lock FeatureMap indicates Door Position Sensor support.DoorLock.attributes.DoorState.DoorStateEnumvalues to SmartThingsdoorStatevalues.supportedDoorStateslist when the capability is active.DoorStateduring refresh when the capability is supported.contactSensoras a workaround; this should use the standarddoorStatecapability.Suggested mapping
The Matter Door Lock
DoorStateEnumvalues should map to SmartThingsdoorStatevalues as follows:DOOR_OPENopenDOOR_CLOSEDclosedDOOR_JAMMEDjammedDOOR_FORCED_OPENforcedOpenDOOR_UNSPECIFIED_ERRORunspecifiedErrorDOOR_AJARajarUnknown or unsupported values should fall back conservatively to
unspecifiedError.Important implementation note
supportedDoorStatesshould not be built as a history of observed door-state reports.A safe implementation should emit a fixed list such as:
and then emit only the current state separately:
This is important because
supportedDoorStatesis metadata. It should not grow over time as repeatedopen/closedreports arrive.Suggested implementation approach
1. Add a profiling field
2. Add
DoorStateto subscribed attributes3. Enable the optional capability only when supported
In
match_profile_modular(), adddoorStateonly when Door Position Sensor support has been detected:The
ENABLE_DOOR_STATEfield can be set from the Door Lock FeatureMap:After updating that field, the driver should run the profile matching logic so the optional capability can be enabled.
4. Add a DoorState handler
5. Register the attribute handler
6. Add
doorStateto modular profilesThe relevant modular lock profiles should declare
doorStateas optional:At minimum, this is needed for:
7. Add DoorState to presentation / automations
For profiles with embedded
deviceConfig,doorStateshould be included as a read-only state indetailViewand as an automation condition.Example:
It should not be added as an automation action or as a dashboard action because
doorStateis read-only.Local test result
With a local implementation on a real Nuki Smart Lock Ultra:
lock-modular-embedded-unlatch.doorStatecapability was enabled.doorState.closed.supportedDoorStatesremained a fixed list and did not grow.doorStateappeared as a Routine condition.App UI note
The generated device presentation can include
doorStateindetailViewandautomation.conditions.In testing,
doorStateappeared in Routines as a condition. The SmartThings app detail screen for the lock may still use a specialized Smart Lock UI/plugin that does not render every generated detail-view item. If so, the app detail UI may require separate handling. However, the driver-side capability state and Routine condition support work correctly oncedoorStateis exposed.Suggested tests
Recommended tests:
DOOR_POSITION_SENSORsupport enables optionaldoorState.DOOR_POSITION_SENSORsupport does not enabledoorState.supportedDoorStates.DoorStateonly when the device supports thedoorStatecapability.doorStateas a condition.