Restructure the youless integration internals (#135842)

This commit is contained in:
Gerben Jongerius 2025-01-23 13:35:21 +01:00 committed by GitHub
parent e57dafee6c
commit d6f6961674
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 367 additions and 350 deletions

View File

@ -1,6 +1,5 @@
"""The youless integration."""
from datetime import timedelta
import logging
from urllib.error import URLError
@ -10,9 +9,9 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from .const import DOMAIN
from .coordinator import YouLessCoordinator
PLATFORMS = [Platform.SENSOR]
@ -28,24 +27,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
except URLError as exception:
raise ConfigEntryNotReady from exception
async def async_update_data() -> YoulessAPI:
"""Fetch data from the API."""
await hass.async_add_executor_job(api.update)
return api
coordinator = DataUpdateCoordinator(
hass,
_LOGGER,
config_entry=entry,
name="youless_gateway",
update_method=async_update_data,
update_interval=timedelta(seconds=10),
)
await coordinator.async_config_entry_first_refresh()
youless_coordinator = YouLessCoordinator(hass, api)
await youless_coordinator.async_config_entry_first_refresh()
hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][entry.entry_id] = coordinator
hass.data[DOMAIN][entry.entry_id] = youless_coordinator
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True

View File

@ -0,0 +1,25 @@
"""The coordinator for the Youless integration."""
from datetime import timedelta
import logging
from youless_api import YoulessAPI
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
_LOGGER = logging.getLogger(__name__)
class YouLessCoordinator(DataUpdateCoordinator[None]):
"""Class to manage fetching YouLess data."""
def __init__(self, hass: HomeAssistant, device: YoulessAPI) -> None:
"""Initialize global YouLess data provider."""
super().__init__(
hass, _LOGGER, name="youless_gateway", update_interval=timedelta(seconds=10)
)
self.device = device
async def _async_update_data(self) -> None:
await self.hass.async_add_executor_job(self.device.update)

View File

@ -0,0 +1,25 @@
"""The entity for the Youless integration."""
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN
from .coordinator import YouLessCoordinator
class YouLessEntity(CoordinatorEntity[YouLessCoordinator]):
"""Base entity for YouLess."""
def __init__(
self, coordinator: YouLessCoordinator, device_group: str, device_name: str
) -> None:
"""Initialize the entity."""
super().__init__(coordinator)
self.device = coordinator.device
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, device_group)},
manufacturer="YouLess",
model=self.device.model,
name=device_name,
sw_version=self.device.firmware_version,
)

View File

@ -2,12 +2,15 @@
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from youless_api import YoulessAPI
from youless_api.youless_sensor import YoulessSensor
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.config_entries import ConfigEntry
@ -20,346 +23,316 @@ from homeassistant.const import (
UnitOfVolume,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
DataUpdateCoordinator,
)
from . import DOMAIN
from .coordinator import YouLessCoordinator
from .entity import YouLessEntity
@dataclass(frozen=True, kw_only=True)
class YouLessSensorEntityDescription(SensorEntityDescription):
"""Describes a YouLess sensor entity."""
device_group: str
device_group_name: str
value_func: Callable[[YoulessAPI], float | None]
SENSOR_TYPES: tuple[YouLessSensorEntityDescription, ...] = (
YouLessSensorEntityDescription(
key="water",
device_group="water",
device_group_name="Water meter",
name="Water usage",
icon="mdi:water",
device_class=SensorDeviceClass.WATER,
state_class=SensorStateClass.TOTAL_INCREASING,
native_unit_of_measurement=UnitOfVolume.CUBIC_METERS,
value_func=(
lambda device: device.water_meter.value if device.water_meter else None
),
),
YouLessSensorEntityDescription(
key="gas",
device_group="gas",
device_group_name="Gas meter",
name="Gas usage",
icon="mdi:fire",
device_class=SensorDeviceClass.GAS,
state_class=SensorStateClass.TOTAL_INCREASING,
native_unit_of_measurement=UnitOfVolume.CUBIC_METERS,
value_func=lambda device: device.gas_meter.value if device.gas_meter else None,
),
YouLessSensorEntityDescription(
key="usage",
device_group="power",
device_group_name="Power usage",
name="Power Usage",
icon="mdi:meter-electric",
device_class=SensorDeviceClass.POWER,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfPower.WATT,
value_func=(
lambda device: device.current_power_usage.value
if device.current_power_usage
else None
),
),
YouLessSensorEntityDescription(
key="power_low",
device_group="power",
device_group_name="Power usage",
name="Energy low",
icon="mdi:transmission-tower-export",
device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL_INCREASING,
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
value_func=(
lambda device: device.power_meter.low.value if device.power_meter else None
),
),
YouLessSensorEntityDescription(
key="power_high",
device_group="power",
device_group_name="Power usage",
name="Energy high",
icon="mdi:transmission-tower-export",
device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL_INCREASING,
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
value_func=(
lambda device: device.power_meter.high.value if device.power_meter else None
),
),
YouLessSensorEntityDescription(
key="power_total",
device_group="power",
device_group_name="Power usage",
name="Energy total",
icon="mdi:transmission-tower-export",
device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL,
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
value_func=(
lambda device: device.power_meter.total.value
if device.power_meter
else None
),
),
YouLessSensorEntityDescription(
key="phase_1_power",
device_group="power",
device_group_name="Power usage",
name="Phase 1 power",
icon=None,
device_class=SensorDeviceClass.POWER,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfPower.WATT,
value_func=lambda device: device.phase1.power.value if device.phase1 else None,
),
YouLessSensorEntityDescription(
key="phase_1_voltage",
device_group="power",
device_group_name="Power usage",
name="Phase 1 voltage",
icon=None,
device_class=SensorDeviceClass.VOLTAGE,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
value_func=(
lambda device: device.phase1.voltage.value if device.phase1 else None
),
),
YouLessSensorEntityDescription(
key="phase_1_current",
device_group="power",
device_group_name="Power usage",
name="Phase 1 current",
icon=None,
device_class=SensorDeviceClass.CURRENT,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
value_func=(
lambda device: device.phase1.current.value if device.phase1 else None
),
),
YouLessSensorEntityDescription(
key="phase_2_power",
device_group="power",
device_group_name="Power usage",
name="Phase 2 power",
icon=None,
device_class=SensorDeviceClass.POWER,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfPower.WATT,
value_func=lambda device: device.phase2.power.value if device.phase2 else None,
),
YouLessSensorEntityDescription(
key="phase_2_voltage",
device_group="power",
device_group_name="Power usage",
name="Phase 2 voltage",
icon=None,
device_class=SensorDeviceClass.VOLTAGE,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
value_func=(
lambda device: device.phase2.voltage.value if device.phase2 else None
),
),
YouLessSensorEntityDescription(
key="phase_2_current",
device_group="power",
device_group_name="Power usage",
name="Phase 2 current",
icon=None,
device_class=SensorDeviceClass.CURRENT,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
value_func=(
lambda device: device.phase2.current.value if device.phase1 else None
),
),
YouLessSensorEntityDescription(
key="phase_3_power",
device_group="power",
device_group_name="Power usage",
name="Phase 3 power",
icon=None,
device_class=SensorDeviceClass.POWER,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfPower.WATT,
value_func=lambda device: device.phase3.power.value if device.phase3 else None,
),
YouLessSensorEntityDescription(
key="phase_3_voltage",
device_group="power",
device_group_name="Power usage",
name="Phase 3 voltage",
icon=None,
device_class=SensorDeviceClass.VOLTAGE,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
value_func=(
lambda device: device.phase3.voltage.value if device.phase3 else None
),
),
YouLessSensorEntityDescription(
key="phase_3_current",
device_group="power",
device_group_name="Power usage",
name="Phase 3 current",
icon=None,
device_class=SensorDeviceClass.CURRENT,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
value_func=(
lambda device: device.phase3.current.value if device.phase1 else None
),
),
YouLessSensorEntityDescription(
key="delivery_low",
device_group="delivery",
device_group_name="Energy delivery",
name="Energy delivery low",
icon="mdi:transmission-tower-import",
device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL_INCREASING,
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
value_func=(
lambda device: device.delivery_meter.low.value
if device.delivery_meter
else None
),
),
YouLessSensorEntityDescription(
key="delivery_high",
device_group="delivery",
device_group_name="Energy delivery",
name="Energy delivery high",
icon="mdi:transmission-tower-import",
device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL_INCREASING,
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
value_func=(
lambda device: device.delivery_meter.high.value
if device.delivery_meter
else None
),
),
YouLessSensorEntityDescription(
key="extra_total",
device_group="extra",
device_group_name="Extra meter",
name="Extra total",
icon="mdi:meter-electric",
device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL_INCREASING,
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
value_func=(
lambda device: device.extra_meter.total.value
if device.extra_meter
else None
),
),
YouLessSensorEntityDescription(
key="extra_usage",
device_group="extra",
device_group_name="Extra meter",
name="Extra usage",
icon="mdi:lightning-bolt",
device_class=SensorDeviceClass.POWER,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfPower.WATT,
value_func=(
lambda device: device.extra_meter.usage.value
if device.extra_meter
else None
),
),
)
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Initialize the integration."""
coordinator: DataUpdateCoordinator[YoulessAPI] = hass.data[DOMAIN][entry.entry_id]
coordinator: YouLessCoordinator = hass.data[DOMAIN][entry.entry_id]
device = entry.data[CONF_DEVICE]
if (device := entry.data[CONF_DEVICE]) is None:
device = entry.entry_id
async_add_entities(
[
WaterSensor(coordinator, device),
GasSensor(coordinator, device),
EnergyMeterSensor(
coordinator, device, "low", SensorStateClass.TOTAL_INCREASING
),
EnergyMeterSensor(
coordinator, device, "high", SensorStateClass.TOTAL_INCREASING
),
EnergyMeterSensor(coordinator, device, "total", SensorStateClass.TOTAL),
CurrentPowerSensor(coordinator, device),
DeliveryMeterSensor(coordinator, device, "low"),
DeliveryMeterSensor(coordinator, device, "high"),
ExtraMeterSensor(coordinator, device, "total"),
ExtraMeterPowerSensor(coordinator, device, "usage"),
PhasePowerSensor(coordinator, device, 1),
PhaseVoltageSensor(coordinator, device, 1),
PhaseCurrentSensor(coordinator, device, 1),
PhasePowerSensor(coordinator, device, 2),
PhaseVoltageSensor(coordinator, device, 2),
PhaseCurrentSensor(coordinator, device, 2),
PhasePowerSensor(coordinator, device, 3),
PhaseVoltageSensor(coordinator, device, 3),
PhaseCurrentSensor(coordinator, device, 3),
YouLessSensor(coordinator, description, device)
for description in SENSOR_TYPES
]
)
class YoulessBaseSensor(
CoordinatorEntity[DataUpdateCoordinator[YoulessAPI]], SensorEntity
):
"""The base sensor for Youless."""
class YouLessSensor(YouLessEntity, SensorEntity):
"""Representation of a Sensor."""
entity_description: YouLessSensorEntityDescription
def __init__(
self,
coordinator: DataUpdateCoordinator[YoulessAPI],
coordinator: YouLessCoordinator,
description: YouLessSensorEntityDescription,
device: str,
device_group: str,
friendly_name: str,
sensor_id: str,
) -> None:
"""Create the sensor."""
super().__init__(coordinator)
self._attr_unique_id = f"{DOMAIN}_{device}_{sensor_id}"
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, f"{device}_{device_group}")},
manufacturer="YouLess",
model=self.coordinator.data.model,
name=friendly_name,
"""Initialize the sensor."""
super().__init__(
coordinator,
f"{device}_{description.device_group}",
description.device_group_name,
)
@property
def get_sensor(self) -> YoulessSensor | None:
"""Property to get the underlying sensor object."""
return None
self._attr_unique_id = f"{DOMAIN}_{device}_{description.key}"
self.entity_description = description
@property
def native_value(self) -> StateType:
"""Determine the state value, only if a sensor is initialized."""
if self.get_sensor is None:
return None
return self.get_sensor.value
@property
def available(self) -> bool:
"""Return a flag to indicate the sensor not being available."""
return super().available and self.get_sensor is not None
class WaterSensor(YoulessBaseSensor):
"""The Youless Water sensor."""
_attr_native_unit_of_measurement = UnitOfVolume.CUBIC_METERS
_attr_device_class = SensorDeviceClass.WATER
_attr_state_class = SensorStateClass.TOTAL_INCREASING
def __init__(
self, coordinator: DataUpdateCoordinator[YoulessAPI], device: str
) -> None:
"""Instantiate a Water sensor."""
super().__init__(coordinator, device, "water", "Water meter", "water")
self._attr_name = "Water usage"
self._attr_icon = "mdi:water"
@property
def get_sensor(self) -> YoulessSensor | None:
"""Get the sensor for providing the value."""
return self.coordinator.data.water_meter
class GasSensor(YoulessBaseSensor):
"""The Youless gas sensor."""
_attr_native_unit_of_measurement = UnitOfVolume.CUBIC_METERS
_attr_device_class = SensorDeviceClass.GAS
_attr_state_class = SensorStateClass.TOTAL_INCREASING
def __init__(
self, coordinator: DataUpdateCoordinator[YoulessAPI], device: str
) -> None:
"""Instantiate a gas sensor."""
super().__init__(coordinator, device, "gas", "Gas meter", "gas")
self._attr_name = "Gas usage"
self._attr_icon = "mdi:fire"
@property
def get_sensor(self) -> YoulessSensor | None:
"""Get the sensor for providing the value."""
return self.coordinator.data.gas_meter
class CurrentPowerSensor(YoulessBaseSensor):
"""The current power usage sensor."""
_attr_native_unit_of_measurement = UnitOfPower.WATT
_attr_device_class = SensorDeviceClass.POWER
_attr_state_class = SensorStateClass.MEASUREMENT
def __init__(
self, coordinator: DataUpdateCoordinator[YoulessAPI], device: str
) -> None:
"""Instantiate the usage meter."""
super().__init__(coordinator, device, "power", "Power usage", "usage")
self._device = device
self._attr_name = "Power Usage"
@property
def get_sensor(self) -> YoulessSensor | None:
"""Get the sensor for providing the value."""
return self.coordinator.data.current_power_usage
class DeliveryMeterSensor(YoulessBaseSensor):
"""The Youless delivery meter value sensor."""
_attr_native_unit_of_measurement = UnitOfEnergy.KILO_WATT_HOUR
_attr_device_class = SensorDeviceClass.ENERGY
_attr_state_class = SensorStateClass.TOTAL_INCREASING
def __init__(
self, coordinator: DataUpdateCoordinator[YoulessAPI], device: str, dev_type: str
) -> None:
"""Instantiate a delivery meter sensor."""
super().__init__(
coordinator, device, "delivery", "Energy delivery", f"delivery_{dev_type}"
)
self._type = dev_type
self._attr_name = f"Energy delivery {dev_type}"
@property
def get_sensor(self) -> YoulessSensor | None:
"""Get the sensor for providing the value."""
if self.coordinator.data.delivery_meter is None:
return None
return getattr(self.coordinator.data.delivery_meter, f"_{self._type}", None)
class EnergyMeterSensor(YoulessBaseSensor):
"""The Youless low meter value sensor."""
_attr_native_unit_of_measurement = UnitOfEnergy.KILO_WATT_HOUR
_attr_device_class = SensorDeviceClass.ENERGY
_attr_state_class = SensorStateClass.TOTAL_INCREASING
def __init__(
self,
coordinator: DataUpdateCoordinator[YoulessAPI],
device: str,
dev_type: str,
state_class: SensorStateClass,
) -> None:
"""Instantiate a energy meter sensor."""
super().__init__(
coordinator, device, "power", "Energy usage", f"power_{dev_type}"
)
self._device = device
self._type = dev_type
self._attr_name = f"Energy {dev_type}"
self._attr_state_class = state_class
@property
def get_sensor(self) -> YoulessSensor | None:
"""Get the sensor for providing the value."""
if self.coordinator.data.power_meter is None:
return None
return getattr(self.coordinator.data.power_meter, f"_{self._type}", None)
class PhasePowerSensor(YoulessBaseSensor):
"""The current power usage of a single phase."""
_attr_native_unit_of_measurement = UnitOfPower.WATT
_attr_device_class = SensorDeviceClass.POWER
_attr_state_class = SensorStateClass.MEASUREMENT
def __init__(
self, coordinator: DataUpdateCoordinator[YoulessAPI], device: str, phase: int
) -> None:
"""Initialize the power phase sensor."""
super().__init__(
coordinator, device, "power", "Energy usage", f"phase_{phase}_power"
)
self._attr_name = f"Phase {phase} power"
self._phase = phase
@property
def get_sensor(self) -> YoulessSensor | None:
"""Get the sensor value from the coordinator."""
phase_sensor = getattr(self.coordinator.data, f"phase{self._phase}", None)
if phase_sensor is None:
return None
return phase_sensor.power
class PhaseVoltageSensor(YoulessBaseSensor):
"""The current voltage of a single phase."""
_attr_native_unit_of_measurement = UnitOfElectricPotential.VOLT
_attr_device_class = SensorDeviceClass.VOLTAGE
_attr_state_class = SensorStateClass.MEASUREMENT
def __init__(
self, coordinator: DataUpdateCoordinator[YoulessAPI], device: str, phase: int
) -> None:
"""Initialize the voltage phase sensor."""
super().__init__(
coordinator, device, "power", "Energy usage", f"phase_{phase}_voltage"
)
self._attr_name = f"Phase {phase} voltage"
self._phase = phase
@property
def get_sensor(self) -> YoulessSensor | None:
"""Get the sensor value from the coordinator for phase voltage."""
phase_sensor = getattr(self.coordinator.data, f"phase{self._phase}", None)
if phase_sensor is None:
return None
return phase_sensor.voltage
class PhaseCurrentSensor(YoulessBaseSensor):
"""The current current of a single phase."""
_attr_native_unit_of_measurement = UnitOfElectricCurrent.AMPERE
_attr_device_class = SensorDeviceClass.CURRENT
_attr_state_class = SensorStateClass.MEASUREMENT
def __init__(
self, coordinator: DataUpdateCoordinator[YoulessAPI], device: str, phase: int
) -> None:
"""Initialize the current phase sensor."""
super().__init__(
coordinator, device, "power", "Energy usage", f"phase_{phase}_current"
)
self._attr_name = f"Phase {phase} current"
self._phase = phase
@property
def get_sensor(self) -> YoulessSensor | None:
"""Get the sensor value from the coordinator for phase current."""
phase_sensor = getattr(self.coordinator.data, f"phase{self._phase}", None)
if phase_sensor is None:
return None
return phase_sensor.current
class ExtraMeterSensor(YoulessBaseSensor):
"""The Youless extra meter value sensor (s0)."""
_attr_native_unit_of_measurement = UnitOfEnergy.KILO_WATT_HOUR
_attr_device_class = SensorDeviceClass.ENERGY
_attr_state_class = SensorStateClass.TOTAL_INCREASING
def __init__(
self, coordinator: DataUpdateCoordinator[YoulessAPI], device: str, dev_type: str
) -> None:
"""Instantiate an extra meter sensor."""
super().__init__(
coordinator, device, "extra", "Extra meter", f"extra_{dev_type}"
)
self._type = dev_type
self._attr_name = f"Extra {dev_type}"
@property
def get_sensor(self) -> YoulessSensor | None:
"""Get the sensor for providing the value."""
if self.coordinator.data.extra_meter is None:
return None
return getattr(self.coordinator.data.extra_meter, f"_{self._type}", None)
class ExtraMeterPowerSensor(YoulessBaseSensor):
"""The Youless extra meter power value sensor (s0)."""
_attr_native_unit_of_measurement = UnitOfPower.WATT
_attr_device_class = SensorDeviceClass.POWER
_attr_state_class = SensorStateClass.MEASUREMENT
def __init__(
self, coordinator: DataUpdateCoordinator[YoulessAPI], device: str, dev_type: str
) -> None:
"""Instantiate an extra meter power sensor."""
super().__init__(
coordinator, device, "extra", "Extra meter", f"extra_{dev_type}"
)
self._type = dev_type
self._attr_name = f"Extra {dev_type}"
@property
def get_sensor(self) -> YoulessSensor | None:
"""Get the sensor for providing the value."""
if self.coordinator.data.extra_meter is None:
return None
return getattr(self.coordinator.data.extra_meter, f"_{self._type}", None)
"""Return the state of the sensor."""
return self.entity_description.value_func(self.device)

View File

@ -24,7 +24,7 @@
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENERGY: 'energy'>,
'original_icon': None,
'original_icon': 'mdi:transmission-tower-import',
'original_name': 'Energy delivery high',
'platform': 'youless',
'previous_unique_id': None,
@ -39,6 +39,7 @@
'attributes': ReadOnlyDict({
'device_class': 'energy',
'friendly_name': 'Energy delivery high',
'icon': 'mdi:transmission-tower-import',
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}),
@ -75,7 +76,7 @@
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENERGY: 'energy'>,
'original_icon': None,
'original_icon': 'mdi:transmission-tower-import',
'original_name': 'Energy delivery low',
'platform': 'youless',
'previous_unique_id': None,
@ -90,6 +91,7 @@
'attributes': ReadOnlyDict({
'device_class': 'energy',
'friendly_name': 'Energy delivery low',
'icon': 'mdi:transmission-tower-import',
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}),
@ -126,7 +128,7 @@
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENERGY: 'energy'>,
'original_icon': None,
'original_icon': 'mdi:transmission-tower-export',
'original_name': 'Energy high',
'platform': 'youless',
'previous_unique_id': None,
@ -141,6 +143,7 @@
'attributes': ReadOnlyDict({
'device_class': 'energy',
'friendly_name': 'Energy high',
'icon': 'mdi:transmission-tower-export',
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}),
@ -177,7 +180,7 @@
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENERGY: 'energy'>,
'original_icon': None,
'original_icon': 'mdi:transmission-tower-export',
'original_name': 'Energy low',
'platform': 'youless',
'previous_unique_id': None,
@ -192,6 +195,7 @@
'attributes': ReadOnlyDict({
'device_class': 'energy',
'friendly_name': 'Energy low',
'icon': 'mdi:transmission-tower-export',
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}),
@ -228,7 +232,7 @@
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENERGY: 'energy'>,
'original_icon': None,
'original_icon': 'mdi:transmission-tower-export',
'original_name': 'Energy total',
'platform': 'youless',
'previous_unique_id': None,
@ -243,6 +247,7 @@
'attributes': ReadOnlyDict({
'device_class': 'energy',
'friendly_name': 'Energy total',
'icon': 'mdi:transmission-tower-export',
'state_class': <SensorStateClass.TOTAL: 'total'>,
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}),
@ -279,7 +284,7 @@
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENERGY: 'energy'>,
'original_icon': None,
'original_icon': 'mdi:meter-electric',
'original_name': 'Extra total',
'platform': 'youless',
'previous_unique_id': None,
@ -294,6 +299,7 @@
'attributes': ReadOnlyDict({
'device_class': 'energy',
'friendly_name': 'Extra total',
'icon': 'mdi:meter-electric',
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}),
@ -330,7 +336,7 @@
'options': dict({
}),
'original_device_class': <SensorDeviceClass.POWER: 'power'>,
'original_icon': None,
'original_icon': 'mdi:lightning-bolt',
'original_name': 'Extra usage',
'platform': 'youless',
'previous_unique_id': None,
@ -345,6 +351,7 @@
'attributes': ReadOnlyDict({
'device_class': 'power',
'friendly_name': 'Extra usage',
'icon': 'mdi:lightning-bolt',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
}),
@ -456,7 +463,7 @@
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unavailable',
'state': 'unknown',
})
# ---
# name: test_sensors[sensor.phase_1_power-entry]
@ -507,7 +514,7 @@
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unavailable',
'state': 'unknown',
})
# ---
# name: test_sensors[sensor.phase_1_voltage-entry]
@ -558,7 +565,7 @@
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unavailable',
'state': 'unknown',
})
# ---
# name: test_sensors[sensor.phase_2_current-entry]
@ -609,7 +616,7 @@
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unavailable',
'state': 'unknown',
})
# ---
# name: test_sensors[sensor.phase_2_power-entry]
@ -660,7 +667,7 @@
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unavailable',
'state': 'unknown',
})
# ---
# name: test_sensors[sensor.phase_2_voltage-entry]
@ -711,7 +718,7 @@
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unavailable',
'state': 'unknown',
})
# ---
# name: test_sensors[sensor.phase_3_current-entry]
@ -762,7 +769,7 @@
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unavailable',
'state': 'unknown',
})
# ---
# name: test_sensors[sensor.phase_3_power-entry]
@ -813,7 +820,7 @@
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unavailable',
'state': 'unknown',
})
# ---
# name: test_sensors[sensor.phase_3_voltage-entry]
@ -864,7 +871,7 @@
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unavailable',
'state': 'unknown',
})
# ---
# name: test_sensors[sensor.power_usage-entry]
@ -892,7 +899,7 @@
'options': dict({
}),
'original_device_class': <SensorDeviceClass.POWER: 'power'>,
'original_icon': None,
'original_icon': 'mdi:meter-electric',
'original_name': 'Power Usage',
'platform': 'youless',
'previous_unique_id': None,
@ -907,6 +914,7 @@
'attributes': ReadOnlyDict({
'device_class': 'power',
'friendly_name': 'Power Usage',
'icon': 'mdi:meter-electric',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
}),