diff --git a/homeassistant/components/incomfort/__init__.py b/homeassistant/components/incomfort/__init__.py index d6f72209f06..adf57e35093 100644 --- a/homeassistant/components/incomfort/__init__.py +++ b/homeassistant/components/incomfort/__init__.py @@ -1,14 +1,18 @@ """Support for an Intergas boiler via an InComfort/Intouch Lan2RF gateway.""" import logging +from typing import Optional from aiohttp import ClientResponseError -import voluptuous as vol from incomfortclient import Gateway as InComfortGateway +import voluptuous as vol from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME +from homeassistant.core import callback from homeassistant.helpers import config_validation as cv from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.discovery import async_load_platform +from homeassistant.helpers.dispatcher import async_dispatcher_connect +from homeassistant.helpers.entity import Entity _LOGGER = logging.getLogger(__name__) @@ -53,3 +57,38 @@ async def async_setup(hass, hass_config): ) return True + + +class IncomfortEntity(Entity): + """Base class for all InComfort entities.""" + + def __init__(self) -> None: + """Initialize the class.""" + self._unique_id = self._name = None + + @property + def unique_id(self) -> Optional[str]: + """Return a unique ID.""" + return self._unique_id + + @property + def name(self) -> Optional[str]: + """Return the name of the sensor.""" + return self._name + + +class IncomfortChild(IncomfortEntity): + """Base class for all InComfort entities (excluding the boiler).""" + + async def async_added_to_hass(self) -> None: + """Set up a listener when this entity is added to HA.""" + async_dispatcher_connect(self.hass, DOMAIN, self._refresh) + + @callback + def _refresh(self) -> None: + self.async_schedule_update_ha_state(force_refresh=True) + + @property + def should_poll(self) -> bool: + """Return False as this device should never be polled.""" + return False diff --git a/homeassistant/components/incomfort/binary_sensor.py b/homeassistant/components/incomfort/binary_sensor.py index 39a45429cb1..b5dbd8e223d 100644 --- a/homeassistant/components/incomfort/binary_sensor.py +++ b/homeassistant/components/incomfort/binary_sensor.py @@ -1,11 +1,9 @@ """Support for an Intergas heater via an InComfort/InTouch Lan2RF gateway.""" from typing import Any, Dict, Optional -from homeassistant.components.binary_sensor import BinarySensorDevice -from homeassistant.core import callback -from homeassistant.helpers.dispatcher import async_dispatcher_connect +from homeassistant.components.binary_sensor import ENTITY_ID_FORMAT, BinarySensorDevice -from . import DOMAIN +from . import DOMAIN, IncomfortChild async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): @@ -18,34 +16,20 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info= ) -class IncomfortFailed(BinarySensorDevice): +class IncomfortFailed(IncomfortChild, BinarySensorDevice): """Representation of an InComfort Failed sensor.""" def __init__(self, client, heater) -> None: """Initialize the binary sensor.""" + super().__init__() + self._unique_id = f"{heater.serial_no}_failed" + self.entity_id = ENTITY_ID_FORMAT.format(f"{DOMAIN}_failed") + self._name = "Boiler Fault" self._client = client self._heater = heater - async def async_added_to_hass(self) -> None: - """Set up a listener when this entity is added to HA.""" - async_dispatcher_connect(self.hass, DOMAIN, self._refresh) - - @callback - def _refresh(self) -> None: - self.async_schedule_update_ha_state(force_refresh=True) - - @property - def unique_id(self) -> Optional[str]: - """Return a unique ID.""" - return self._unique_id - - @property - def name(self) -> Optional[str]: - """Return the name of the sensor.""" - return "Fault state" - @property def is_on(self) -> bool: """Return the status of the sensor.""" @@ -55,8 +39,3 @@ class IncomfortFailed(BinarySensorDevice): def device_state_attributes(self) -> Optional[Dict[str, Any]]: """Return the device state attributes.""" return {"fault_code": self._heater.status["fault_code"]} - - @property - def should_poll(self) -> bool: - """Return False as this device should never be polled.""" - return False diff --git a/homeassistant/components/incomfort/climate.py b/homeassistant/components/incomfort/climate.py index 3918244d4e8..95ccf186372 100644 --- a/homeassistant/components/incomfort/climate.py +++ b/homeassistant/components/incomfort/climate.py @@ -1,16 +1,14 @@ """Support for an Intergas boiler via an InComfort/InTouch Lan2RF gateway.""" from typing import Any, Dict, List, Optional -from homeassistant.components.climate import ClimateDevice +from homeassistant.components.climate import ENTITY_ID_FORMAT, ClimateDevice from homeassistant.components.climate.const import ( HVAC_MODE_HEAT, SUPPORT_TARGET_TEMPERATURE, ) from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS -from homeassistant.core import callback -from homeassistant.helpers.dispatcher import async_dispatcher_connect -from . import DOMAIN +from . import DOMAIN, IncomfortChild async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): @@ -24,39 +22,19 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info= async_add_entities([InComfortClimate(client, heater, r) for r in heater.rooms]) -class InComfortClimate(ClimateDevice): +class InComfortClimate(IncomfortChild, ClimateDevice): """Representation of an InComfort/InTouch climate device.""" def __init__(self, client, heater, room) -> None: """Initialize the climate device.""" + super().__init__() + self._unique_id = f"{heater.serial_no}_{room.room_no}" + self.entity_id = ENTITY_ID_FORMAT.format(f"{DOMAIN}_{room.room_no}") + self._name = f"Thermostat {room.room_no}" self._client = client self._room = room - self._name = f"Room {room.room_no}" - - async def async_added_to_hass(self) -> None: - """Set up a listener when this entity is added to HA.""" - async_dispatcher_connect(self.hass, DOMAIN, self._refresh) - - @callback - def _refresh(self) -> None: - self.async_schedule_update_ha_state(force_refresh=True) - - @property - def should_poll(self) -> bool: - """Return False as this device should never be polled.""" - return False - - @property - def unique_id(self) -> Optional[str]: - """Return a unique ID.""" - return self._unique_id - - @property - def name(self) -> str: - """Return the name of the climate device.""" - return self._name @property def device_state_attributes(self) -> Dict[str, Any]: diff --git a/homeassistant/components/incomfort/sensor.py b/homeassistant/components/incomfort/sensor.py index 772b5dab183..f3170b7b9bb 100644 --- a/homeassistant/components/incomfort/sensor.py +++ b/homeassistant/components/incomfort/sensor.py @@ -1,18 +1,16 @@ """Support for an Intergas heater via an InComfort/InTouch Lan2RF gateway.""" from typing import Any, Dict, Optional +from homeassistant.components.sensor import ENTITY_ID_FORMAT from homeassistant.const import ( - PRESSURE_BAR, - TEMP_CELSIUS, DEVICE_CLASS_PRESSURE, DEVICE_CLASS_TEMPERATURE, + PRESSURE_BAR, + TEMP_CELSIUS, ) -from homeassistant.core import callback -from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity import Entity from homeassistant.util import slugify -from . import DOMAIN +from . import DOMAIN, IncomfortChild INCOMFORT_HEATER_TEMP = "CV Temp" INCOMFORT_PRESSURE = "CV Pressure" @@ -42,42 +40,28 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info= ) -class IncomfortSensor(Entity): +class IncomfortSensor(IncomfortChild): """Representation of an InComfort/InTouch sensor device.""" def __init__(self, client, heater, name) -> None: """Initialize the sensor.""" + super().__init__() + self._client = client self._heater = heater self._unique_id = f"{heater.serial_no}_{slugify(name)}" + self.entity_id = ENTITY_ID_FORMAT.format(f"{DOMAIN}_{slugify(name)}") + self._name = f"Boiler {name}" - self._name = name self._device_class = None + self._state_attr = INCOMFORT_MAP_ATTRS[name][0] self._unit_of_measurement = None - async def async_added_to_hass(self) -> None: - """Set up a listener when this entity is added to HA.""" - async_dispatcher_connect(self.hass, DOMAIN, self._refresh) - - @callback - def _refresh(self) -> None: - self.async_schedule_update_ha_state(force_refresh=True) - - @property - def unique_id(self) -> Optional[str]: - """Return a unique ID.""" - return self._unique_id - - @property - def name(self) -> Optional[str]: - """Return the name of the sensor.""" - return self._name - @property def state(self) -> Optional[str]: """Return the state of the sensor.""" - return self._heater.status[INCOMFORT_MAP_ATTRS[self._name][0]] + return self._heater.status[self._state_attr] @property def device_class(self) -> Optional[str]: @@ -89,11 +73,6 @@ class IncomfortSensor(Entity): """Return the unit of measurement of the sensor.""" return self._unit_of_measurement - @property - def should_poll(self) -> bool: - """Return False as this device should never be polled.""" - return False - class IncomfortPressure(IncomfortSensor): """Representation of an InTouch CV Pressure sensor.""" @@ -113,11 +92,11 @@ class IncomfortTemperature(IncomfortSensor): """Initialize the signal strength sensor.""" super().__init__(client, heater, name) + self._attr = INCOMFORT_MAP_ATTRS[name][1] self._device_class = DEVICE_CLASS_TEMPERATURE self._unit_of_measurement = TEMP_CELSIUS @property def device_state_attributes(self) -> Optional[Dict[str, Any]]: """Return the device state attributes.""" - key = INCOMFORT_MAP_ATTRS[self._name][1] - return {key: self._heater.status[key]} + return {self._attr: self._heater.status[self._attr]} diff --git a/homeassistant/components/incomfort/water_heater.py b/homeassistant/components/incomfort/water_heater.py index 70423611705..0015107b40f 100644 --- a/homeassistant/components/incomfort/water_heater.py +++ b/homeassistant/components/incomfort/water_heater.py @@ -1,14 +1,15 @@ """Support for an Intergas boiler via an InComfort/Intouch Lan2RF gateway.""" import asyncio import logging -from typing import Any, Dict, Optional +from typing import Any, Dict from aiohttp import ClientResponseError -from homeassistant.components.water_heater import WaterHeaterDevice + +from homeassistant.components.water_heater import ENTITY_ID_FORMAT, WaterHeaterDevice from homeassistant.const import TEMP_CELSIUS from homeassistant.helpers.dispatcher import async_dispatcher_send -from . import DOMAIN +from . import DOMAIN, IncomfortEntity _LOGGER = logging.getLogger(__name__) @@ -26,26 +27,20 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info= async_add_entities([IncomfortWaterHeater(client, heater)]) -class IncomfortWaterHeater(WaterHeaterDevice): +class IncomfortWaterHeater(IncomfortEntity, WaterHeaterDevice): """Representation of an InComfort/Intouch water_heater device.""" def __init__(self, client, heater) -> None: """Initialize the water_heater device.""" + super().__init__() + self._unique_id = f"{heater.serial_no}" + self.entity_id = ENTITY_ID_FORMAT.format(DOMAIN) + self._name = "Boiler" self._client = client self._heater = heater - @property - def unique_id(self) -> Optional[str]: - """Return a unique ID.""" - return self._unique_id - - @property - def name(self) -> str: - """Return the name of the water_heater device.""" - return "Boiler" - @property def icon(self) -> str: """Return the icon of the water_heater device."""