mirror of
https://github.com/home-assistant/core.git
synced 2025-12-06 07:58:08 +00:00
231 lines
7.9 KiB
Python
231 lines
7.9 KiB
Python
"""Sensors for the Seko PoolDose integration."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
import logging
|
|
from typing import TYPE_CHECKING
|
|
|
|
from homeassistant.components.sensor import (
|
|
SensorDeviceClass,
|
|
SensorEntity,
|
|
SensorEntityDescription,
|
|
)
|
|
from homeassistant.const import (
|
|
CONCENTRATION_PARTS_PER_MILLION,
|
|
EntityCategory,
|
|
UnitOfElectricPotential,
|
|
UnitOfTime,
|
|
)
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|
|
|
from . import PooldoseConfigEntry
|
|
from .const import UNIT_MAPPING
|
|
from .entity import PooldoseEntity
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
@dataclass(frozen=True, kw_only=True)
|
|
class PooldoseSensorEntityDescription(SensorEntityDescription):
|
|
"""Describes PoolDose sensor entity."""
|
|
|
|
use_dynamic_unit: bool = False
|
|
|
|
|
|
SENSOR_DESCRIPTIONS: tuple[PooldoseSensorEntityDescription, ...] = (
|
|
PooldoseSensorEntityDescription(
|
|
key="temperature",
|
|
device_class=SensorDeviceClass.TEMPERATURE,
|
|
use_dynamic_unit=True,
|
|
),
|
|
PooldoseSensorEntityDescription(key="ph", device_class=SensorDeviceClass.PH),
|
|
PooldoseSensorEntityDescription(
|
|
key="orp",
|
|
translation_key="orp",
|
|
device_class=SensorDeviceClass.VOLTAGE,
|
|
native_unit_of_measurement=UnitOfElectricPotential.MILLIVOLT,
|
|
),
|
|
PooldoseSensorEntityDescription(
|
|
key="cl",
|
|
translation_key="cl",
|
|
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
|
),
|
|
PooldoseSensorEntityDescription(
|
|
key="flow_rate",
|
|
translation_key="flow_rate",
|
|
device_class=SensorDeviceClass.VOLUME_FLOW_RATE,
|
|
use_dynamic_unit=True,
|
|
),
|
|
PooldoseSensorEntityDescription(
|
|
key="ph_type_dosing",
|
|
translation_key="ph_type_dosing",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
device_class=SensorDeviceClass.ENUM,
|
|
options=["alcalyne", "acid"],
|
|
),
|
|
PooldoseSensorEntityDescription(
|
|
key="peristaltic_ph_dosing",
|
|
translation_key="peristaltic_ph_dosing",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
entity_registry_enabled_default=False,
|
|
device_class=SensorDeviceClass.ENUM,
|
|
options=["proportional", "on_off", "timed"],
|
|
),
|
|
PooldoseSensorEntityDescription(
|
|
key="ofa_ph_time",
|
|
translation_key="ofa_ph_time",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
device_class=SensorDeviceClass.DURATION,
|
|
entity_registry_enabled_default=False,
|
|
native_unit_of_measurement=UnitOfTime.MINUTES,
|
|
),
|
|
PooldoseSensorEntityDescription(
|
|
key="orp_type_dosing",
|
|
translation_key="orp_type_dosing",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
entity_registry_enabled_default=False,
|
|
device_class=SensorDeviceClass.ENUM,
|
|
options=["low", "high"],
|
|
),
|
|
PooldoseSensorEntityDescription(
|
|
key="peristaltic_orp_dosing",
|
|
translation_key="peristaltic_orp_dosing",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
entity_registry_enabled_default=False,
|
|
device_class=SensorDeviceClass.ENUM,
|
|
options=["off", "proportional", "on_off", "timed"],
|
|
),
|
|
PooldoseSensorEntityDescription(
|
|
key="cl_type_dosing",
|
|
translation_key="cl_type_dosing",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
entity_registry_enabled_default=False,
|
|
device_class=SensorDeviceClass.ENUM,
|
|
options=["low", "high"],
|
|
),
|
|
PooldoseSensorEntityDescription(
|
|
key="peristaltic_cl_dosing",
|
|
translation_key="peristaltic_cl_dosing",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
entity_registry_enabled_default=False,
|
|
device_class=SensorDeviceClass.ENUM,
|
|
options=["off", "proportional", "on_off", "timed"],
|
|
),
|
|
PooldoseSensorEntityDescription(
|
|
key="ofa_orp_time",
|
|
translation_key="ofa_orp_time",
|
|
device_class=SensorDeviceClass.DURATION,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
entity_registry_enabled_default=False,
|
|
native_unit_of_measurement=UnitOfTime.MINUTES,
|
|
),
|
|
PooldoseSensorEntityDescription(
|
|
key="ph_calibration_type",
|
|
translation_key="ph_calibration_type",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
entity_registry_enabled_default=False,
|
|
device_class=SensorDeviceClass.ENUM,
|
|
options=["off", "reference", "1_point", "2_points"],
|
|
),
|
|
PooldoseSensorEntityDescription(
|
|
key="ph_calibration_offset",
|
|
translation_key="ph_calibration_offset",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
device_class=SensorDeviceClass.VOLTAGE,
|
|
suggested_display_precision=2,
|
|
entity_registry_enabled_default=False,
|
|
native_unit_of_measurement=UnitOfElectricPotential.MILLIVOLT,
|
|
),
|
|
PooldoseSensorEntityDescription(
|
|
key="ph_calibration_slope",
|
|
translation_key="ph_calibration_slope",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
device_class=SensorDeviceClass.VOLTAGE,
|
|
suggested_display_precision=2,
|
|
entity_registry_enabled_default=False,
|
|
native_unit_of_measurement=UnitOfElectricPotential.MILLIVOLT,
|
|
),
|
|
PooldoseSensorEntityDescription(
|
|
key="orp_calibration_type",
|
|
translation_key="orp_calibration_type",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
entity_registry_enabled_default=False,
|
|
device_class=SensorDeviceClass.ENUM,
|
|
options=["off", "reference", "1_point"],
|
|
),
|
|
PooldoseSensorEntityDescription(
|
|
key="orp_calibration_offset",
|
|
translation_key="orp_calibration_offset",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
device_class=SensorDeviceClass.VOLTAGE,
|
|
suggested_display_precision=2,
|
|
entity_registry_enabled_default=False,
|
|
native_unit_of_measurement=UnitOfElectricPotential.MILLIVOLT,
|
|
),
|
|
PooldoseSensorEntityDescription(
|
|
key="orp_calibration_slope",
|
|
translation_key="orp_calibration_slope",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
device_class=SensorDeviceClass.VOLTAGE,
|
|
suggested_display_precision=2,
|
|
entity_registry_enabled_default=False,
|
|
native_unit_of_measurement=UnitOfElectricPotential.MILLIVOLT,
|
|
),
|
|
)
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
config_entry: PooldoseConfigEntry,
|
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
|
) -> None:
|
|
"""Set up PoolDose sensor entities from a config entry."""
|
|
if TYPE_CHECKING:
|
|
assert config_entry.unique_id is not None
|
|
|
|
coordinator = config_entry.runtime_data
|
|
sensor_data = coordinator.data["sensor"]
|
|
serial_number = config_entry.unique_id
|
|
|
|
async_add_entities(
|
|
PooldoseSensor(
|
|
coordinator,
|
|
serial_number,
|
|
coordinator.device_info,
|
|
description,
|
|
"sensor",
|
|
)
|
|
for description in SENSOR_DESCRIPTIONS
|
|
if description.key in sensor_data
|
|
)
|
|
|
|
|
|
class PooldoseSensor(PooldoseEntity, SensorEntity):
|
|
"""Sensor entity for the Seko PoolDose Python API."""
|
|
|
|
entity_description: PooldoseSensorEntityDescription
|
|
|
|
@property
|
|
def native_value(self) -> float | int | str | None:
|
|
"""Return the current value of the sensor."""
|
|
data = self.get_data()
|
|
if data is not None:
|
|
return data["value"]
|
|
return None
|
|
|
|
@property
|
|
def native_unit_of_measurement(self) -> str | None:
|
|
"""Return the unit of measurement."""
|
|
if (
|
|
self.entity_description.use_dynamic_unit
|
|
and (data := self.get_data()) is not None
|
|
and (device_unit := data.get("unit"))
|
|
):
|
|
# Map device unit to Home Assistant unit, return None if unknown
|
|
return UNIT_MAPPING.get(device_unit)
|
|
|
|
# Fall back to static unit from entity description
|
|
return super().native_unit_of_measurement
|