Update cli modify presets to support smart devices (#1295)

This commit is contained in:
Steven B. 2024-11-21 18:10:18 +00:00 committed by GitHub
parent dab64e5d48
commit 879aca77d1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 78 additions and 18 deletions

View File

@ -127,13 +127,15 @@ async def presets(ctx, dev):
def presets_list(dev: Device): def presets_list(dev: Device):
"""List presets.""" """List presets."""
if not (light_preset := dev.modules.get(Module.LightPreset)): if not (light_preset := dev.modules.get(Module.LightPreset)):
error("Presets not supported on device") error("Device does not support light presets")
return return
for idx, preset in enumerate(light_preset.preset_states_list): for idx, preset in enumerate(light_preset.preset_states_list):
echo( echo(
f"[{idx}] Hue: {preset.hue:3} Saturation: {preset.saturation:3} " f"[{idx}] Hue: {preset.hue or '':3} "
f"Brightness/Value: {preset.brightness:3} Temp: {preset.color_temp:4}" f"Saturation: {preset.saturation or '':3} "
f"Brightness/Value: {preset.brightness or '':3} "
f"Temp: {preset.color_temp or '':4}"
) )
return light_preset.preset_states_list return light_preset.preset_states_list
@ -141,32 +143,44 @@ def presets_list(dev: Device):
@presets.command(name="modify") @presets.command(name="modify")
@click.argument("index", type=int) @click.argument("index", type=int)
@click.option("--brightness", type=int) @click.option("--brightness", type=int, required=False, default=None)
@click.option("--hue", type=int) @click.option("--hue", type=int, required=False, default=None)
@click.option("--saturation", type=int) @click.option("--saturation", type=int, required=False, default=None)
@click.option("--temperature", type=int) @click.option("--temperature", type=int, required=False, default=None)
@pass_dev_or_child @pass_dev_or_child
async def presets_modify(dev: Device, index, brightness, hue, saturation, temperature): async def presets_modify(dev: Device, index, brightness, hue, saturation, temperature):
"""Modify a preset.""" """Modify a preset."""
for preset in dev.presets: if not (light_preset := dev.modules.get(Module.LightPreset)):
if preset.index == index: error("Device does not support light presets")
break
else:
error(f"No preset found for index {index}")
return return
if brightness is not None: max_index = len(light_preset.preset_states_list) - 1
if index > len(light_preset.preset_states_list) - 1:
error(f"Invalid index, must be between 0 and {max_index}")
return
if all([val is None for val in {brightness, hue, saturation, temperature}]):
error("Need to supply at least one option to modify.")
return
# Preset names have `Not set`` as the first value
preset_name = light_preset.preset_list[index + 1]
preset = light_preset.preset_states_list[index]
echo(f"Preset {preset_name} currently: {preset}")
if brightness is not None and preset.brightness is not None:
preset.brightness = brightness preset.brightness = brightness
if hue is not None: if hue is not None and preset.hue is not None:
preset.hue = hue preset.hue = hue
if saturation is not None: if saturation is not None and preset.saturation is not None:
preset.saturation = saturation preset.saturation = saturation
if temperature is not None: if temperature is not None and preset.temperature is not None:
preset.color_temp = temperature preset.color_temp = temperature
echo(f"Going to save preset: {preset}") echo(f"Updating preset {preset_name} to: {preset}")
return await dev.save_preset(preset) return await light_preset.save_preset(preset_name, preset)
@light.command() @light.command()

View File

@ -34,6 +34,8 @@ from kasa.cli.light import (
brightness, brightness,
effect, effect,
hsv, hsv,
presets,
presets_modify,
temperature, temperature,
) )
from kasa.cli.main import TYPES, _legacy_type_to_class, cli, cmd_command, raw_command from kasa.cli.main import TYPES, _legacy_type_to_class, cli, cmd_command, raw_command
@ -575,6 +577,50 @@ async def test_light_effect(dev: Device, runner: CliRunner):
assert res.exit_code == 2 assert res.exit_code == 2
async def test_light_preset(dev: Device, runner: CliRunner):
res = await runner.invoke(presets, obj=dev)
if not (light_preset := dev.modules.get(Module.LightPreset)):
assert "Device does not support light presets" in res.output
return
if len(light_preset.preset_states_list) == 0:
pytest.skip(
"Some fixtures do not have presets and"
" the api doesn'tsupport creating them"
)
# Start off with a known state
first_name = light_preset.preset_list[1]
await light_preset.set_preset(first_name)
await dev.update()
assert light_preset.preset == first_name
res = await runner.invoke(presets, obj=dev)
assert "Brightness" in res.output
assert res.exit_code == 0
res = await runner.invoke(
presets_modify,
[
"0",
"--brightness",
"12",
],
obj=dev,
)
await dev.update()
assert light_preset.preset_states_list[0].brightness == 12
res = await runner.invoke(
presets_modify,
[
"0",
],
obj=dev,
)
await dev.update()
assert "Need to supply at least one option to modify." in res.output
async def test_led(dev: Device, runner: CliRunner): async def test_led(dev: Device, runner: CliRunner):
res = await runner.invoke(led, obj=dev) res = await runner.invoke(led, obj=dev)
if not (led_module := dev.modules.get(Module.Led)): if not (led_module := dev.modules.get(Module.Led)):