Skip to content

Commit

Permalink
Add support for controlling power on behavior (#699)
Browse files Browse the repository at this point in the history
  • Loading branch information
frenck authored Feb 5, 2023
1 parent 6e320ae commit 0a5bc58
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 2 deletions.
39 changes: 38 additions & 1 deletion src/elgato/elgato.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down
94 changes: 93 additions & 1 deletion tests/test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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()

0 comments on commit 0a5bc58

Please sign in to comment.