Skip to content

Commit 9e55549

Browse files
authored
Allow dict/list parameters in Command (#2089) (#2091)
## Summary Fixes #2089. `Command.parameters` could not be typed with `dict` elements, even though the Overkiz API accepts (and some commands require) a dict parameter. This forced consumers to `cast()` around the type, defeating the type checker for the exact case where it matters. Examples of dict-valued command parameters: - `setAbsenceStartDate` / `setAbsenceEndDate` — take a date dict (`{"year": ..., "month": ..., ...}`) - `setCurrentOperatingMode` — takes `{"relaunch": "off", "absence": "on"}` ## Changes - **Widen `CommandParameterValue`** in `pyoverkiz/types.py` to include `dict[str, Any]` and `list[Any]`, consistent with how `StateType` is already defined. - **Fix `Command.to_payload`** in `pyoverkiz/models.py`. The serializer previously stringified anything that wasn't a `str`/`int`/`float`/`bool` (to handle `OverkizCommandParam` enums), so a dict parameter would have been sent as a Python `repr` string instead of a JSON object. Dicts and lists now pass through untouched. - **Add a test** asserting a dict parameter survives `to_payload` round-trip. ## Notes The issue's code snippet referenced a stale `class Command(dict)` shape; the type now lives in `CommandParameterValue` (`types.py`), which is where this patch widens it. Once released and the requirement is bumped, the `cast()` workaround in the Home Assistant `overkiz` integration (water heater absence-date commands) can be removed. ## Test plan - [x] `pytest tests/` — 457 passed - [x] `mypy` clean on changed files - [x] `ruff check` clean
1 parent 4cc0635 commit 9e55549

3 files changed

Lines changed: 41 additions & 2 deletions

File tree

pyoverkiz/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ def to_payload(self) -> dict[str, object]:
358358

359359
if self.parameters is not None:
360360
payload["parameters"] = [
361-
p if isinstance(p, (str, int, float, bool)) else str(p)
361+
p if isinstance(p, (str, int, float, bool, dict, list)) else str(p)
362362
for p in self.parameters
363363
]
364364

pyoverkiz/types.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111

1212
StateType = str | int | float | bool | dict[str, Any] | list[Any] | None
1313

14-
CommandParameterValue = str | int | float | bool | OverkizCommandParam
14+
CommandParameterValue = (
15+
str | int | float | bool | dict[str, Any] | list[Any] | OverkizCommandParam
16+
)
1517

1618

1719
def _parse_bool(value: str) -> bool:

tests/test_models.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,43 @@ def test_command_to_payload_omits_none():
927927
assert payload == {"name": "close"}
928928

929929

930+
def test_command_to_payload_preserves_dict_parameter():
931+
"""Command.to_payload passes dict/list parameters through untouched.
932+
933+
Several Atlantic/Thermor commands (e.g. setAbsenceStartDate,
934+
setCurrentOperatingMode) take a dict parameter that must reach the API as a
935+
JSON object, not a stringified repr.
936+
"""
937+
from pyoverkiz.models import Command
938+
939+
date = {
940+
"year": 2026,
941+
"month": 5,
942+
"day": 28,
943+
"hour": 12,
944+
"minute": 0,
945+
"second": 0,
946+
"weekday": 3,
947+
}
948+
cmd = Command(name="setAbsenceStartDate", parameters=[date])
949+
950+
payload = cmd.to_payload()
951+
952+
assert payload["parameters"] == [date]
953+
954+
955+
def test_command_to_payload_preserves_list_parameter():
956+
"""Command.to_payload passes a nested list parameter through untouched."""
957+
from pyoverkiz.models import Command
958+
959+
schedule = [[0, 1, 2], [3, 4, 5]]
960+
cmd = Command(name="setSchedule", parameters=[schedule])
961+
962+
payload = cmd.to_payload()
963+
964+
assert payload["parameters"] == [schedule]
965+
966+
930967
def test_action_to_payload_and_parameters_conversion():
931968
"""Action.to_payload converts nested Command enums to primitives."""
932969
from pyoverkiz.enums.command import OverkizCommand, OverkizCommandParam

0 commit comments

Comments
 (0)