mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Restructure the youless integration internals (#135842)
This commit is contained in:
parent
e57dafee6c
commit
d6f6961674
@ -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
|
||||
|
25
homeassistant/components/youless/coordinator.py
Normal file
25
homeassistant/components/youless/coordinator.py
Normal 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)
|
25
homeassistant/components/youless/entity.py
Normal file
25
homeassistant/components/youless/entity.py
Normal 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,
|
||||
)
|
@ -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)
|
||||
|
@ -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'>,
|
||||
}),
|
||||
|
Loading…
x
Reference in New Issue
Block a user