mirror of
https://github.com/home-assistant/core.git
synced 2025-07-15 17:27:10 +00:00
Fix locking/unlocking transition state in Matter lock platform (#121099)
This commit is contained in:
parent
ac9c08f52c
commit
24f6e6e885
@ -90,6 +90,9 @@ class MatterLock(MatterEntity, LockEntity):
|
|||||||
|
|
||||||
async def async_lock(self, **kwargs: Any) -> None:
|
async def async_lock(self, **kwargs: Any) -> None:
|
||||||
"""Lock the lock with pin if needed."""
|
"""Lock the lock with pin if needed."""
|
||||||
|
# optimistically signal locking to state machine
|
||||||
|
self._attr_is_locking = True
|
||||||
|
self.async_write_ha_state()
|
||||||
code: str | None = kwargs.get(ATTR_CODE)
|
code: str | None = kwargs.get(ATTR_CODE)
|
||||||
code_bytes = code.encode() if code else None
|
code_bytes = code.encode() if code else None
|
||||||
await self.send_device_command(
|
await self.send_device_command(
|
||||||
@ -98,6 +101,9 @@ class MatterLock(MatterEntity, LockEntity):
|
|||||||
|
|
||||||
async def async_unlock(self, **kwargs: Any) -> None:
|
async def async_unlock(self, **kwargs: Any) -> None:
|
||||||
"""Unlock the lock with pin if needed."""
|
"""Unlock the lock with pin if needed."""
|
||||||
|
# optimistically signal unlocking to state machine
|
||||||
|
self._attr_is_unlocking = True
|
||||||
|
self.async_write_ha_state()
|
||||||
code: str | None = kwargs.get(ATTR_CODE)
|
code: str | None = kwargs.get(ATTR_CODE)
|
||||||
code_bytes = code.encode() if code else None
|
code_bytes = code.encode() if code else None
|
||||||
if self.supports_unbolt:
|
if self.supports_unbolt:
|
||||||
@ -114,6 +120,9 @@ class MatterLock(MatterEntity, LockEntity):
|
|||||||
|
|
||||||
async def async_open(self, **kwargs: Any) -> None:
|
async def async_open(self, **kwargs: Any) -> None:
|
||||||
"""Open the door latch."""
|
"""Open the door latch."""
|
||||||
|
# optimistically signal unlocking to state machine
|
||||||
|
self._attr_is_unlocking = True
|
||||||
|
self.async_write_ha_state()
|
||||||
code: str | None = kwargs.get(ATTR_CODE)
|
code: str | None = kwargs.get(ATTR_CODE)
|
||||||
code_bytes = code.encode() if code else None
|
code_bytes = code.encode() if code else None
|
||||||
await self.send_device_command(
|
await self.send_device_command(
|
||||||
@ -135,26 +144,23 @@ class MatterLock(MatterEntity, LockEntity):
|
|||||||
clusters.DoorLock.Attributes.LockState
|
clusters.DoorLock.Attributes.LockState
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# always reset the optimisically (un)locking state on state update
|
||||||
|
self._attr_is_locking = False
|
||||||
|
self._attr_is_unlocking = False
|
||||||
|
|
||||||
LOGGER.debug("Lock state: %s for %s", lock_state, self.entity_id)
|
LOGGER.debug("Lock state: %s for %s", lock_state, self.entity_id)
|
||||||
|
|
||||||
if lock_state is clusters.DoorLock.Enums.DlLockState.kLocked:
|
if lock_state is clusters.DoorLock.Enums.DlLockState.kLocked:
|
||||||
self._attr_is_locked = True
|
self._attr_is_locked = True
|
||||||
self._attr_is_locking = False
|
elif lock_state in (
|
||||||
self._attr_is_unlocking = False
|
clusters.DoorLock.Enums.DlLockState.kUnlocked,
|
||||||
elif lock_state is clusters.DoorLock.Enums.DlLockState.kUnlocked:
|
clusters.DoorLock.Enums.DlLockState.kUnlatched,
|
||||||
|
clusters.DoorLock.Enums.DlLockState.kNotFullyLocked,
|
||||||
|
):
|
||||||
self._attr_is_locked = False
|
self._attr_is_locked = False
|
||||||
self._attr_is_locking = False
|
|
||||||
self._attr_is_unlocking = False
|
|
||||||
elif lock_state is clusters.DoorLock.Enums.DlLockState.kNotFullyLocked:
|
|
||||||
if self.is_locked is True:
|
|
||||||
self._attr_is_unlocking = True
|
|
||||||
elif self.is_locked is False:
|
|
||||||
self._attr_is_locking = True
|
|
||||||
else:
|
else:
|
||||||
# According to the matter docs a null state can happen during device startup.
|
# According to the matter docs a null state can happen during device startup.
|
||||||
self._attr_is_locked = None
|
self._attr_is_locked = None
|
||||||
self._attr_is_locking = None
|
|
||||||
self._attr_is_unlocking = None
|
|
||||||
|
|
||||||
if self.supports_door_position_sensor:
|
if self.supports_door_position_sensor:
|
||||||
door_state = self.get_matter_attribute_value(
|
door_state = self.get_matter_attribute_value(
|
||||||
|
@ -8,13 +8,11 @@ import pytest
|
|||||||
|
|
||||||
from homeassistant.components.lock import (
|
from homeassistant.components.lock import (
|
||||||
STATE_LOCKED,
|
STATE_LOCKED,
|
||||||
STATE_LOCKING,
|
|
||||||
STATE_OPEN,
|
STATE_OPEN,
|
||||||
STATE_UNLOCKED,
|
STATE_UNLOCKED,
|
||||||
STATE_UNLOCKING,
|
|
||||||
LockEntityFeature,
|
LockEntityFeature,
|
||||||
)
|
)
|
||||||
from homeassistant.const import ATTR_CODE, STATE_UNKNOWN
|
from homeassistant.const import ATTR_CODE, STATE_LOCKING, STATE_UNKNOWN
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import ServiceValidationError
|
from homeassistant.exceptions import ServiceValidationError
|
||||||
import homeassistant.helpers.entity_registry as er
|
import homeassistant.helpers.entity_registry as er
|
||||||
@ -68,14 +66,14 @@ async def test_lock(
|
|||||||
|
|
||||||
state = hass.states.get("lock.mock_door_lock_lock")
|
state = hass.states.get("lock.mock_door_lock_lock")
|
||||||
assert state
|
assert state
|
||||||
assert state.state == STATE_LOCKED
|
assert state.state == STATE_LOCKING
|
||||||
|
|
||||||
set_node_attribute(door_lock, 1, 257, 0, 0)
|
set_node_attribute(door_lock, 1, 257, 0, 0)
|
||||||
await trigger_subscription_callback(hass, matter_client)
|
await trigger_subscription_callback(hass, matter_client)
|
||||||
|
|
||||||
state = hass.states.get("lock.mock_door_lock_lock")
|
state = hass.states.get("lock.mock_door_lock_lock")
|
||||||
assert state
|
assert state
|
||||||
assert state.state == STATE_UNLOCKING
|
assert state.state == STATE_UNLOCKED
|
||||||
|
|
||||||
set_node_attribute(door_lock, 1, 257, 0, 2)
|
set_node_attribute(door_lock, 1, 257, 0, 2)
|
||||||
await trigger_subscription_callback(hass, matter_client)
|
await trigger_subscription_callback(hass, matter_client)
|
||||||
@ -89,7 +87,7 @@ async def test_lock(
|
|||||||
|
|
||||||
state = hass.states.get("lock.mock_door_lock_lock")
|
state = hass.states.get("lock.mock_door_lock_lock")
|
||||||
assert state
|
assert state
|
||||||
assert state.state == STATE_LOCKING
|
assert state.state == STATE_UNLOCKED
|
||||||
|
|
||||||
set_node_attribute(door_lock, 1, 257, 0, None)
|
set_node_attribute(door_lock, 1, 257, 0, None)
|
||||||
await trigger_subscription_callback(hass, matter_client)
|
await trigger_subscription_callback(hass, matter_client)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user