Skip to content

Commit

Permalink
Добавлено ограничение по аккаунту для интента (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
dext0r committed Apr 25, 2024
1 parent 2d6852f commit 3033d64
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 7 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ yandex_station_intents:
execute_command: Прибавь температуру кондиционера на 1 градус в {{ event.room }}
Точная температура в комнате: # (7)
say_phrase: "Точная температура {{ states('sensor.room_temperature') }} в {{ event.room }}"
Давай поиграем:
accounts: [vasya] # (8)
```

В данном случае интеграция автоматически создаст в УДЯ семь сценариев, каждый из которых начинается с символов `---`. **Не удаляйте эти символы и не модифицируйте никак название!** По ним компонент понимает, что это его сценарий и в случае необходимости синхронизирует/удалит его.
Expand All @@ -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
Expand Down
17 changes: 13 additions & 4 deletions custom_components/yandex_station_intents/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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]),
}
),
),
Expand All @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions custom_components/yandex_station_intents/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
8 changes: 5 additions & 3 deletions custom_components/yandex_station_intents/yandex_intent.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand All @@ -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)

Expand Down

0 comments on commit 3033d64

Please sign in to comment.