"""Client interface for Home Assistant to cloud.""" from __future__ import annotations from abc import ABC, abstractmethod from asyncio import AbstractEventLoop from pathlib import Path from typing import TYPE_CHECKING, Any, Literal from aiohttp import ClientSession from aiohttp.web import AppRunner from .iot import HandlerError if TYPE_CHECKING: from . import Cloud class RemoteActivationNotAllowed(HandlerError): """Raised when it's not allowed to remotely activate remote UI.""" def __init__(self) -> None: """Initialize Error Message.""" super().__init__("remote_activation_not_allowed") class CloudClient(ABC): """Interface class for Home Assistant.""" cloud: Cloud @property @abstractmethod def base_path(self) -> Path: """Return path to base dir.""" @property @abstractmethod def loop(self) -> AbstractEventLoop: """Return client loop.""" @property @abstractmethod def websession(self) -> ClientSession: """Return client session for aiohttp.""" @property @abstractmethod def client_name(self) -> str: """Return name of the client, this will be used as the user-agent.""" @property @abstractmethod def aiohttp_runner(self) -> AppRunner | None: """Return client webinterface aiohttp application.""" @property @abstractmethod def cloudhooks(self) -> dict[str, dict[str, str | bool]]: """Return list of cloudhooks.""" @property @abstractmethod def remote_autostart(self) -> bool: """Return true if we want start a remote connection.""" @abstractmethod async def cloud_connected(self) -> None: """Cloud connected.""" @abstractmethod async def cloud_disconnected(self) -> None: """Cloud disconnected.""" @abstractmethod async def cloud_started(self) -> None: """Cloud started with an active subscription.""" @abstractmethod async def cloud_stopped(self) -> None: """Cloud stopped.""" @abstractmethod async def logout_cleanups(self) -> None: """Cleanup before logout.""" @abstractmethod async def async_cloud_connect_update(self, connect: bool) -> None: """Process cloud remote message to client. If it's not allowed to remotely enable remote control, the implementation should raise RemoteActivationNotAllowed """ @abstractmethod async def async_cloud_connection_info( self, payload: dict[str, Any], ) -> dict[str, Any]: """Process cloud connection info message to client.""" @abstractmethod async def async_alexa_message(self, payload: dict[str, Any]) -> dict[str, Any]: """Process cloud alexa message to client.""" @abstractmethod async def async_system_message(self, payload: dict[str, Any]) -> None: """Process cloud system message to client.""" @abstractmethod async def async_google_message(self, payload: dict[str, Any]) -> dict[str, Any]: """Process cloud google message to client.""" @abstractmethod async def async_webhook_message(self, payload: dict[str, Any]) -> dict[str, Any]: """Process cloud webhook message to client.""" @abstractmethod async def async_cloudhooks_update( self, data: dict[str, dict[str, str | bool]], ) -> None: """Update local list of cloudhooks.""" @abstractmethod def dispatcher_message(self, identifier: str, data: Any = None) -> None: """Send data to dispatcher.""" @abstractmethod def user_message(self, identifier: str, title: str, message: str) -> None: """Create a message for user to UI.""" @abstractmethod async def async_create_repair_issue( self, identifier: str, translation_key: str, *, placeholders: dict[str, str] | None = None, severity: Literal["error", "warning"] = "warning", ) -> None: """Create a repair issue.""" @abstractmethod async def async_delete_repair_issue(self, identifier: str) -> None: """Delete a repair issue."""