diff --git a/.coveragerc b/.coveragerc index 78ef0996c53daf..5719f4bf16cd65 100644 --- a/.coveragerc +++ b/.coveragerc @@ -514,6 +514,7 @@ omit = homeassistant/components/intellifire/coordinator.py homeassistant/components/intellifire/binary_sensor.py homeassistant/components/intellifire/sensor.py + homeassistant/components/intellifire/entity.py homeassistant/components/incomfort/* homeassistant/components/intesishome/* homeassistant/components/ios/* diff --git a/homeassistant/components/intellifire/binary_sensor.py b/homeassistant/components/intellifire/binary_sensor.py index 62082bb9ab40fe..747dcaa58bef3d 100644 --- a/homeassistant/components/intellifire/binary_sensor.py +++ b/homeassistant/components/intellifire/binary_sensor.py @@ -13,10 +13,10 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import IntellifireDataUpdateCoordinator from .const import DOMAIN +from .entity import IntellifireEntity @dataclass @@ -75,28 +75,11 @@ async def async_setup_entry( ) -class IntellifireBinarySensor(CoordinatorEntity, BinarySensorEntity): - """A semi-generic wrapper around Binary Sensor entities for IntelliFire.""" +class IntellifireBinarySensor(IntellifireEntity, BinarySensorEntity): + """Extends IntellifireEntity with Binary Sensor specific logic.""" - # Define types - coordinator: IntellifireDataUpdateCoordinator entity_description: IntellifireBinarySensorEntityDescription - def __init__( - self, - coordinator: IntellifireDataUpdateCoordinator, - description: IntellifireBinarySensorEntityDescription, - ) -> None: - """Class initializer.""" - super().__init__(coordinator=coordinator) - self.entity_description = description - - # Set the Display name the User will see - self._attr_name = f"Fireplace {description.name}" - self._attr_unique_id = f"{description.key}_{coordinator.api.data.serial}" - # Configure the Device Info - self._attr_device_info = self.coordinator.device_info - @property def is_on(self) -> bool: """Use this to get the correct value.""" diff --git a/homeassistant/components/intellifire/entity.py b/homeassistant/components/intellifire/entity.py new file mode 100644 index 00000000000000..eeb5e7b51bd9a6 --- /dev/null +++ b/homeassistant/components/intellifire/entity.py @@ -0,0 +1,28 @@ +"""Platform for shared base classes for sensors.""" +from __future__ import annotations + +from homeassistant.helpers.entity import EntityDescription +from homeassistant.helpers.update_coordinator import CoordinatorEntity + +from . import IntellifireDataUpdateCoordinator + + +class IntellifireEntity(CoordinatorEntity): + """Define a generic class for Intellifire entities.""" + + coordinator: IntellifireDataUpdateCoordinator + _attr_attribution = "Data provided by unpublished Intellifire API" + + def __init__( + self, + coordinator: IntellifireDataUpdateCoordinator, + description: EntityDescription, + ) -> None: + """Class initializer.""" + super().__init__(coordinator=coordinator) + self.entity_description = description + # Set the Display name the User will see + self._attr_name = f"Fireplace {description.name}" + self._attr_unique_id = f"{description.key}_{coordinator.api.data.serial}" + # Configure the Device Info + self._attr_device_info = self.coordinator.device_info diff --git a/homeassistant/components/intellifire/sensor.py b/homeassistant/components/intellifire/sensor.py index 991e4e69e8c1e2..7c52581498b78f 100644 --- a/homeassistant/components/intellifire/sensor.py +++ b/homeassistant/components/intellifire/sensor.py @@ -17,47 +17,11 @@ from homeassistant.const import TEMP_CELSIUS from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util.dt import utcnow from . import IntellifireDataUpdateCoordinator from .const import DOMAIN - - -class IntellifireSensor(CoordinatorEntity, SensorEntity): - """Define a generic class for Sensors.""" - - # Define types - coordinator: IntellifireDataUpdateCoordinator - entity_description: IntellifireSensorEntityDescription - _attr_attribution = "Data provided by unpublished Intellifire API" - - def __init__( - self, - coordinator: IntellifireDataUpdateCoordinator, - description: IntellifireSensorEntityDescription, - ) -> None: - """Init the sensor.""" - super().__init__(coordinator=coordinator) - self.entity_description = description - - # Set the Display name the User will see - self._attr_name = f"Fireplace {description.name}" - self._attr_unique_id = f"{description.key}_{coordinator.api.data.serial}" - # Configure the Device Info - self._attr_device_info = self.coordinator.device_info - - @property - def native_value(self) -> int | str | datetime | None: - """Return the state.""" - return self.entity_description.value_fn(self.coordinator.api.data) - - -def _time_remaining_to_timestamp(data: IntellifirePollData) -> datetime | None: - """Define a sensor that takes into account timezone.""" - if not (seconds_offset := data.timeremaining_s): - return None - return utcnow() + timedelta(seconds=seconds_offset) +from .entity import IntellifireEntity @dataclass @@ -69,21 +33,17 @@ class IntellifireSensorRequiredKeysMixin: @dataclass class IntellifireSensorEntityDescription( - SensorEntityDescription, IntellifireSensorRequiredKeysMixin + SensorEntityDescription, + IntellifireSensorRequiredKeysMixin, ): - """Describes a sensor sensor entity.""" + """Describes a sensor entity.""" -async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback -) -> None: - """Define setup entry call.""" - - coordinator: IntellifireDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] - async_add_entities( - IntellifireSensor(coordinator=coordinator, description=description) - for description in INTELLIFIRE_SENSORS - ) +def _time_remaining_to_timestamp(data: IntellifirePollData) -> datetime | None: + """Define a sensor that takes into account timezone.""" + if not (seconds_offset := data.timeremaining_s): + return None + return utcnow() + timedelta(seconds=seconds_offset) INTELLIFIRE_SENSORS: tuple[IntellifireSensorEntityDescription, ...] = ( @@ -126,3 +86,26 @@ async def async_setup_entry( value_fn=_time_remaining_to_timestamp, ), ) + + +async def async_setup_entry( + hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback +) -> None: + """Define setup entry call.""" + + coordinator: IntellifireDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] + async_add_entities( + IntellifireSensor(coordinator=coordinator, description=description) + for description in INTELLIFIRE_SENSORS + ) + + +class IntellifireSensor(IntellifireEntity, SensorEntity): + """Extends IntellifireEntity with Sensor specific logic.""" + + entity_description: IntellifireSensorEntityDescription + + @property + def native_value(self) -> int | str | datetime | None: + """Return the state.""" + return self.entity_description.value_fn(self.coordinator.api.data)