"""HomeWizard Energy base class""" from __future__ import annotations import asyncio from typing import Any from aiohttp.client import ClientSession, ClientTimeout, TCPConnector from .const import LOGGER from .errors import UnsupportedError from .models import Batteries, CombinedModels, Device, Measurement, State, System class HomeWizardEnergy: """Base class for HomeWizard Energy API.""" _session: ClientSession | None = None _close_session: bool = False _request_timeout: int = 10 _host: str _device: Device | None = None _lock: asyncio.Lock def __init__( self, host: str, clientsession: ClientSession = None, timeout: int = 10, ): """Create a HomeWizard Energy object. Args: host: IP or URL for device. clientsession: The clientsession. timeout: Request timeout in seconds. """ self._host = host self._session = clientsession self._close_session = clientsession is None self._request_timeout = timeout self._lock = asyncio.Lock() @property def host(self) -> str: """Return the hostname of the device. Returns: host: The used host """ return self._host async def combined(self) -> CombinedModels: """Get all information.""" async def fetch_data(coroutine): try: return await coroutine except (UnsupportedError, NotImplementedError): return None device, measurement, system, state, batteries = await asyncio.gather( fetch_data(self.device()), fetch_data(self.measurement()), fetch_data(self.system()), fetch_data(self.state()), fetch_data(self.batteries()), ) return CombinedModels( device=device, measurement=measurement, system=system, state=state, batteries=batteries, ) async def device(self, reset_cache: bool = False) -> Device: """Get the device information.""" raise NotImplementedError async def measurement(self) -> Measurement: """Get the current measurement.""" raise NotImplementedError async def telegram(self) -> str: """Get the latest telegram.""" raise NotImplementedError async def system( self, cloud_enabled: bool | None = None, status_led_brightness_pct: int | None = None, api_v1_enabled: bool | None = None, ) -> System: """Get/set the system.""" raise NotImplementedError async def state( self, power_on: bool | None = None, switch_lock: bool | None = None, brightness: int | None = None, ) -> State: """Get/set the state.""" raise UnsupportedError("State is not supported") async def batteries(self, mode: Batteries.Mode | None = None) -> Batteries: """Get the batteries.""" raise UnsupportedError("Batteries are not supported") async def identify( self, ) -> None: """Identify the device.""" raise NotImplementedError async def reboot( self, ) -> None: """Reboot the device.""" raise UnsupportedError("Reboot is not supported") async def close(self) -> None: """Close client session.""" LOGGER.debug("Closing clientsession") if self._session and self._close_session: await self._session.close() async def _create_clientsession(self) -> None: """Create a client session.""" LOGGER.debug("Creating clientsession") if self._session is not None: raise RuntimeError("Session already exists") # pragma: no cover connector = TCPConnector( enable_cleanup_closed=True, limit_per_host=1, ) self._close_session = True self._session = ClientSession( connector=connector, timeout=ClientTimeout(total=self._request_timeout) ) async def __aenter__(self) -> HomeWizardEnergy: """Async enter. Returns: The HomeWizardEnergy object. """ return self async def __aexit__(self, *_exc_info: Any) -> None: """Async exit. Args: _exc_info: Exec type. """ await self.close()