1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
"""Controller holding and managing HUE resources of type `light`."""
from aiohue.v2.models.feature import (
AlertEffectType,
AlertFeaturePut,
ColorFeaturePut,
ColorPoint,
ColorTemperatureFeaturePut,
DeltaAction,
DimmingFeaturePut,
DimmingDeltaFeaturePut,
DynamicsFeaturePut,
EffectsFeaturePut,
EffectStatus,
EffectsV2ActionPut,
EffectsV2FeaturePut,
EffectsV2ParametersPut,
OnFeature,
TimedEffectsFeaturePut,
TimedEffectStatus,
)
from aiohue.v2.models.light import Light, LightPut
from aiohue.v2.models.resource import ResourceTypes
from .base import BaseResourcesController
class LightsController(BaseResourcesController[type[Light]]):
"""Controller holding and managing HUE resources of type `light`."""
item_type = ResourceTypes.LIGHT
item_cls = Light
async def turn_on(self, id: str, transition_time: int | None = None) -> None:
"""Turn on the light."""
await self.set_state(id, on=True, transition_time=transition_time)
async def turn_off(self, id: str, transition_time: int | None = None) -> None:
"""Turn off the light."""
await self.set_state(id, on=False, transition_time=transition_time)
async def set_brightness(
self, id: str, brightness: float, transition_time: int | None = None
) -> None:
"""Set brightness to light. Turn on light if it's currently off."""
await self.set_state(
id, on=True, brightness=brightness, transition_time=transition_time
)
async def set_color(
self, id: str, x: float, y: float, transition_time: int | None = None
) -> None:
"""Set color to light. Turn on light if it's currently off."""
await self.set_state(
id, on=True, color_xy=(x, y), transition_time=transition_time
)
async def set_color_temperature(
self, id: str, mirek: int, transition_time: int | None = None
) -> None:
"""Set Color Temperature to light. Turn on light if it's currently off."""
await self.set_state(
id, on=True, color_temp=mirek, transition_time=transition_time
)
async def set_flash(self, id: str, short: bool = False) -> None:
"""Send Flash command to light."""
if short:
device = self.get_device(id)
await self._bridge.devices.set_identify(device.id)
else:
await self.set_state(id, alert=AlertEffectType.BREATHE)
async def set_state(
self,
id: str,
on: bool | None = None,
brightness: float | None = None,
color_xy: tuple[float, float] | None = None,
color_temp: int | None = None,
transition_time: int | None = None,
alert: AlertEffectType | None = None,
effect: EffectStatus | TimedEffectStatus | None = None,
effect_speed: float | None = None,
) -> None:
"""Set supported feature(s) to light resource."""
update_obj = LightPut()
if on is not None:
update_obj.on = OnFeature(on=on)
if brightness is not None:
update_obj.dimming = DimmingFeaturePut(brightness=brightness)
if color_xy is not None:
update_obj.color = ColorFeaturePut(xy=ColorPoint(*color_xy))
if color_temp is not None:
update_obj.color_temperature = ColorTemperatureFeaturePut(mirek=color_temp)
if transition_time is not None and effect in (None, EffectStatus.NO_EFFECT):
update_obj.dynamics = DynamicsFeaturePut(duration=transition_time)
if alert is not None:
update_obj.alert = AlertFeaturePut(action=alert)
# for timed_effects feature, transition time is used for duration
if effect is not None and isinstance(effect, TimedEffectStatus):
update_obj.timed_effects = TimedEffectsFeaturePut(
effect=effect, duration=transition_time
)
elif effect is not None and (
effect_speed is not None or color_xy is not None or color_temp is not None
):
# if color is set together with effect it is ignored unless we use effects_v2.
update_obj.effects_v2 = EffectsV2FeaturePut(
action=EffectsV2ActionPut(
effect=effect, parameters=EffectsV2ParametersPut()
)
)
if color_xy is not None:
update_obj.effects_v2.action.parameters.color = ColorFeaturePut(
xy=ColorPoint(*color_xy)
)
if color_temp is not None:
update_obj.effects_v2.action.parameters.color_temperature = (
ColorTemperatureFeaturePut(mirek=color_temp)
)
if effect_speed is not None:
update_obj.effects_v2.action.parameters.speed = effect_speed
elif effect is not None:
# fallback to old effects feature for backwards compatibility
update_obj.effects = EffectsFeaturePut(effect=effect)
await self.update(id, update_obj)
async def set_dimming_delta(
self, id: str, brightness_delta: float | None = None
) -> None:
"""
Set brightness_delta value and action via DimmingDeltaFeature.
The action to be send depends on brightness_delta value:
None: STOP (this immediately stops any dimming transition)
> 0: UP,
< 0: DOWN
"""
if brightness_delta in (None, 0):
dimming_delta = DimmingDeltaFeaturePut(action=DeltaAction.STOP)
else:
dimming_delta = DimmingDeltaFeaturePut(
action=DeltaAction.UP if brightness_delta > 0 else DeltaAction.DOWN,
brightness_delta=abs(brightness_delta),
)
update_obj = LightPut()
update_obj.dimming_delta = dimming_delta
await self.update(id, update_obj)
|