From cc9e421c49df4fe695c447089e1e235e6ddee50c Mon Sep 17 00:00:00 2001 From: Nicolas Hilberg Date: Sat, 20 Dec 2025 10:42:39 +0100 Subject: [PATCH] WIP Add DeviceOnBehaviorEnum and support for device on behavior configuration --- src/dirigera/devices/device.py | 5 ++++ src/dirigera/devices/light.py | 42 +++++++++++++++++++++++++++++++++- tests/test_light.py | 34 +++++++++++++++++++++++++-- 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/src/dirigera/devices/device.py b/src/dirigera/devices/device.py index df7b0f0..36b3b8e 100644 --- a/src/dirigera/devices/device.py +++ b/src/dirigera/devices/device.py @@ -12,6 +12,11 @@ class StartupEnum(Enum): START_TOGGLE = "startToggle" +class DeviceOnBehaviorEnum(Enum): + LAST_VALUE = "lastValue" + ADAPTIVE_PROFILE = "adaptiveProfile" + + class Attributes(BaseIkeaModel): custom_name: str model: str diff --git a/src/dirigera/devices/light.py b/src/dirigera/devices/light.py index 9e01302..6eecf2d 100644 --- a/src/dirigera/devices/light.py +++ b/src/dirigera/devices/light.py @@ -1,6 +1,8 @@ from __future__ import annotations from typing import Any, Optional, Dict -from .device import Attributes, Device, StartupEnum + +from .base_ikea_model import BaseIkeaModel +from .device import Attributes, Device, StartupEnum, DeviceOnBehaviorEnum from ..hub.abstract_smart_home_hub import AbstractSmartHomeHub @@ -13,6 +15,12 @@ class LightAttributes(Attributes): color_temperature_max: Optional[int] = None color_hue: Optional[float] = None color_saturation: Optional[float] = None + device_on_behavior: Optional[DeviceOnBehavior] = None + + +class DeviceOnBehavior(BaseIkeaModel): + behavior: Optional[DeviceOnBehaviorEnum] = None + profile_id: Optional[str] = None class Light(Device): @@ -104,6 +112,38 @@ def set_startup_behaviour(self, behaviour: StartupEnum) -> None: self.dirigera_client.patch(route=f"/devices/{self.id}", data=data) self.attributes.startup_on_off = behaviour + def set_device_on_behavior(self, device_on_behavior: DeviceOnBehavior) -> None: + """Configure the behavior of the device when it is turned on. + + This method allows you to specify how the device should behave upon being powered on. + The behavior can be set to either use the adaptive profile or retain the last known state. + + Args: + device_on_behavior (DeviceOnBehavior): An instance of `DeviceOnBehavior` that defines + the desired behavior. It can be one of the following: + - `DeviceOnBehavior.ADAPTIVE_PROFILE`: The device will use the adaptive profile. + - `DeviceOnBehavior.LAST_VALUE`: The device will retain its last known state. + + Raises: + HTTPError: If the request to update the device configuration fails. + + Side Effects: + Updates the device's `device_on_behavior` attribute to reflect the new configuration. + """ + data = [ + { + "attributes": { + "deviceOnBehavior": { + "behavior": device_on_behavior.behavior.value, + "profileId": device_on_behavior.profile_id, + } + } + } + ] + self.dirigera_client.patch(route=f"/devices/{self.id}", data=data) + + self.attributes.device_on_behavior = device_on_behavior + def dict_to_light(data: Dict[str, Any], dirigera_client: AbstractSmartHomeHub) -> Light: return Light( diff --git a/tests/test_light.py b/tests/test_light.py index 6040f97..07b0b1f 100644 --- a/tests/test_light.py +++ b/tests/test_light.py @@ -3,8 +3,8 @@ import pytest from src.dirigera.hub.abstract_smart_home_hub import FakeDirigeraHub from src.dirigera.devices.light import dict_to_light -from src.dirigera.devices.light import Light -from src.dirigera.devices.device import StartupEnum +from src.dirigera.devices.light import Light, DeviceOnBehavior +from src.dirigera.devices.device import StartupEnum, DeviceOnBehaviorEnum @pytest.fixture(name="fake_client") @@ -328,3 +328,33 @@ def test_dict_to_light_3rdparty(fake_client: FakeDirigeraHub) -> None: assert light.attributes.model == data["attributes"]["model"] assert light.attributes.manufacturer == data["attributes"]["manufacturer"] assert light.attributes.serial_number == data["attributes"]["serialNumber"] + + +def test_set_device_on_behavior_adaptive_profile( + fake_light: Light, fake_client: FakeDirigeraHub +) -> None: + behavior = DeviceOnBehavior( + behaviour=DeviceOnBehaviorEnum.ADAPTIVE_PROFILE, profile_id="adaptive_123" + ) + fake_light.set_device_on_behavior(behavior) + action = fake_client.patch_actions.pop() + assert action["route"] == f"/devices/{fake_light.id}" + assert action["data"] == [ + {"attributes": {"deviceOnBehavior": behavior.behaviour.value}} + ] + assert fake_light.attributes.device_on_behavior == behavior + + +def test_set_device_on_behavior_last_value( + fake_light: Light, fake_client: FakeDirigeraHub +) -> None: + behavior = DeviceOnBehavior( + behaviour=DeviceOnBehaviorEnum.LAST_VALUE, profile_id="last_value_456" + ) + fake_light.set_device_on_behavior(behavior) + action = fake_client.patch_actions.pop() + assert action["route"] == f"/devices/{fake_light.id}" + assert action["data"] == [ + {"attributes": {"deviceOnBehavior": behavior.behaviour.value}} + ] + assert fake_light.attributes.device_on_behavior == behavior