Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ All notable changes to `OWNd` are documented in this file.
- Canonical `libqtdevices` (`TS10_1_0_23`) coarse `WHAT 2..10` $\leftrightarrow$ fine `1..100%` conversion helpers (`COARSE_PRESET_TO_PERCENT`, `brightness_preset_to_percent`, `percent_to_brightness_preset`), `OWNLightingEvent.is_coarse_dimmer`, `OWNLightingEvent.brightness_preset_percent`, and `OWNLightingCommand.set_brightness(..., coarse=..., gateway=...)` (`#134`).
- `WHAT 39` end of movement (`*1*39*WHERE##`) from WHO 1 motion detectors: `message_type` `motion_detected` with `motion` `False`, new `OWNLightingEvent.motion_end`, `is_sensor` `True`, `is_on` `None`. It was `unknown_state` `39` before (`MyHOME#777`).

### Fixed
- **WHO 1 (`normalize_where`)**: a 4-digit point address of area 0 (`0004`, `0007#4#01`) normalises to its 2-digit form (`04`, `07#4#01`), the one gateways accept and report: `*#1*0001##` / `*1*1*0001##` are `nack`/`silent` on 11 of 12 emulated gateways (own-firmware-oracle `lights-area0`) and on a live F461 2.0.11, and the MH202 reports the light as `01`. Other 4-digit inputs (`0109`, `0010`) stay as typed (`#123`, `MyHOME#147`).

## [2.0.0b11] - 2026-10-20

### Added
Expand Down
15 changes: 14 additions & 1 deletion OWNd/message/lighting.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,20 @@ def normalize_where(where: str | int | None) -> str:
return ""
parts = where_str.split("#", 1)
base = parts[0]
if is_apl_address(base) or base in ("00", "100", "0"):
if (
len(base) == 4
and base.isdigit()
and base[:3] == "000"
and base[3] != "0"
):
# Area 0, PL 1..9 spelled with four digits (0004) is canonically
# 04: `*#1*0001##` and `*1*1*0001##` are nack/silent on 11 of the 12
# emulated gateways (own-firmware-oracle lights-area0) and the one
# that ACKs them, the MH202, reports the light as `01`
# (`*1*1000#1*01##`); a live F461 2.0.11 NACKs `0001` and ACKs `01`.
# Any other 4-digit input (0109, 0209) is left as typed (OWNd#123).
norm_base = f"{base[1]}{base[3]}"
elif is_apl_address(base) or base in ("00", "100", "0"):
norm_base = base
elif base.isdigit() and base.startswith("00") and int(base) > 15:
norm_base = str(int(base))
Expand Down
36 changes: 36 additions & 0 deletions tests/test_who1_ts10_builders.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,42 @@ def test_apl_addressing_helpers():
assert normalize_where(" ") == ""


@pytest.mark.parametrize(
("where", "expected"),
[
# Area 0, PL 1..9 written on 4 digits: `*#1*0001##` is nack/silent on
# 11 of the 12 emulated gateways (own-firmware-oracle lights-area0),
# and the MH202, which ACKs it, reports the light as `01`.
("0004", "04"),
("0001", "01"),
("0007#4#01", "07#4#01"),
# Any other 4-digit input is left as typed (OWNd#123).
("0109", "0109"),
("0209", "0209"),
("0809", "0809"),
("0901", "0901"),
# Real 4-digit addresses stay as written (the MH202 echoes 0010 as 0010).
("0010", "0010"),
("0015", "0015"),
("0112", "0112"),
("1015", "1015"),
("1001", "1001"),
# Not point addresses, or already canonical.
("0000", "0000"),
("0900", "0900"),
("04", "04"),
("29", "29"),
("00", "00"),
("0", "0"),
("#0004", "#0004"),
],
)
def test_normalize_where_canonicalises_area_0_four_digit_points(where, expected):
from OWNd.message import normalize_where

assert normalize_where(where) == expected


def test_lighting_dimension_properties():
from OWNd.message import OWNLightingEvent, OWNMessage

Expand Down
Loading