Add econet device and state classes (#84201)

* Updated econet sensors to have device and state classes

* Updated econet sensors to have device and state classes

* EcoNet sensor updates

* Updated EcoNet sensors to convert kBtu to kWh

* Updating EcoNet sensor with suggestions

* Updating EcoNet sensor with suggestions

* Updating EcoNet sensor with suggestions

* Updating EcoNet sensor with suggestions

* Updating EcoNet sensors name and unique id

* Updating EcoNet sensor with suggestions

* Updating EcoNet sensor with suggestions
This commit is contained in:
David McKenna 2023-01-05 09:25:33 -04:00 committed by GitHub
parent b578d08e8a
commit 8ffeffd9d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 100 additions and 101 deletions

View File

@ -116,6 +116,8 @@ class EcoNetEntity(Entity):
def __init__(self, econet): def __init__(self, econet):
"""Initialize.""" """Initialize."""
self._econet = econet self._econet = econet
self._attr_name = econet.device_name
self._attr_unique_id = f"{econet.device_id}_{econet.device_name}"
async def async_added_to_hass(self): async def async_added_to_hass(self):
"""Subscribe to device events.""" """Subscribe to device events."""
@ -143,16 +145,6 @@ class EcoNetEntity(Entity):
name=self._econet.device_name, name=self._econet.device_name,
) )
@property
def name(self):
"""Return the name of the entity."""
return self._econet.device_name
@property
def unique_id(self):
"""Return the unique ID of the entity."""
return f"{self._econet.device_id}_{self._econet.device_name}"
@property @property
def temperature_unit(self): def temperature_unit(self):
"""Return the unit of measurement.""" """Return the unit of measurement."""

View File

@ -64,19 +64,12 @@ class EcoNetBinarySensor(EcoNetEntity, BinarySensorEntity):
"""Initialize.""" """Initialize."""
super().__init__(econet_device) super().__init__(econet_device)
self.entity_description = description self.entity_description = description
self._econet = econet_device self._attr_name = f"{econet_device.device_name}_{description.name}"
self._attr_unique_id = (
f"{econet_device.device_id}_{econet_device.device_name}_{description.name}"
)
@property @property
def is_on(self): def is_on(self):
"""Return true if the binary sensor is on.""" """Return true if the binary sensor is on."""
return getattr(self._econet, self.entity_description.key) return getattr(self._econet, self.entity_description.key)
@property
def name(self):
"""Return the name of the entity."""
return f"{self._econet.device_name}_{self.entity_description.name}"
@property
def unique_id(self):
"""Return the unique ID of the entity."""
return f"{self._econet.device_id}_{self._econet.device_name}_{self.entity_description.name}"

View File

@ -1,50 +1,83 @@
"""Support for Rheem EcoNet water heaters.""" """Support for Rheem EcoNet water heaters."""
from pyeconet.equipment import EquipmentType from __future__ import annotations
from homeassistant.components.sensor import SensorEntity from pyeconet.equipment import Equipment, EquipmentType
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import PERCENTAGE, UnitOfEnergy, UnitOfVolume from homeassistant.const import (
PERCENTAGE,
SIGNAL_STRENGTH_DECIBELS,
UnitOfEnergy,
UnitOfVolume,
)
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import EcoNetEntity from . import EcoNetEntity
from .const import DOMAIN, EQUIPMENT from .const import DOMAIN, EQUIPMENT
ENERGY_KILO_BRITISH_THERMAL_UNIT = "kBtu" SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
SensorEntityDescription(
TANK_HEALTH = "tank_health" key="tank_health",
AVAILABLE_HOT_WATER = "available_hot_water" name="tank_health",
COMPRESSOR_HEALTH = "compressor_health" native_unit_of_measurement=PERCENTAGE,
OVERRIDE_STATUS = "override_status" state_class=SensorStateClass.MEASUREMENT,
WATER_USAGE_TODAY = "water_usage_today" ),
POWER_USAGE_TODAY = "power_usage_today" SensorEntityDescription(
ALERT_COUNT = "alert_count" key="tank_hot_water_availability",
WIFI_SIGNAL = "wifi_signal" name="available_hot_water",
RUNNING_STATE = "running_state" native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
SENSOR_NAMES_TO_ATTRIBUTES = { ),
TANK_HEALTH: "tank_health", SensorEntityDescription(
AVAILABLE_HOT_WATER: "tank_hot_water_availability", key="compressor_health",
COMPRESSOR_HEALTH: "compressor_health", name="compressor_health",
OVERRIDE_STATUS: "override_status", native_unit_of_measurement=PERCENTAGE,
WATER_USAGE_TODAY: "todays_water_usage", state_class=SensorStateClass.MEASUREMENT,
POWER_USAGE_TODAY: "todays_energy_usage", ),
ALERT_COUNT: "alert_count", SensorEntityDescription(
WIFI_SIGNAL: "wifi_signal", key="override_status",
RUNNING_STATE: "running_state", name="override_status",
} ),
SensorEntityDescription(
SENSOR_NAMES_TO_UNIT_OF_MEASUREMENT = { key="todays_water_usage",
TANK_HEALTH: PERCENTAGE, name="water_usage_today",
AVAILABLE_HOT_WATER: PERCENTAGE, native_unit_of_measurement=UnitOfVolume.GALLONS,
COMPRESSOR_HEALTH: PERCENTAGE, device_class=SensorDeviceClass.WATER,
OVERRIDE_STATUS: None, state_class=SensorStateClass.TOTAL_INCREASING,
WATER_USAGE_TODAY: UnitOfVolume.GALLONS, ),
POWER_USAGE_TODAY: None, # Depends on unit type SensorEntityDescription(
ALERT_COUNT: None, key="todays_energy_usage",
WIFI_SIGNAL: None, name="power_usage_today",
RUNNING_STATE: None, # This is just a string native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
} device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL_INCREASING,
),
SensorEntityDescription(
key="alert_count",
name="alert_count",
),
SensorEntityDescription(
key="wifi_signal",
name="wifi_signal",
native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS,
device_class=SensorDeviceClass.SIGNAL_STRENGTH,
state_class=SensorStateClass.MEASUREMENT,
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
SensorEntityDescription(
key="running_state",
name="running_state",
),
)
async def async_setup_entry( async def async_setup_entry(
@ -52,22 +85,16 @@ async def async_setup_entry(
) -> None: ) -> None:
"""Set up EcoNet sensor based on a config entry.""" """Set up EcoNet sensor based on a config entry."""
equipment = hass.data[DOMAIN][EQUIPMENT][entry.entry_id] data = hass.data[DOMAIN][EQUIPMENT][entry.entry_id]
sensors = [] equipment = data[EquipmentType.WATER_HEATER].copy()
all_equipment = equipment[EquipmentType.WATER_HEATER].copy() equipment.extend(data[EquipmentType.THERMOSTAT].copy())
all_equipment.extend(equipment[EquipmentType.THERMOSTAT].copy())
for _equip in all_equipment: sensors = [
for name, attribute in SENSOR_NAMES_TO_ATTRIBUTES.items(): EcoNetSensor(_equip, description)
if getattr(_equip, attribute, None) is not None: for _equip in equipment
sensors.append(EcoNetSensor(_equip, name)) for description in SENSOR_TYPES
# This is None to start with and all device have it if getattr(_equip, description.key, False) is not False
sensors.append(EcoNetSensor(_equip, WIFI_SIGNAL)) ]
for water_heater in equipment[EquipmentType.WATER_HEATER]:
# These aren't part of the device and start off as None in pyeconet so always add them
sensors.append(EcoNetSensor(water_heater, WATER_USAGE_TODAY))
sensors.append(EcoNetSensor(water_heater, POWER_USAGE_TODAY))
async_add_entities(sensors) async_add_entities(sensors)
@ -75,39 +102,26 @@ async def async_setup_entry(
class EcoNetSensor(EcoNetEntity, SensorEntity): class EcoNetSensor(EcoNetEntity, SensorEntity):
"""Define a Econet sensor.""" """Define a Econet sensor."""
def __init__(self, econet_device, device_name): def __init__(
self,
econet_device: Equipment,
description: SensorEntityDescription,
) -> None:
"""Initialize.""" """Initialize."""
super().__init__(econet_device) super().__init__(econet_device)
self._econet = econet_device self.entity_description = description
self._device_name = device_name self._attr_name = f"{econet_device.device_name}_{description.name}"
self._attr_unique_id = (
f"{econet_device.device_id}_{econet_device.device_name}_{description.name}"
)
@property @property
def native_value(self): def native_value(self):
"""Return sensors state.""" """Return sensors state."""
value = getattr(self._econet, SENSOR_NAMES_TO_ATTRIBUTES[self._device_name]) value = getattr(self._econet, self.entity_description.key)
if self.entity_description.name == "power_usage_today":
if self._econet.energy_type == "KBTU":
value = value * 0.2930710702 # Convert kBtu to kWh
if isinstance(value, float): if isinstance(value, float):
value = round(value, 2) value = round(value, 2)
return value return value
@property
def native_unit_of_measurement(self):
"""Return the unit of measurement of this entity, if any."""
unit_of_measurement = SENSOR_NAMES_TO_UNIT_OF_MEASUREMENT[self._device_name]
if self._device_name == POWER_USAGE_TODAY:
if self._econet.energy_type == ENERGY_KILO_BRITISH_THERMAL_UNIT.upper():
unit_of_measurement = ENERGY_KILO_BRITISH_THERMAL_UNIT
else:
unit_of_measurement = UnitOfEnergy.KILO_WATT_HOUR
return unit_of_measurement
@property
def name(self) -> str:
"""Return the name of the entity."""
return f"{self._econet.device_name}_{self._device_name}"
@property
def unique_id(self) -> str:
"""Return the unique ID of the entity."""
return (
f"{self._econet.device_id}_{self._econet.device_name}_{self._device_name}"
)