Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a base class for Intellifire entities #65077

Merged
merged 9 commits into from Feb 12, 2022
1 change: 1 addition & 0 deletions .coveragerc
Expand Up @@ -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/*
Expand Down
23 changes: 3 additions & 20 deletions homeassistant/components/intellifire/binary_sensor.py
Expand Up @@ -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
Expand Down Expand Up @@ -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."""
Expand Down
28 changes: 28 additions & 0 deletions 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
81 changes: 32 additions & 49 deletions homeassistant/components/intellifire/sensor.py
Expand Up @@ -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
Expand All @@ -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, ...] = (
Expand Down Expand Up @@ -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)