From 3033d64a712bc2682be6e5e92ff38cb17d50daaa Mon Sep 17 00:00:00 2001 From: Artem Sorokin Date: Thu, 25 Apr 2024 17:00:48 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=20=D0=BE=D0=B3=D1=80=D0=B0=D0=BD=D0=B8=D1=87=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=BE=20=D0=B0=D0=BA=D0=BA=D0=B0?= =?UTF-8?q?=D1=83=D0=BD=D1=82=D1=83=20=D0=B4=D0=BB=D1=8F=20=D0=B8=D0=BD?= =?UTF-8?q?=D1=82=D0=B5=D0=BD=D1=82=D0=B0=20(#29)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++++ .../yandex_station_intents/__init__.py | 17 +++++++++++++---- .../yandex_station_intents/const.py | 1 + .../yandex_station_intents/yandex_intent.py | 8 +++++--- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 48cdf1d..c2c2b70 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,8 @@ yandex_station_intents: execute_command: Прибавь температуру кондиционера на 1 градус в {{ event.room }} Точная температура в комнате: # (7) say_phrase: "Точная температура {{ states('sensor.room_temperature') }} в {{ event.room }}" + Давай поиграем: + accounts: [vasya] # (8) ``` В данном случае интеграция автоматически создаст в УДЯ семь сценариев, каждый из которых начинается с символов `---`. **Не удаляйте эти символы и не модифицируйте никак название!** По ним компонент понимает, что это его сценарий и в случае необходимости синхронизирует/удалит его. @@ -92,12 +94,14 @@ yandex_station_intents: 5. Срабатывает от `Алиса, давай попьем чаю`, генерирует событие с `text: Давай попьем чаю`, колонка, которая нас услышала ответит `Отличная идея, сейчас включу свет на кухне`, после этого колонка выполнит команду `Включи свет на кухне` 6. Срабатывает от `Алиса, очень холодно`, генерирует событие с `text: Очень холодно`, колонка выполнит команду `Прибавь температуру кондиционера на 1 градус в КОМНАТА` (вместо `КОМНАТА` будет подставлена комната, в которой находится колонка) 7. Срабатывает от `Алиса, точная температура в комнате`, генерирует событие с `text: Точная температура в комнате`, колонка, которая нас услышала ответит вычисленным шаблоном из `say_phrase` +8. Сценарий будет создан и работать только на аккаунте `vasya` (можно указать несколько аккаунтов через запятую). Аккаунт указывается в том же виде, как отображается в списке интеграций. Если аккаунты не указаны - сценарии будут созданы для всех активных интеграций. ### Обработка событий После того как колонка услышит ключевую фразу в Home Assistant сгенерируется событие `yandex_intent` с параметрами: * `text`: Основная фраза (смотрите примеры) * `entity_id`: ID колонки, которая услышала фразу активации (только `mode: websocket`) * `room`: Комната, в которой находится колонка (только `mode: websocket`) +* `account`: Аккаунт, к которому привязана колонка Пример обработки: ```yaml diff --git a/custom_components/yandex_station_intents/__init__.py b/custom_components/yandex_station_intents/__init__.py index 911405c..14517c1 100644 --- a/custom_components/yandex_station_intents/__init__.py +++ b/custom_components/yandex_station_intents/__init__.py @@ -17,6 +17,7 @@ from .const import ( CLEAR_CONFIRM_KEY, CLEAR_CONFIRM_TEXT, + CONF_ACCOUNTS, CONF_AUTOSYNC, CONF_INTENT_EXECUTE_COMMAND, CONF_INTENT_EXTRA_PHRASES, @@ -103,6 +104,7 @@ def string_or_template(value: str) -> str | template_helper.Template: ], vol.Optional(CONF_INTENT_SAY_PHRASE): string_or_template, vol.Optional(CONF_INTENT_EXECUTE_COMMAND): cv.template, + vol.Optional(CONF_ACCOUNTS): vol.All(cv.ensure_list, [cv.string]), } ), ), @@ -127,9 +129,16 @@ class Component: yaml_config: ConfigType entry_datas: dict[str, ConfigEntryData] - @property - def intents_config(self) -> ConfigType: - return dict(self.yaml_config.get(CONF_INTENTS, {})) + def get_intents_config(self, entry: ConfigEntry) -> ConfigType: + intents_config: ConfigType = {} + for name, config in self.yaml_config.get(CONF_INTENTS, {}).items(): + if accounts := config.get(CONF_ACCOUNTS): + if entry.unique_id not in accounts: + continue + + intents_config[name] = config + + return intents_config async def async_setup(hass: HomeAssistant, yaml_config: ConfigType) -> bool: @@ -171,7 +180,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: if not await session.async_validate(): await session.async_refresh() - manager = IntentManager(hass, component.intents_config) + manager = IntentManager(hass, entry, component.get_intents_config(entry)) quasar = YandexQuasar(session) await quasar.async_init() except Exception as e: diff --git a/custom_components/yandex_station_intents/const.py b/custom_components/yandex_station_intents/const.py index 2fd057a..9b69e4f 100644 --- a/custom_components/yandex_station_intents/const.py +++ b/custom_components/yandex_station_intents/const.py @@ -4,6 +4,7 @@ NOTIFICATION_TITLE = "Yandex.Station Intents" YANDEX_STATION_DOMAIN = "yandex_station" +CONF_ACCOUNTS = "accounts" CONF_INTENTS = "intents" CONF_INTENT_EXTRA_PHRASES = "extra_phrases" CONF_INTENT_SAY_PHRASE = "say_phrase" diff --git a/custom_components/yandex_station_intents/yandex_intent.py b/custom_components/yandex_station_intents/yandex_intent.py index abe9460..5e4a41e 100644 --- a/custom_components/yandex_station_intents/yandex_intent.py +++ b/custom_components/yandex_station_intents/yandex_intent.py @@ -3,6 +3,7 @@ import logging from homeassistant.components import media_player +from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_ENTITY_ID from homeassistant.core import HomeAssistant from homeassistant.helpers.template import Template @@ -82,8 +83,9 @@ def decode(cls, number: str) -> int: class IntentManager: - def __init__(self, hass: HomeAssistant, intents_config: ConfigType) -> None: + def __init__(self, hass: HomeAssistant, entry: ConfigEntry, intents_config: ConfigType) -> None: self._hass = hass + self._entry = entry self._last_command_at: datetime | None = None self._command_execution_loop_count: int = 0 @@ -106,12 +108,12 @@ def event_from_id(self, intent_id: int) -> None: if intent_id < len(self.intents): text = self.intents[intent_id].name _LOGGER.debug(f"Получена команда: {text}") - self._hass.bus.async_fire(EVENT_NAME, {"text": text}) + self._hass.bus.async_fire(EVENT_NAME, {"text": text, "account": self._entry.unique_id}) async def async_handle_phrase(self, phrase: str, event_data: ConfigType, yandex_station_entity_id: str) -> None: intent = self._intent_from_phrase(phrase) if intent: - event_data["text"] = intent.name + event_data.update({"text": intent.name, "account": self._entry.unique_id}) _LOGGER.debug(f"Получена команда: {event_data!r}") self._hass.bus.async_fire(EVENT_NAME, event_data)