This commit is contained in:
Victor Alexandrovich Tsyrenschikov
2026-03-30 20:25:42 +05:00
parent 139f9f1bd2
commit 373ed28445
2449 changed files with 53602 additions and 0 deletions

View File

@@ -0,0 +1,167 @@
from homeassistant.components.light import ColorMode, LightEntity, LightEntityFeature
from .core.entity import YandexEntity
from .hass import hass_utils
INCLUDE_TYPES = (
"devices.types.light",
"devices.types.light.ceiling",
"devices.types.light.dimmable",
"devices.types.light.garland",
"devices.types.light.lamp",
"devices.types.light.strip",
"devices.types.smart_speaker.yandex.station.orion",
)
async def async_setup_entry(hass, entry, async_add_entities):
async_add_entities(
YandexLight(quasar, device, config)
for quasar, device, config in hass_utils.incluce_devices(hass, entry)
if device["type"] in INCLUDE_TYPES
)
def conv(value: int, src_min: int, src_max: int, dst_min: int, dst_max: int) -> int:
value = round(
(value - src_min) / (src_max - src_min) * (dst_max - dst_min) + dst_min
)
if value < dst_min:
value = dst_min
if value > dst_max:
value = dst_max
return value
# noinspection PyAbstractClass
class YandexLight(LightEntity, YandexEntity):
max_brightness: int
min_brightness: int
effects: list
on_instance: str
def internal_init(self, capabilities: dict, properties: dict):
self._attr_color_mode = ColorMode.ONOFF
# backlight for Yandex Station 3 and maybe some others
for instance in ("on", "backlight"):
if instance in capabilities:
self.on_instance = instance
break
if bright := capabilities.get("brightness"):
self.max_brightness = bright["range"]["max"]
self.min_brightness = bright["range"]["min"]
self._attr_color_mode = ColorMode.BRIGHTNESS
modes = set()
if color := capabilities.get("color"):
self.effects = []
if palette := color.get("palette"):
self.effects.extend(palette)
modes.add(ColorMode.HS)
if scenes := color.get("scenes"):
self.effects.extend(scenes)
if temp := color.get("temperature_k"):
self._attr_max_color_temp_kelvin = temp["max"]
self._attr_min_color_temp_kelvin = temp["min"]
modes.add(ColorMode.COLOR_TEMP)
if self.effects:
self._attr_effect_list = [i["name"] for i in self.effects]
self._attr_supported_features = LightEntityFeature.EFFECT
self._attr_supported_color_modes = modes or {self._attr_color_mode}
def internal_update(self, capabilities: dict, properties: dict):
if self.on_instance in capabilities:
self._attr_is_on = capabilities[self.on_instance]
if "brightness" in capabilities:
value = capabilities["brightness"]
self._attr_brightness = (
conv(value, self.min_brightness, self.max_brightness, 1, 255)
if value
else None
)
if animation := capabilities.get("color_animation"):
animation_type = animation["current_animation_type"]
if animation_type == "color":
color = animation["animations"]["color"]
state = color["internal_state"]
if state["instance"] == "hsv":
value = state["value"]
self._attr_hs_color = (value["h"], value["s"])
self._attr_color_mode = ColorMode.HS
elif animation_type == "scene":
scene = animation["animations"]["scene"]
id = scene["variant"]
self._attr_effect = next(
i["name"] for i in self.effects if i["id"] == id
)
elif color := capabilities.get("color"):
value = color.get("value")
if isinstance(value, dict):
self._attr_hs_color = (value["h"], value["s"])
self._attr_color_mode = ColorMode.HS
elif isinstance(value, int):
# fix https://github.com/AlexxIT/YandexStation/issues/465
# self._attr_hs_color = color_temperature_to_hs(value)
self._attr_color_temp_kelvin = value
self._attr_color_mode = ColorMode.COLOR_TEMP
else:
self._attr_color_temp_kelvin = None
self._attr_hs_color = None
if name := color.get("name"):
self._attr_effect = name
elif id := color.get("id"):
self._attr_effect = next(
i["name"] for i in self.effects if i["id"] == id
)
else:
self._attr_effect = None
async def async_turn_on(
self,
brightness: int = None,
effect: str = None,
color_temp_kelvin: int = None,
hs_color: tuple = None,
**kwargs,
):
if color_temp_kelvin:
await self.device_color(temperature_k=color_temp_kelvin)
return
if hs_color:
hsv = {"h": round(hs_color[0]), "s": round(hs_color[1]), "v": 100}
await self.device_color(hsv=hsv)
return
payload = {}
if brightness is not None:
payload["brightness"] = conv(
brightness, 1, 255, self.min_brightness, self.max_brightness
)
if effect is not None:
color: dict = next(i for i in self.effects if i["name"] == effect)
key = "color" if "value" in color else "scene"
payload[key] = color["id"]
if not payload:
payload[self.on_instance] = True
await self.device_actions(**payload)
async def async_turn_off(self, **kwargs):
await self.device_action(self.on_instance, False)