Skip to content

Commit

Permalink
Merge pull request #530 from Shulyaka/conversation
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexxIT committed Oct 15, 2024
2 parents 4c766bf + 980962e commit cb965c7
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 13 deletions.
19 changes: 8 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -651,19 +651,16 @@ automation:
platform: event
event_type: telegram_text
action:
service: media_player.play_media
entity_id: media_player.yandex_station_mini # замените на вашу станцию
- service: conversation.process
data:
media_content_id: "{{ trigger.event.data.text }}"
media_content_type: "question:{{ trigger.event.data.chat_id }}"
- trigger:
platform: event
event_type: yandex_station_response
action:
service: telegram_bot.send_message
agent_id: conversation.yandex_station_mini # замените на вашу станцию
text: "{{ trigger.event.data.text }}"
conversation_id: "{{ trigger.event.data.chat_id }}"
response_variable: response
- service: telegram_bot.send_message
data:
target: "{{ trigger.event.data.request_id }}"
message: "{{ trigger.event.data.text }}"
target: "{{ trigger.event.data.chat_id }}"
message: "{{ response.response.speech.plain.speech }}"
```

Для отправки Telegram сообщений разным станциям [@ProstoMaksks](https://t.me/ProstoMaksks) предложил [такое решение](https://gist.github.com/AlexxIT/dc42882c44e298d41631720f146e701d).
Expand Down
3 changes: 2 additions & 1 deletion custom_components/yandex_station/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"button",
"climate",
"camera",
"conversation",
"cover",
"humidifier",
"light",
Expand All @@ -62,7 +63,7 @@
"sensor",
"water_heater",
]
PLATFORMS2 = ["camera", "media_player", "select"] # only for speakers
PLATFORMS2 = ["camera", "conversation", "media_player", "select"] # only for speakers

CONF_TTS_NAME = "tts_service_name"
CONF_DEBUG = "debug"
Expand Down
114 changes: 114 additions & 0 deletions custom_components/yandex_station/conversation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import logging

from typing import Literal
from homeassistant.components import conversation
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.core import HomeAssistant, callback
from homeassistant.config_entries import ConfigEntry
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers import intent
from homeassistant.util import ulid

from .core.const import DOMAIN
from .core.yandex_quasar import YandexQuasar
from .core.yandex_station import YandexStation

_LOGGER = logging.getLogger(__name__)

SUPPORTED_LANGUAGES = ["ru"]


async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
quasar: YandexQuasar = hass.data[DOMAIN][entry.unique_id]

async_add_entities(
[
YandexConversation(quasar, speaker)
for speaker in await quasar.load_speakers()
],
False,
)


class YandexConversation(
conversation.ConversationEntity, conversation.AbstractConversationAgent
):
"""Yandex conversation agent."""

def __init__(self, quasar: YandexQuasar, device: dict) -> None:
super().__init__()
self.quasar = quasar
self.device = device

self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, device["quasar_info"]["device_id"])},
name=self.device["name"],
)
self._attr_name = device["name"] + " Алиса"
self._attr_unique_id = device["quasar_info"]["device_id"] + "_conversation"
self._attr_supported_features = conversation.ConversationEntityFeature.CONTROL

self.entity_id = f"conversation.yandex_station_{self._attr_unique_id.lower()}"

@property
def supported_languages(self) -> list[str] | Literal["*"]:
"""Return a list of supported languages."""
return SUPPORTED_LANGUAGES

async def async_process(
self, user_input: conversation.ConversationInput
) -> conversation.ConversationResult:
"""Process a sentence."""
intent_response = intent.IntentResponse(language=user_input.language)

if user_input.conversation_id is None:
conversation_id = ulid.ulid_now()
else:
try:
ulid.ulid_to_bytes(user_input.conversation_id)
conversation_id = ulid.ulid_now()
except ValueError:
conversation_id = user_input.conversation_id

entity: YandexStation = self.device.get("entity")
if not entity:
intent_response.async_set_error(
intent.IntentResponseErrorCode.UNKNOWN,
f"Яндекс станция {self.device['quasar_info']['device_id']} не найдена",
)
return conversation.ConversationResult(
response=intent_response, conversation_id=conversation_id
)

response = self.hass.loop.create_future()

@callback
def event_filter(event_data):
return (
event_data.get("request_id") == conversation_id
and event_data.get("entity_id") == entity.entity_id
)

@callback
async def response_listener(event):
response.set_result(event.data["text"])

remove_listener = self.hass.bus.async_listen(
f"{DOMAIN}_response", response_listener, event_filter
)

await entity.async_play_media(
media_type=f"question:{conversation_id}", media_id=user_input.text
)

await response

remove_listener()

intent_response.async_set_speech(response.result())

return conversation.ConversationResult(
response=intent_response, conversation_id=conversation_id
)
2 changes: 1 addition & 1 deletion hacs.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Yandex.Station",
"homeassistant": "2023.2.0",
"homeassistant": "2024.5.0",
"render_readme": true,
"country": "RU"
}

0 comments on commit cb965c7

Please sign in to comment.