Skip to content

Commit

Permalink
Code refactoring after #530
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexxIT committed Oct 15, 2024
1 parent cb965c7 commit 66d1c8f
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 68 deletions.
8 changes: 7 additions & 1 deletion custom_components/yandex_station/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
"button",
"climate",
"camera",
"conversation",
"cover",
"humidifier",
"light",
Expand Down Expand Up @@ -121,6 +120,13 @@ async def async_setup(hass: HomeAssistant, hass_config: dict):
await _init_services(hass)
await _setup_entry_from_config(hass)

try:
from . import conversation

PLATFORMS.append("conversation")
except ImportError as e:
_LOGGER.warning(repr(e)) # supported from 2024.5

hass.http.register_view(utils.StreamingView(hass))

return True
Expand Down
106 changes: 40 additions & 66 deletions custom_components/yandex_station/conversation.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import logging

from typing import Literal
from homeassistant.components import conversation
from homeassistant.components.conversation import (
ConversationEntity,
ConversationEntityFeature,
ConversationInput,
ConversationResult,
)
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.helpers.intent import IntentResponse, IntentResponseErrorCode
from homeassistant.util import ulid

from .core.const import DOMAIN
Expand All @@ -15,14 +16,9 @@

_LOGGER = logging.getLogger(__name__)

SUPPORTED_LANGUAGES = ["ru"]


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

async_add_entities(
[
YandexConversation(quasar, speaker)
Expand All @@ -32,36 +28,28 @@ async def async_setup_entry(
)


class YandexConversation(
conversation.ConversationEntity, conversation.AbstractConversationAgent
):
"""Yandex conversation agent."""
class YandexConversation(ConversationEntity):
_attr_entity_registry_enabled_default = False
_attr_supported_features = ConversationEntityFeature.CONTROL

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

self._attr_name = device["name"] + " Алиса"
self._attr_unique_id = device["quasar_info"]["device_id"] + "_conversation"

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
def supported_languages(self) -> list[str]:
return ["ru"]

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

if user_input.conversation_id is None:
conversation_id = ulid.ulid_now()
Expand All @@ -73,42 +61,28 @@ async def async_process(
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
if entity and entity.glagol:
card = await entity.glagol.send(
{"command": "sendText", "text": user_input.text}
)

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
if card:
if text := card.get("text"):
response.async_set_speech(text)
elif error := card.get("error"):
response.async_set_error(
IntentResponseErrorCode.FAILED_TO_HANDLE, error
)
else:
response.async_set_error(
IntentResponseErrorCode.NO_INTENT_MATCH, "Нет текстового ответа"
)
else:
response.async_set_error(
IntentResponseErrorCode.FAILED_TO_HANDLE, "Неизвестная ошибка"
)
else:
response.async_set_error(
IntentResponseErrorCode.UNKNOWN, "Алиса недоступна"
)

@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
)
return ConversationResult(response=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": "2024.5.0",
"homeassistant": "2023.2.0",
"render_readme": true,
"country": "RU"
}

0 comments on commit 66d1c8f

Please sign in to comment.