22
33from __future__ import annotations
44
5+ from dataclasses import dataclass
56import logging
67from typing import TYPE_CHECKING
78
1011 SensorEntity ,
1112 SensorEntityDescription ,
1213)
13- from homeassistant .const import EntityCategory , UnitOfElectricPotential , UnitOfTime
14+ from homeassistant .const import (
15+ CONCENTRATION_PARTS_PER_MILLION ,
16+ EntityCategory ,
17+ UnitOfElectricPotential ,
18+ UnitOfTime ,
19+ )
1420from homeassistant .core import HomeAssistant
1521from homeassistant .helpers .entity_platform import AddConfigEntryEntitiesCallback
1622
1723from . import PooldoseConfigEntry
24+ from .const import UNIT_MAPPING
1825from .entity import PooldoseEntity
1926
2027_LOGGER = logging .getLogger (__name__ )
2128
22- SENSOR_DESCRIPTIONS : tuple [SensorEntityDescription , ...] = (
23- SensorEntityDescription (
29+
30+ @dataclass (frozen = True , kw_only = True )
31+ class PooldoseSensorEntityDescription (SensorEntityDescription ):
32+ """Describes PoolDose sensor entity."""
33+
34+ use_dynamic_unit : bool = False
35+
36+
37+ SENSOR_DESCRIPTIONS : tuple [PooldoseSensorEntityDescription , ...] = (
38+ PooldoseSensorEntityDescription (
2439 key = "temperature" ,
2540 device_class = SensorDeviceClass .TEMPERATURE ,
26- # Unit dynamically determined via API
41+ use_dynamic_unit = True ,
2742 ),
28- SensorEntityDescription (key = "ph" , device_class = SensorDeviceClass .PH ),
29- SensorEntityDescription (
43+ PooldoseSensorEntityDescription (key = "ph" , device_class = SensorDeviceClass .PH ),
44+ PooldoseSensorEntityDescription (
3045 key = "orp" ,
3146 translation_key = "orp" ,
3247 device_class = SensorDeviceClass .VOLTAGE ,
3348 native_unit_of_measurement = UnitOfElectricPotential .MILLIVOLT ,
3449 ),
35- SensorEntityDescription (
50+ PooldoseSensorEntityDescription (
51+ key = "cl" ,
52+ translation_key = "cl" ,
53+ native_unit_of_measurement = CONCENTRATION_PARTS_PER_MILLION ,
54+ ),
55+ PooldoseSensorEntityDescription (
56+ key = "flow_rate" ,
57+ translation_key = "flow_rate" ,
58+ device_class = SensorDeviceClass .VOLUME_FLOW_RATE ,
59+ use_dynamic_unit = True ,
60+ ),
61+ PooldoseSensorEntityDescription (
3662 key = "ph_type_dosing" ,
3763 translation_key = "ph_type_dosing" ,
3864 entity_category = EntityCategory .DIAGNOSTIC ,
3965 device_class = SensorDeviceClass .ENUM ,
4066 options = ["alcalyne" , "acid" ],
4167 ),
42- SensorEntityDescription (
68+ PooldoseSensorEntityDescription (
4369 key = "peristaltic_ph_dosing" ,
4470 translation_key = "peristaltic_ph_dosing" ,
4571 entity_category = EntityCategory .DIAGNOSTIC ,
4672 entity_registry_enabled_default = False ,
4773 device_class = SensorDeviceClass .ENUM ,
4874 options = ["proportional" , "on_off" , "timed" ],
4975 ),
50- SensorEntityDescription (
76+ PooldoseSensorEntityDescription (
5177 key = "ofa_ph_time" ,
5278 translation_key = "ofa_ph_time" ,
5379 entity_category = EntityCategory .DIAGNOSTIC ,
5480 device_class = SensorDeviceClass .DURATION ,
5581 entity_registry_enabled_default = False ,
5682 native_unit_of_measurement = UnitOfTime .MINUTES ,
5783 ),
58- SensorEntityDescription (
84+ PooldoseSensorEntityDescription (
5985 key = "orp_type_dosing" ,
6086 translation_key = "orp_type_dosing" ,
6187 entity_category = EntityCategory .DIAGNOSTIC ,
6288 entity_registry_enabled_default = False ,
6389 device_class = SensorDeviceClass .ENUM ,
6490 options = ["low" , "high" ],
6591 ),
66- SensorEntityDescription (
92+ PooldoseSensorEntityDescription (
6793 key = "peristaltic_orp_dosing" ,
6894 translation_key = "peristaltic_orp_dosing" ,
6995 entity_category = EntityCategory .DIAGNOSTIC ,
7096 entity_registry_enabled_default = False ,
7197 device_class = SensorDeviceClass .ENUM ,
7298 options = ["off" , "proportional" , "on_off" , "timed" ],
7399 ),
74- SensorEntityDescription (
100+ PooldoseSensorEntityDescription (
101+ key = "cl_type_dosing" ,
102+ translation_key = "cl_type_dosing" ,
103+ entity_category = EntityCategory .DIAGNOSTIC ,
104+ entity_registry_enabled_default = False ,
105+ device_class = SensorDeviceClass .ENUM ,
106+ options = ["low" , "high" ],
107+ ),
108+ PooldoseSensorEntityDescription (
109+ key = "peristaltic_cl_dosing" ,
110+ translation_key = "peristaltic_cl_dosing" ,
111+ entity_category = EntityCategory .DIAGNOSTIC ,
112+ entity_registry_enabled_default = False ,
113+ device_class = SensorDeviceClass .ENUM ,
114+ options = ["off" , "proportional" , "on_off" , "timed" ],
115+ ),
116+ PooldoseSensorEntityDescription (
75117 key = "ofa_orp_time" ,
76118 translation_key = "ofa_orp_time" ,
77119 device_class = SensorDeviceClass .DURATION ,
78120 entity_category = EntityCategory .DIAGNOSTIC ,
79121 entity_registry_enabled_default = False ,
80122 native_unit_of_measurement = UnitOfTime .MINUTES ,
81123 ),
82- SensorEntityDescription (
124+ PooldoseSensorEntityDescription (
83125 key = "ph_calibration_type" ,
84126 translation_key = "ph_calibration_type" ,
85127 entity_category = EntityCategory .DIAGNOSTIC ,
86128 entity_registry_enabled_default = False ,
87129 device_class = SensorDeviceClass .ENUM ,
88130 options = ["off" , "reference" , "1_point" , "2_points" ],
89131 ),
90- SensorEntityDescription (
132+ PooldoseSensorEntityDescription (
91133 key = "ph_calibration_offset" ,
92134 translation_key = "ph_calibration_offset" ,
93135 entity_category = EntityCategory .DIAGNOSTIC ,
96138 entity_registry_enabled_default = False ,
97139 native_unit_of_measurement = UnitOfElectricPotential .MILLIVOLT ,
98140 ),
99- SensorEntityDescription (
141+ PooldoseSensorEntityDescription (
100142 key = "ph_calibration_slope" ,
101143 translation_key = "ph_calibration_slope" ,
102144 entity_category = EntityCategory .DIAGNOSTIC ,
105147 entity_registry_enabled_default = False ,
106148 native_unit_of_measurement = UnitOfElectricPotential .MILLIVOLT ,
107149 ),
108- SensorEntityDescription (
150+ PooldoseSensorEntityDescription (
109151 key = "orp_calibration_type" ,
110152 translation_key = "orp_calibration_type" ,
111153 entity_category = EntityCategory .DIAGNOSTIC ,
112154 entity_registry_enabled_default = False ,
113155 device_class = SensorDeviceClass .ENUM ,
114156 options = ["off" , "reference" , "1_point" ],
115157 ),
116- SensorEntityDescription (
158+ PooldoseSensorEntityDescription (
117159 key = "orp_calibration_offset" ,
118160 translation_key = "orp_calibration_offset" ,
119161 entity_category = EntityCategory .DIAGNOSTIC ,
122164 entity_registry_enabled_default = False ,
123165 native_unit_of_measurement = UnitOfElectricPotential .MILLIVOLT ,
124166 ),
125- SensorEntityDescription (
167+ PooldoseSensorEntityDescription (
126168 key = "orp_calibration_slope" ,
127169 translation_key = "orp_calibration_slope" ,
128170 entity_category = EntityCategory .DIAGNOSTIC ,
@@ -163,6 +205,8 @@ async def async_setup_entry(
163205class PooldoseSensor (PooldoseEntity , SensorEntity ):
164206 """Sensor entity for the Seko PoolDose Python API."""
165207
208+ entity_description : PooldoseSensorEntityDescription
209+
166210 @property
167211 def native_value (self ) -> float | int | str | None :
168212 """Return the current value of the sensor."""
@@ -175,9 +219,12 @@ def native_value(self) -> float | int | str | None:
175219 def native_unit_of_measurement (self ) -> str | None :
176220 """Return the unit of measurement."""
177221 if (
178- self .entity_description .key == "temperature"
222+ self .entity_description .use_dynamic_unit
179223 and (data := self .get_data ()) is not None
224+ and (device_unit := data .get ("unit" ))
180225 ):
181- return data ["unit" ] # °C or °F
226+ # Map device unit to Home Assistant unit, return None if unknown
227+ return UNIT_MAPPING .get (device_unit )
182228
229+ # Fall back to static unit from entity description
183230 return super ().native_unit_of_measurement
0 commit comments