From c18b789cc3cc371a33b368b1e4afe9e4e958ce4b Mon Sep 17 00:00:00 2001 From: Oscar Calvo Date: Fri, 11 Aug 2023 02:11:35 +0000 Subject: [PATCH] Use Py-ccm15 --- homeassistant/components/ccm15/coordinator.py | 77 ++----------------- homeassistant/components/ccm15/data_model.py | 63 --------------- homeassistant/components/ccm15/manifest.json | 2 +- requirements_all.txt | 4 +- requirements_test_all.txt | 4 +- 5 files changed, 13 insertions(+), 137 deletions(-) delete mode 100644 homeassistant/components/ccm15/data_model.py diff --git a/homeassistant/components/ccm15/coordinator.py b/homeassistant/components/ccm15/coordinator.py index 04f70fff1c3..d6ec69a8e6d 100644 --- a/homeassistant/components/ccm15/coordinator.py +++ b/homeassistant/components/ccm15/coordinator.py @@ -1,12 +1,10 @@ """Climate device for CCM15 coordinator.""" -import asyncio import datetime import logging from typing import Any, Optional -import aiohttp +from ccm15 import CCM15Device, CCM15DeviceState, CCM15SlaveDevice import httpx -import xmltodict from homeassistant.components.climate import ( FAN_AUTO, @@ -19,10 +17,7 @@ from homeassistant.components.climate import ( ClimateEntityFeature, HVACMode, ) -from homeassistant.const import ( - ATTR_TEMPERATURE, - UnitOfTemperature, -) +from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.update_coordinator import ( @@ -32,9 +27,6 @@ from homeassistant.helpers.update_coordinator import ( ) from .const import ( - BASE_URL, - CONF_URL_CTRL, - CONF_URL_STATUS, CONST_CMD_FAN_MAP, CONST_CMD_STATE_MAP, CONST_FAN_CMD_MAP, @@ -42,7 +34,6 @@ from .const import ( DEFAULT_TIMEOUT, DOMAIN, ) -from .data_model import CCM15DeviceState, CCM15SlaveDevice _LOGGER = logging.getLogger(__name__) @@ -61,8 +52,8 @@ class CCM15Coordinator(DataUpdateCoordinator[CCM15DeviceState]): update_method=self._async_update_data, update_interval=datetime.timedelta(seconds=interval), ) + self._ccm15 = CCM15Device(host, port, DEFAULT_TIMEOUT) self._host = host - self._port = port self._ac_devices: dict[int, CCM15Climate] = {} def get_devices(self): @@ -76,31 +67,9 @@ class CCM15Coordinator(DataUpdateCoordinator[CCM15DeviceState]): except httpx.RequestError as err: # pragma: no cover raise UpdateFailed(f"Error communicating with Device: {err}") from err - async def _fetch_xml_data(self) -> str: # pragma: no cover - url = BASE_URL.format(self._host, self._port, CONF_URL_STATUS) - _LOGGER.debug("Querying url:'%s'", url) - async with httpx.AsyncClient() as client: - response = await client.get(url, timeout=DEFAULT_TIMEOUT) - return response.text - async def _fetch_data(self) -> CCM15DeviceState: """Get the current status of all AC devices.""" - str_data = await self._fetch_xml_data() - doc = xmltodict.parse(str_data) - data = doc["response"] - _LOGGER.debug("Found %s items in host %s", len(data.items()), self._host) - ac_data = CCM15DeviceState(devices={}) - ac_index = 0 - for ac_name, ac_binary in data.items(): - _LOGGER.debug("Found ac_name:'%s', data:'%s'", ac_name, ac_binary) - if ac_binary == "-": - break - bytesarr = bytes.fromhex(ac_binary.strip(",")) - ac_slave = CCM15SlaveDevice(bytesarr) - _LOGGER.debug("Index: %s, state:'%s'", ac_index, ac_slave) - ac_data.devices[ac_index] = ac_slave - ac_index += 1 - _LOGGER.debug("Found data '%s'", ac_data.devices) + ac_data = await self._ccm15.get_status_async() if len(self._ac_devices) == 0: for ac_index in ac_data.devices: _LOGGER.debug("Creating new ac device at index '%s'", ac_index) @@ -109,45 +78,11 @@ class CCM15Coordinator(DataUpdateCoordinator[CCM15DeviceState]): async def async_test_connection(self): # pragma: no cover """Test the connection to the CCM15 device.""" - url = f"http://{self._host}:{self._port}/{CONF_URL_STATUS}" - try: - async with aiohttp.ClientSession() as session, session.get( - url, timeout=10 - ) as response: - if response.status == 200: - return True - _LOGGER.debug("Test connection: Cannot connect : %s", response.status) - return False - except (aiohttp.ClientError, asyncio.TimeoutError): - _LOGGER.debug("Test connection: Timeout") - return False - - async def async_send_state(self, url: str) -> bool: # pragma: no cover - """Send the url to set state to the ccm15 slave.""" - async with httpx.AsyncClient() as client: - response = await client.get(url, timeout=DEFAULT_TIMEOUT) - _LOGGER.debug("API response status code:%d", response.status_code) - return response.status_code in (httpx.codes.OK, httpx.codes.FOUND) + return await self._ccm15.async_test_connection() async def async_set_state(self, ac_index: int, state: str, value: int) -> None: """Set new target states.""" - _LOGGER.debug("Calling async_set_states for ac index '%s'", ac_index) - ac_id: int = 2**ac_index - url = BASE_URL.format( - self._host, - self._port, - CONF_URL_CTRL - + "?ac0=" - + str(ac_id) - + "&ac1=0" - + "&" - + state - + "=" - + str(value), - ) - _LOGGER.debug("Url:'%s'", url) - - if await self.async_send_state(url): + if await self._ccm15.async_set_state(ac_index, state, value): await self.async_request_refresh() def get_ac_data(self, ac_index: int) -> Optional[CCM15SlaveDevice]: diff --git a/homeassistant/components/ccm15/data_model.py b/homeassistant/components/ccm15/data_model.py deleted file mode 100644 index 926d9e1793d..00000000000 --- a/homeassistant/components/ccm15/data_model.py +++ /dev/null @@ -1,63 +0,0 @@ -"""Data model to represent state of a CCM15 device.""" -from dataclasses import dataclass -import logging - -from homeassistant.const import ( - UnitOfTemperature, -) - -_LOGGER = logging.getLogger(__name__) - - -@dataclass -class CCM15SlaveDevice: - """Data retrieved from a CCM15 slave device.""" - - def __init__(self, bytesarr: bytes) -> None: - """Initialize the slave device.""" - self.unit = UnitOfTemperature.CELSIUS - buf = bytesarr[0] - if (buf >> 0) & 1: - self.unit = UnitOfTemperature.FAHRENHEIT - self.locked_cool_temperature: int = (buf >> 3) & 0x1F - - buf = bytesarr[1] - self.locked_heat_temperature: int = (buf >> 0) & 0x1F - self.locked_wind: int = (buf >> 5) & 7 - - buf = bytesarr[2] - self.locked_ac_mode: int = (buf >> 0) & 3 - self.error_code: int = (buf >> 2) & 0x3F - - buf = bytesarr[3] - self.ac_mode: int = (buf >> 2) & 7 - self.fan_mode: int = (buf >> 5) & 7 - - buf = (buf >> 1) & 1 - self.is_ac_mode_locked: bool = buf != 0 - - buf = bytesarr[4] - self.temperature_setpoint: int = (buf >> 3) & 0x1F - if self.unit == UnitOfTemperature.FAHRENHEIT: - self.temperature_setpoint += 62 - self.locked_cool_temperature += 62 - self.locked_heat_temperature += 62 - self.is_swing_on: bool = (buf >> 1) & 1 != 0 - - buf = bytesarr[5] - if ((buf >> 3) & 1) == 0: - self.locked_cool_temperature = 0 - if ((buf >> 4) & 1) == 0: - self.locked_heat_temperature = 0 - self.fan_locked: bool = buf >> 5 & 1 != 0 - self.is_remote_locked: bool = ((buf >> 6) & 1) != 0 - - buf = bytesarr[6] - self.temperature: int = buf if buf < 128 else buf - 256 - - -@dataclass -class CCM15DeviceState: - """Data retrieved from a CCM15 device.""" - - devices: dict[int, CCM15SlaveDevice] diff --git a/homeassistant/components/ccm15/manifest.json b/homeassistant/components/ccm15/manifest.json index cae9876a097..f6dbe29dad0 100644 --- a/homeassistant/components/ccm15/manifest.json +++ b/homeassistant/components/ccm15/manifest.json @@ -7,7 +7,7 @@ "documentation": "https://www.home-assistant.io/integrations/ccm15", "homekit": {}, "iot_class": "local_polling", - "requirements": ["xmltodict==0.13.0"], + "requirements": ["py-ccm15==0.0.5"], "ssdp": [], "zeroconf": [] } diff --git a/requirements_all.txt b/requirements_all.txt index 0d22c3f4e80..101fbe5eee9 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1483,6 +1483,9 @@ pvo==1.0.0 # homeassistant.components.canary py-canary==0.5.3 +# homeassistant.components.ccm15 +py-ccm15==0.0.5 + # homeassistant.components.cpuspeed py-cpuinfo==8.0.0 @@ -2707,7 +2710,6 @@ xknx==2.11.2 xknxproject==3.2.0 # homeassistant.components.bluesound -# homeassistant.components.ccm15 # homeassistant.components.fritz # homeassistant.components.rest # homeassistant.components.startca diff --git a/requirements_test_all.txt b/requirements_test_all.txt index ad405ba0c9b..f813258175b 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1116,6 +1116,9 @@ pvo==1.0.0 # homeassistant.components.canary py-canary==0.5.3 +# homeassistant.components.ccm15 +py-ccm15==0.0.5 + # homeassistant.components.cpuspeed py-cpuinfo==8.0.0 @@ -1992,7 +1995,6 @@ xknx==2.11.2 xknxproject==3.2.0 # homeassistant.components.bluesound -# homeassistant.components.ccm15 # homeassistant.components.fritz # homeassistant.components.rest # homeassistant.components.startca