From 1921db17e7704b8c60a5b98014d5201a4a19e9b0 Mon Sep 17 00:00:00 2001 From: Alex X Date: Fri, 5 Apr 2024 08:19:32 +0300 Subject: [PATCH] Add buttons support --- custom_components/yandex_station/__init__.py | 2 +- custom_components/yandex_station/button.py | 26 +++++++ .../yandex_station/core/yandex_quasar.py | 13 +++- .../yandex_station/hass/hass_utils.py | 3 +- custom_components/yandex_station/remote.py | 78 ------------------- 5 files changed, 38 insertions(+), 84 deletions(-) create mode 100644 custom_components/yandex_station/button.py delete mode 100644 custom_components/yandex_station/remote.py diff --git a/custom_components/yandex_station/__init__.py b/custom_components/yandex_station/__init__.py index 64071ad..c471d7e 100644 --- a/custom_components/yandex_station/__init__.py +++ b/custom_components/yandex_station/__init__.py @@ -48,12 +48,12 @@ _LOGGER = logging.getLogger(__name__) PLATFORMS = [ + "button", "climate", "light", "humidifier", "media_player", "number", - "remote", "select", "switch", "vacuum", diff --git a/custom_components/yandex_station/button.py b/custom_components/yandex_station/button.py new file mode 100644 index 0000000..d39b46d --- /dev/null +++ b/custom_components/yandex_station/button.py @@ -0,0 +1,26 @@ +from homeassistant.components.button import ButtonEntity + +from .core.entity import YandexCustomEntity +from .hass import hass_utils + +INCLUDE_CAPABILITIES = ("devices.capabilities.custom.button",) + + +async def async_setup_entry(hass, entry, async_add_entities): + entities = [] + + for quasar, device, config in hass_utils.incluce_devices(hass, entry): + if instances := config.get("capabilities"): + for instance in device["capabilities"]: + if instance["type"] not in INCLUDE_CAPABILITIES: + continue + if instance["parameters"].get("instance", "on") in instances: + entities.append(YandexCustomButton(quasar, device, instance)) + + async_add_entities(entities) + + +# noinspection PyAbstractClass +class YandexCustomButton(ButtonEntity, YandexCustomEntity): + async def async_press(self) -> None: + await self.quasar.device_action(self.device["id"], self.instance, True) diff --git a/custom_components/yandex_station/core/yandex_quasar.py b/custom_components/yandex_station/core/yandex_quasar.py index 04d38ef..3741300 100644 --- a/custom_components/yandex_station/core/yandex_quasar.py +++ b/custom_components/yandex_station/core/yandex_quasar.py @@ -419,10 +419,15 @@ async def get_device(self, deviceid: str): return resp async def device_action(self, deviceid: str, instance: str, value): - action = { - "type": IOT_TYPES[instance], - "state": {"instance": instance, "value": value}, - } + action = {"state": {"instance": instance, "value": value}} + + if instance in IOT_TYPES: + action["type"] = IOT_TYPES[instance] + elif instance.isdecimal(): + action["type"] = "devices.capabilities.custom.button" + else: + return + r = await self.session.post( f"{URL_USER}/devices/{deviceid}/actions", json={"actions": [action]} ) diff --git a/custom_components/yandex_station/hass/hass_utils.py b/custom_components/yandex_station/hass/hass_utils.py index aade56b..2aa03d8 100644 --- a/custom_components/yandex_station/hass/hass_utils.py +++ b/custom_components/yandex_station/hass/hass_utils.py @@ -25,6 +25,7 @@ "devices.types.iron", "devices.types.openable", "devices.types.openable.curtain", + "devices.types.other", "devices.types.pet_drinking_fountain", "devices.types.pet_feeder", "devices.types.washing_machine", @@ -61,7 +62,7 @@ def incluce_devices( for conf in includes: for device in quasar.devices: if isinstance(conf, str): - if conf == device["name"] or conf == device["id"]: + if conf == device["id"] or conf == device["name"]: conf = build_include_config(device) devices.append((quasar, device, conf)) break diff --git a/custom_components/yandex_station/remote.py b/custom_components/yandex_station/remote.py deleted file mode 100644 index a473370..0000000 --- a/custom_components/yandex_station/remote.py +++ /dev/null @@ -1,78 +0,0 @@ -import asyncio -import logging -from typing import Any, Iterable - -from homeassistant.components.remote import ( - ATTR_DELAY_SECS, - ATTR_NUM_REPEATS, - RemoteEntity, -) - -from .core.yandex_quasar import YandexQuasar -from .hass import hass_utils - -_LOGGER = logging.getLogger(__name__) - -INCLUDE_TYPES = ("devices.types.other",) - - -async def async_setup_entry(hass, entry, async_add_entities): - async_add_entities( - YandexOther(quasar, device) - for quasar, device, _ in hass_utils.incluce_devices(hass, entry) - if device["type"] in INCLUDE_TYPES - ) - - -# noinspection PyAbstractClass -class YandexOther(RemoteEntity): - _name = None - - def __init__(self, quasar: YandexQuasar, device: dict): - self.quasar = quasar - self.device = device - - self.buttons = {} - - async def async_added_to_hass(self): - self._name = self.device["name"] - - data = await self.quasar.get_device(self.device["id"]) - for capability in data["capabilities"]: - if capability["type"] != "devices.capabilities.custom.button": - continue - name = capability["parameters"]["name"] - self.buttons[name] = capability["parameters"]["instance"] - - @property - def unique_id(self): - return self.device["id"].replace("-", "") - - @property - def name(self): - return self._name - - @property - def should_poll(self) -> bool: - return False - - @property - def is_on(self) -> bool: - return True - - async def async_send_command(self, command: Iterable[str], **kwargs: Any) -> None: - if num_repeats := kwargs.get(ATTR_NUM_REPEATS): - command *= num_repeats - - delay = kwargs.get(ATTR_DELAY_SECS, 0) - - for i, cmd in enumerate(command): - if cmd not in self.buttons: - _LOGGER.error(f"Неизвестная команда {cmd}") - continue - - if delay and i: - await asyncio.sleep(delay) - - payload = {self.buttons[cmd]: True} - await self.quasar.device_actions(self.device["id"], **payload)