Skip to content
14 changes: 13 additions & 1 deletion homeassistant/components/lock/zwave.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
WORKAROUND_V2BTZE = 1
WORKAROUND_DEVICE_STATE = 2
WORKAROUND_TRACK_MESSAGE = 4
WORKAROUND_ALARM_TYPE = 8

DEVICE_MAPPINGS = {
POLYCONTROL_DANALOCK_V2_BTZE_LOCK: WORKAROUND_V2BTZE,
Expand All @@ -42,7 +43,7 @@
(0x0129, 0xAA00): WORKAROUND_DEVICE_STATE,
(0x0129, 0x0000): WORKAROUND_DEVICE_STATE,
# Yale YRD220 (as reported by adrum in PR #17386)
(0x0109, 0x0000): WORKAROUND_DEVICE_STATE,
(0x0109, 0x0000): WORKAROUND_DEVICE_STATE | WORKAROUND_ALARM_TYPE,
# Schlage BE469
(0x003B, 0x5044): WORKAROUND_DEVICE_STATE | WORKAROUND_TRACK_MESSAGE,
# Schlage FE599NX
Expand Down Expand Up @@ -236,6 +237,7 @@ def __init__(self, values):
self._state_workaround = False
self._track_message_workaround = False
self._previous_message = None
self._alarm_type_workaround = False

# Enable appropriate workaround flags for our device
# Make sure that we have values for the key before converting to int
Expand All @@ -256,6 +258,10 @@ def __init__(self, values):
if workaround & WORKAROUND_TRACK_MESSAGE:
self._track_message_workaround = True
_LOGGER.debug("Message tracking workaround enabled")
if workaround & WORKAROUND_ALARM_TYPE:
self._alarm_type_workaround = True
_LOGGER.debug(
"Alarm Type device state workaround enabled")
self.update_properties()

def update_properties(self):
Expand Down Expand Up @@ -310,6 +316,12 @@ def update_properties(self):

if not alarm_type:
return

if self._alarm_type_workaround:
self._state = LOCK_STATUS.get(str(alarm_type))
_LOGGER.debug("workaround: lock state set to %s -- alarm type: %s",
self._state, str(alarm_type))

if alarm_type == 21:
self._lock_status = '{}{}'.format(
LOCK_ALARM_TYPE.get(str(alarm_type)),
Expand Down
41 changes: 41 additions & 0 deletions tests/components/lock/test_zwave.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,47 @@ def test_v2btze_value_changed(mock_openzwave):
assert device.is_locked


def test_alarm_type_workaround(mock_openzwave):
Comment thread
adrum marked this conversation as resolved.
"""Test value changed for Z-Wave lock using alarm type."""
node = MockNode(manufacturer_id='0109', product_id='0000')
values = MockEntityValues(
primary=MockValue(data=True, node=node),
access_control=None,
alarm_type=MockValue(data=16, node=node),
alarm_level=None,
)
device = zwave.get_device(node=node, values=values)
assert not device.is_locked

values.alarm_type.data = 18
value_changed(values.alarm_type)
assert device.is_locked

values.alarm_type.data = 19
value_changed(values.alarm_type)
assert not device.is_locked

values.alarm_type.data = 21
value_changed(values.alarm_type)
assert device.is_locked

values.alarm_type.data = 22
value_changed(values.alarm_type)
assert not device.is_locked

values.alarm_type.data = 24
value_changed(values.alarm_type)
assert device.is_locked

values.alarm_type.data = 25
value_changed(values.alarm_type)
assert not device.is_locked

values.alarm_type.data = 27
value_changed(values.alarm_type)
assert device.is_locked


def test_lock_access_control(mock_openzwave):
"""Test access control for Z-Wave lock."""
node = MockNode()
Expand Down