From d1352c6b134da57f0f91e7039aa425c9223aa04e Mon Sep 17 00:00:00 2001 From: Laurens <43173895+GreenGrassBlueOcean@users.noreply.github.com> Date: Fri, 25 Sep 2026 10:22:59 +0200 Subject: [PATCH] fix(message): motion frames have no on/off state (is_on is None) Follow-up to fedem95 review on PR #59: https://github.com/OpenWebNet-HA/OWNd/pull/59#pullrequestreview-5311439506 A motion frame such as *1*34*74## reports motion detection from a sensor, not an actuator on/off state. Previously, 34 fell outside 0 < state < 32, causing is_on to evaluate to False (switched off). Motion events now leave is_on as None, matching the principle that frames without an on/off state return None rather than False. --- OWNd/message.py | 9 +++++---- tests/test_message_protocol.py | 10 +++++++++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/OWNd/message.py b/OWNd/message.py index db2ec48..5b26e73 100755 --- a/OWNd/message.py +++ b/OWNd/message.py @@ -662,9 +662,9 @@ def transition(self) -> int | None: @property def is_on(self) -> bool | None: """True/False when the on/off state is known, None otherwise (e.g. a - reply carrying only a dimension such as illuminance or a timer, or a - WHAT outside the published table; see unknown_state).""" - if self._state is None: + motion event, a reply carrying only a dimension such as illuminance + or a timer, or a WHAT outside the published table; see unknown_state).""" + if self._state is None or self._motion: return None return 0 < self._state < 32 @@ -680,7 +680,8 @@ def unknown_state(self) -> int | None: @property def is_sensor(self) -> bool: return ( - self._state == 34 + self._motion + or self._state == 34 or (self._dimension is not None and self._dimension in (5, 6, 7)) or self._type in ( diff --git a/tests/test_message_protocol.py b/tests/test_message_protocol.py index 0916afd..ee59358 100644 --- a/tests/test_message_protocol.py +++ b/tests/test_message_protocol.py @@ -248,11 +248,19 @@ def test_lighting_what_in_the_table_keeps_its_state(what: int, is_on: bool) -> N def test_lighting_motion_what_34_is_not_an_unknown_state() -> None: # 34 is not in WHO_1.pdf; OWNd decodes it as motion (ZigBee variant). + # A motion frame says nothing about on/off, so is_on is None (fedem95 review on PR #59). msg = OWNLightingEvent("*1*34*21##") assert msg.motion is True - assert msg.is_on is False + assert msg.is_on is None assert msg.unknown_state is None + assert msg.is_sensor is True + + # Frame cited in review: *1*34*74## + msg74 = OWNLightingEvent("*1*34*74##") + assert msg74.motion is True + assert msg74.is_on is None + assert msg74.unknown_state is None @pytest.mark.parametrize("frame", ["*1*1000#1*74##", "*1*1000#19*74##"])