Skip to content

Commit 90dc3a8

Browse files
authored
Pooldose: add number platform (home-assistant#157787)
1 parent 5112742 commit 90dc3a8

File tree

7 files changed

+888
-1
lines changed

7 files changed

+888
-1
lines changed

homeassistant/components/pooldose/__init__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@
1717

1818
_LOGGER = logging.getLogger(__name__)
1919

20-
PLATFORMS: list[Platform] = [Platform.BINARY_SENSOR, Platform.SENSOR, Platform.SWITCH]
20+
PLATFORMS: list[Platform] = [
21+
Platform.BINARY_SENSOR,
22+
Platform.NUMBER,
23+
Platform.SENSOR,
24+
Platform.SWITCH,
25+
]
2126

2227

2328
async def async_migrate_entry(hass: HomeAssistant, entry: PooldoseConfigEntry) -> bool:

homeassistant/components/pooldose/icons.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,35 @@
6868
}
6969
}
7070
},
71+
"number": {
72+
"cl_target": {
73+
"default": "mdi:pool"
74+
},
75+
"ofa_cl_lower": {
76+
"default": "mdi:arrow-down-bold"
77+
},
78+
"ofa_cl_upper": {
79+
"default": "mdi:arrow-up-bold"
80+
},
81+
"ofa_orp_lower": {
82+
"default": "mdi:arrow-down-bold"
83+
},
84+
"ofa_orp_upper": {
85+
"default": "mdi:arrow-up-bold"
86+
},
87+
"ofa_ph_lower": {
88+
"default": "mdi:arrow-down-bold"
89+
},
90+
"ofa_ph_upper": {
91+
"default": "mdi:arrow-up-bold"
92+
},
93+
"orp_target": {
94+
"default": "mdi:water-check"
95+
},
96+
"ph_target": {
97+
"default": "mdi:ph"
98+
}
99+
},
71100
"sensor": {
72101
"cl": {
73102
"default": "mdi:pool"
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
"""Number entities for the Seko PoolDose integration."""
2+
3+
from __future__ import annotations
4+
5+
import logging
6+
from typing import TYPE_CHECKING, Any, cast
7+
8+
from homeassistant.components.number import (
9+
NumberDeviceClass,
10+
NumberEntity,
11+
NumberEntityDescription,
12+
)
13+
from homeassistant.const import (
14+
CONCENTRATION_PARTS_PER_MILLION,
15+
EntityCategory,
16+
UnitOfElectricPotential,
17+
)
18+
from homeassistant.core import HomeAssistant
19+
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
20+
21+
from . import PooldoseConfigEntry
22+
from .entity import PooldoseEntity
23+
24+
if TYPE_CHECKING:
25+
from .coordinator import PooldoseCoordinator
26+
27+
_LOGGER = logging.getLogger(__name__)
28+
29+
30+
NUMBER_DESCRIPTIONS: tuple[NumberEntityDescription, ...] = (
31+
NumberEntityDescription(
32+
key="ph_target",
33+
translation_key="ph_target",
34+
entity_category=EntityCategory.CONFIG,
35+
device_class=NumberDeviceClass.PH,
36+
),
37+
NumberEntityDescription(
38+
key="orp_target",
39+
translation_key="orp_target",
40+
entity_category=EntityCategory.CONFIG,
41+
device_class=NumberDeviceClass.VOLTAGE,
42+
native_unit_of_measurement=UnitOfElectricPotential.MILLIVOLT,
43+
),
44+
NumberEntityDescription(
45+
key="cl_target",
46+
translation_key="cl_target",
47+
entity_category=EntityCategory.CONFIG,
48+
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
49+
),
50+
NumberEntityDescription(
51+
key="ofa_ph_lower",
52+
translation_key="ofa_ph_lower",
53+
entity_category=EntityCategory.CONFIG,
54+
device_class=NumberDeviceClass.PH,
55+
),
56+
NumberEntityDescription(
57+
key="ofa_ph_upper",
58+
translation_key="ofa_ph_upper",
59+
entity_category=EntityCategory.CONFIG,
60+
device_class=NumberDeviceClass.PH,
61+
),
62+
NumberEntityDescription(
63+
key="ofa_orp_lower",
64+
translation_key="ofa_orp_lower",
65+
entity_category=EntityCategory.CONFIG,
66+
device_class=NumberDeviceClass.VOLTAGE,
67+
native_unit_of_measurement=UnitOfElectricPotential.MILLIVOLT,
68+
),
69+
NumberEntityDescription(
70+
key="ofa_orp_upper",
71+
translation_key="ofa_orp_upper",
72+
entity_category=EntityCategory.CONFIG,
73+
device_class=NumberDeviceClass.VOLTAGE,
74+
native_unit_of_measurement=UnitOfElectricPotential.MILLIVOLT,
75+
),
76+
NumberEntityDescription(
77+
key="ofa_cl_lower",
78+
translation_key="ofa_cl_lower",
79+
entity_category=EntityCategory.CONFIG,
80+
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
81+
),
82+
NumberEntityDescription(
83+
key="ofa_cl_upper",
84+
translation_key="ofa_cl_upper",
85+
entity_category=EntityCategory.CONFIG,
86+
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
87+
),
88+
)
89+
90+
91+
async def async_setup_entry(
92+
hass: HomeAssistant,
93+
config_entry: PooldoseConfigEntry,
94+
async_add_entities: AddConfigEntryEntitiesCallback,
95+
) -> None:
96+
"""Set up PoolDose number entities from a config entry."""
97+
if TYPE_CHECKING:
98+
assert config_entry.unique_id is not None
99+
100+
coordinator = config_entry.runtime_data
101+
number_data = coordinator.data.get("number", {})
102+
serial_number = config_entry.unique_id
103+
104+
async_add_entities(
105+
PooldoseNumber(coordinator, serial_number, coordinator.device_info, description)
106+
for description in NUMBER_DESCRIPTIONS
107+
if description.key in number_data
108+
)
109+
110+
111+
class PooldoseNumber(PooldoseEntity, NumberEntity):
112+
"""Number entity for the Seko PoolDose Python API."""
113+
114+
def __init__(
115+
self,
116+
coordinator: PooldoseCoordinator,
117+
serial_number: str,
118+
device_info: Any,
119+
description: NumberEntityDescription,
120+
) -> None:
121+
"""Initialize the number."""
122+
super().__init__(coordinator, serial_number, device_info, description, "number")
123+
self._async_update_attrs()
124+
125+
def _handle_coordinator_update(self) -> None:
126+
"""Handle updated data from the coordinator."""
127+
self._async_update_attrs()
128+
super()._handle_coordinator_update()
129+
130+
def _async_update_attrs(self) -> None:
131+
"""Update number attributes."""
132+
data = cast(dict, self.get_data())
133+
self._attr_native_value = data["value"]
134+
self._attr_native_min_value = data["min"]
135+
self._attr_native_max_value = data["max"]
136+
self._attr_native_step = data["step"]
137+
138+
async def async_set_native_value(self, value: float) -> None:
139+
"""Set new value."""
140+
await self.coordinator.client.set_number(self.entity_description.key, value)
141+
self._attr_native_value = value
142+
self.async_write_ha_state()

homeassistant/components/pooldose/strings.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,35 @@
6868
"name": "Auxiliary relay 3 status"
6969
}
7070
},
71+
"number": {
72+
"cl_target": {
73+
"name": "Chlorine target"
74+
},
75+
"ofa_cl_lower": {
76+
"name": "Chlorine overfeed alarm lower limit"
77+
},
78+
"ofa_cl_upper": {
79+
"name": "Chlorine overfeed alarm upper limit"
80+
},
81+
"ofa_orp_lower": {
82+
"name": "ORP overfeed alarm lower limit"
83+
},
84+
"ofa_orp_upper": {
85+
"name": "ORP overfeed alarm upper limit"
86+
},
87+
"ofa_ph_lower": {
88+
"name": "pH overfeed alarm lower limit"
89+
},
90+
"ofa_ph_upper": {
91+
"name": "pH overfeed alarm upper limit"
92+
},
93+
"orp_target": {
94+
"name": "ORP target"
95+
},
96+
"ph_target": {
97+
"name": "pH target"
98+
}
99+
},
71100
"sensor": {
72101
"cl": {
73102
"name": "Chlorine"

tests/components/pooldose/fixtures/instantvalues.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,48 @@
141141
"min": 0,
142142
"max": 65535,
143143
"step": 0.01
144+
},
145+
"ofa_ph_lower": {
146+
"value": 6,
147+
"unit": null,
148+
"min": 0,
149+
"max": 14,
150+
"step": 0.1
151+
},
152+
"ofa_ph_upper": {
153+
"value": 8,
154+
"unit": null,
155+
"min": 0,
156+
"max": 14,
157+
"step": 0.1
158+
},
159+
"ofa_orp_lower": {
160+
"value": 600,
161+
"unit": "mV",
162+
"min": 0,
163+
"max": 1000,
164+
"step": 1
165+
},
166+
"ofa_orp_upper": {
167+
"value": 800,
168+
"unit": "mV",
169+
"min": 0,
170+
"max": 1000,
171+
"step": 1
172+
},
173+
"ofa_cl_lower": {
174+
"value": 0.2,
175+
"unit": "ppm",
176+
"min": 0,
177+
"max": 10,
178+
"step": 0.1
179+
},
180+
"ofa_cl_upper": {
181+
"value": 0.9,
182+
"unit": "ppm",
183+
"min": 0,
184+
"max": 10,
185+
"step": 0.1
144186
}
145187
},
146188
"switch": {

0 commit comments

Comments
 (0)