Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add combine commands to light control #512

Merged
merged 2 commits into from
Jun 24, 2022
Merged
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: 2 additions & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ exclude_lines =
# Don't complain if tests don't hit defensive assertion code:
raise AssertionError
raise NotImplementedError
if TYPE_CHECKING:
omit =
pytradfri/__main__.py
pytradfri/__main__.py
26 changes: 24 additions & 2 deletions pytradfri/device/light_control.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
"""Class to control the lights."""
from __future__ import annotations

from collections.abc import Mapping
from typing import TYPE_CHECKING
from collections.abc import Sequence
from copy import deepcopy
from typing import TYPE_CHECKING, List, Mapping, Union, cast

from ..color import COLORS
from ..command import Command
Expand Down Expand Up @@ -187,3 +188,24 @@ def set_values(
assert len(self.raw) == 1, "Only devices with 1 light supported"

return Command("put", self._device.path, {ATTR_LIGHT_CONTROL: [values]})

def combine_commands(self, commands: Sequence[Command[None]]) -> Command[None]:
"""Combine a sequence of light control commands."""
combined_data: dict[str, str | int] = {}

for command in commands:
data = command.data
if data is None or ATTR_LIGHT_CONTROL not in data:
raise TypeError(f"Invalid command data: {data}")

light_control_data = cast(
List[Mapping[str, Union[str, int]]], data[ATTR_LIGHT_CONTROL]
)
for control_data in light_control_data:
combined_data.update(control_data)

new_command = deepcopy(commands[0])
assert new_command.data is not None # Ensured by raising an error above.
new_command.data[ATTR_LIGHT_CONTROL] = [combined_data]

return new_command
36 changes: 36 additions & 0 deletions tests/test_light.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,39 @@ def test_setters():

with pytest.raises(error.ColorError):
Device(LIGHT_CWS).light_control.set_predefined_color("Ggravlingen")


def test_combine_command():
"""Test light control combine command."""
device = Device(LIGHT_CWS)

assert device.light_control is not None

dimmer_cmd = device.light_control.set_dimmer(100)

assert dimmer_cmd.data == {"3311": [{"5851": 100}]}

hsb_xy_color_cmd = device.light_control.set_hsb(
hue=100, saturation=75, brightness=50, transition_time=60
)

assert hsb_xy_color_cmd.data == {
"3311": [{"5707": 100, "5708": 75, "5712": 60, "5851": 50}]
}

combined_cmd = device.light_control.combine_commands([dimmer_cmd, hsb_xy_color_cmd])

assert combined_cmd.data == {
"3311": [{"5707": 100, "5708": 75, "5712": 60, "5851": 50}]
}

combined_cmd = device.light_control.combine_commands([combined_cmd, dimmer_cmd])

assert combined_cmd.data == {
"3311": [{"5707": 100, "5708": 75, "5712": 60, "5851": 100}]
}

combined_cmd.data.clear()

with pytest.raises(TypeError):
device.light_control.combine_commands([dimmer_cmd, combined_cmd])