Skip to content

Commit abb52bc

Browse files
lmaertinCopilot
andauthored
Add more sensors to Pooldose (home-assistant#156002)
Co-authored-by: Copilot <[email protected]>
1 parent d2d6889 commit abb52bc

File tree

7 files changed

+365
-67
lines changed

7 files changed

+365
-67
lines changed

homeassistant/components/pooldose/const.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,17 @@
22

33
from __future__ import annotations
44

5+
from homeassistant.const import UnitOfTemperature, UnitOfVolumeFlowRate
6+
57
DOMAIN = "pooldose"
68
MANUFACTURER = "SEKO"
9+
10+
# Mapping of device units to Home Assistant units
11+
UNIT_MAPPING: dict[str, str] = {
12+
# Temperature units
13+
"°C": UnitOfTemperature.CELSIUS,
14+
"°F": UnitOfTemperature.FAHRENHEIT,
15+
# Volume flow rate units
16+
"m3/h": UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
17+
"L/s": UnitOfVolumeFlowRate.LITERS_PER_SECOND,
18+
}

homeassistant/components/pooldose/icons.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
{
22
"entity": {
33
"sensor": {
4+
"cl": {
5+
"default": "mdi:pool"
6+
},
7+
"cl_type_dosing": {
8+
"default": "mdi:flask"
9+
},
10+
"flow_rate": {
11+
"default": "mdi:pipe-valve"
12+
},
413
"ofa_orp_time": {
514
"default": "mdi:clock"
615
},
@@ -22,6 +31,9 @@
2231
"orp_type_dosing": {
2332
"default": "mdi:flask"
2433
},
34+
"peristaltic_cl_dosing": {
35+
"default": "mdi:pump"
36+
},
2537
"peristaltic_orp_dosing": {
2638
"default": "mdi:pump"
2739
},

homeassistant/components/pooldose/sensor.py

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import annotations
44

5+
from dataclasses import dataclass
56
import logging
67
from typing import TYPE_CHECKING
78

@@ -10,84 +11,125 @@
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+
)
1420
from homeassistant.core import HomeAssistant
1521
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
1622

1723
from . import PooldoseConfigEntry
24+
from .const import UNIT_MAPPING
1825
from .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,
@@ -96,7 +138,7 @@
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,
@@ -105,15 +147,15 @@
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,
@@ -122,7 +164,7 @@
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(
163205
class 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

homeassistant/components/pooldose/strings.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,19 @@
3434
},
3535
"entity": {
3636
"sensor": {
37+
"cl": {
38+
"name": "Chlorine"
39+
},
40+
"cl_type_dosing": {
41+
"name": "Chlorine dosing type",
42+
"state": {
43+
"high": "[%key:common::state::high%]",
44+
"low": "[%key:common::state::low%]"
45+
}
46+
},
47+
"flow_rate": {
48+
"name": "Flow rate"
49+
},
3750
"ofa_orp_time": {
3851
"name": "ORP overfeed alert time"
3952
},
@@ -64,6 +77,15 @@
6477
"low": "[%key:common::state::low%]"
6578
}
6679
},
80+
"peristaltic_cl_dosing": {
81+
"name": "Chlorine peristaltic dosing",
82+
"state": {
83+
"off": "[%key:common::state::off%]",
84+
"on_off": "[%key:component::pooldose::entity::sensor::peristaltic_ph_dosing::state::on_off%]",
85+
"proportional": "[%key:component::pooldose::entity::sensor::peristaltic_ph_dosing::state::proportional%]",
86+
"timed": "[%key:component::pooldose::entity::sensor::peristaltic_ph_dosing::state::timed%]"
87+
}
88+
},
6789
"peristaltic_orp_dosing": {
6890
"name": "ORP peristaltic dosing",
6991
"state": {

tests/components/pooldose/fixtures/instantvalues.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@
4040
"value": "proportional",
4141
"unit": null
4242
},
43+
"cl_type_dosing": {
44+
"value": "low",
45+
"unit": null
46+
},
47+
"peristaltic_cl_dosing": {
48+
"value": "off",
49+
"unit": null
50+
},
4351
"ofa_orp_time": {
4452
"value": 0,
4553
"unit": "min"

0 commit comments

Comments
 (0)