diff --git a/src/elgato/elgato.py b/src/elgato/elgato.py index 34105da0..76bb8ba5 100644 --- a/src/elgato/elgato.py +++ b/src/elgato/elgato.py @@ -13,7 +13,7 @@ from yarl import URL from .exceptions import ElgatoConnectionError, ElgatoError, ElgatoNoBatteryError -from .models import BatteryInfo, BatterySettings, Info, Settings, State +from .models import BatteryInfo, BatterySettings, Info, PowerOnBehavior, Settings, State if TYPE_CHECKING: from collections.abc import Callable, Coroutine @@ -357,6 +357,43 @@ class LightState(TypedDict, total=False): data={"numberOfLights": 1, "lights": [state]}, ) + async def power_on_behavior( + self, + *, + behavior: PowerOnBehavior | None = None, + brightness: int | None = None, + hue: float | None = None, + temperature: int | None = None, + ) -> None: + """Change the power on behavior of the Elgato Light device. + + Args: + ---- + behavior: The power on behavior to set. + brightness: The power on brightness of the light, between 0 and 255. + hue: The power on hue range as a float from 0 to 360 degrees. + temperature: The power on color temperature of the light, in mired. + """ + current_settings = await self.settings() + if behavior is not None: + current_settings.power_on_behavior = behavior + if brightness is not None: + current_settings.power_on_brightness = brightness + if hue is not None: + current_settings.power_on_hue = hue + if temperature is not None: + current_settings.power_on_temperature = temperature + + # Unset battery if present, needs special handling + if current_settings.battery: + current_settings.battery = None + + await self._request( + "/elgato/lights/settings", + method=METH_PUT, + data=current_settings.dict(by_alias=True, exclude_none=True), + ) + async def close(self) -> None: """Close open client session.""" if self.session and self._close_session: diff --git a/tests/test_settings.py b/tests/test_settings.py index 6ef82df7..8bd98390 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -4,7 +4,7 @@ from aiohttp import ClientResponse, ClientSession from aresponses import Response, ResponsesMockServer -from elgato import Elgato, ElgatoNoBatteryError, Settings +from elgato import Elgato, ElgatoNoBatteryError, PowerOnBehavior, Settings from . import load_fixture @@ -261,3 +261,95 @@ async def response_handler(request: ClientResponse) -> Response: async with ClientSession() as session: elgato = Elgato("example.com", session=session) await elgato.energy_saving() + + +async def test_power_on_behavior_full(aresponses: ResponsesMockServer) -> None: + """Test changing power on behavior settings.""" + aresponses.add( + "example.com:9123", + "/elgato/lights/settings", + "GET", + aresponses.Response( + status=200, + headers={"Content-Type": "application/json"}, + text=load_fixture("settings-keylight.json"), + ), + repeat=1, + ) + + async def response_handler(request: ClientResponse) -> Response: + """Response handler for this test.""" + data = await request.json() + assert data == { + "colorChangeDurationMs": 100, + "powerOnBehavior": 2, + "powerOnBrightness": 42, + "powerOnHue": 21.0, + "powerOnTemperature": 242, + "switchOffDurationMs": 300, + "switchOnDurationMs": 100, + } + return aresponses.Response( + status=200, + headers={"Content-Type": "application/json"}, + text="{}", + ) + + aresponses.add( + "example.com:9123", + "/elgato/lights/settings", + "PUT", + response_handler, + ) + + async with ClientSession() as session: + elgato = Elgato("example.com", session=session) + await elgato.power_on_behavior( + behavior=PowerOnBehavior.USE_DEFAULTS, + brightness=42, + hue=21.0, + temperature=242, + ) + + +async def test_power_on_behavior_no_changes(aresponses: ResponsesMockServer) -> None: + """Test changing power on behavior settings.""" + aresponses.add( + "example.com:9123", + "/elgato/lights/settings", + "GET", + aresponses.Response( + status=200, + headers={"Content-Type": "application/json"}, + text=load_fixture("settings-key-light-mini.json"), + ), + repeat=2, + ) + + async def response_handler(request: ClientResponse) -> Response: + """Response handler for this test.""" + data = await request.json() + assert data == { + "colorChangeDurationMs": 100, + "powerOnBehavior": 1, + "powerOnBrightness": 20, + "powerOnTemperature": 230, + "switchOffDurationMs": 300, + "switchOnDurationMs": 100, + } + return aresponses.Response( + status=200, + headers={"Content-Type": "application/json"}, + text="{}", + ) + + aresponses.add( + "example.com:9123", + "/elgato/lights/settings", + "PUT", + response_handler, + ) + + async with ClientSession() as session: + elgato = Elgato("example.com", session=session) + await elgato.power_on_behavior()