Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion homeassistant/components/pooldose/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@

_LOGGER = logging.getLogger(__name__)

PLATFORMS: list[Platform] = [Platform.BINARY_SENSOR, Platform.SENSOR, Platform.SWITCH]
PLATFORMS: list[Platform] = [
Platform.BINARY_SENSOR,
Platform.NUMBER,
Platform.SENSOR,
Platform.SWITCH,
]


async def async_migrate_entry(hass: HomeAssistant, entry: PooldoseConfigEntry) -> bool:
Expand Down
29 changes: 29 additions & 0 deletions homeassistant/components/pooldose/icons.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,35 @@
}
}
},
"number": {
"cl_target": {
"default": "mdi:pool"
},
"ofa_cl_lower": {
"default": "mdi:arrow-down-bold"
},
"ofa_cl_upper": {
"default": "mdi:arrow-up-bold"
},
"ofa_orp_lower": {
"default": "mdi:arrow-down-bold"
},
"ofa_orp_upper": {
"default": "mdi:arrow-up-bold"
},
"ofa_ph_lower": {
"default": "mdi:arrow-down-bold"
},
"ofa_ph_upper": {
"default": "mdi:arrow-up-bold"
},
"orp_target": {
"default": "mdi:water-check"
},
"ph_target": {
"default": "mdi:ph"
}
},
"sensor": {
"cl": {
"default": "mdi:pool"
Expand Down
142 changes: 142 additions & 0 deletions homeassistant/components/pooldose/number.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
"""Number entities for the Seko PoolDose integration."""

from __future__ import annotations

import logging
from typing import TYPE_CHECKING, Any, cast

from homeassistant.components.number import (
NumberDeviceClass,
NumberEntity,
NumberEntityDescription,
)
from homeassistant.const import (
CONCENTRATION_PARTS_PER_MILLION,
EntityCategory,
UnitOfElectricPotential,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback

from . import PooldoseConfigEntry
from .entity import PooldoseEntity

if TYPE_CHECKING:
from .coordinator import PooldoseCoordinator

_LOGGER = logging.getLogger(__name__)


NUMBER_DESCRIPTIONS: tuple[NumberEntityDescription, ...] = (
NumberEntityDescription(
key="ph_target",
translation_key="ph_target",
entity_category=EntityCategory.CONFIG,
device_class=NumberDeviceClass.PH,
),
NumberEntityDescription(
key="orp_target",
translation_key="orp_target",
entity_category=EntityCategory.CONFIG,
device_class=NumberDeviceClass.VOLTAGE,
native_unit_of_measurement=UnitOfElectricPotential.MILLIVOLT,
),
NumberEntityDescription(
key="cl_target",
translation_key="cl_target",
entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
),
NumberEntityDescription(
key="ofa_ph_lower",
translation_key="ofa_ph_lower",
entity_category=EntityCategory.CONFIG,
device_class=NumberDeviceClass.PH,
),
NumberEntityDescription(
key="ofa_ph_upper",
translation_key="ofa_ph_upper",
entity_category=EntityCategory.CONFIG,
device_class=NumberDeviceClass.PH,
),
NumberEntityDescription(
key="ofa_orp_lower",
translation_key="ofa_orp_lower",
entity_category=EntityCategory.CONFIG,
device_class=NumberDeviceClass.VOLTAGE,
native_unit_of_measurement=UnitOfElectricPotential.MILLIVOLT,
),
NumberEntityDescription(
key="ofa_orp_upper",
translation_key="ofa_orp_upper",
entity_category=EntityCategory.CONFIG,
device_class=NumberDeviceClass.VOLTAGE,
native_unit_of_measurement=UnitOfElectricPotential.MILLIVOLT,
),
NumberEntityDescription(
key="ofa_cl_lower",
translation_key="ofa_cl_lower",
entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
),
NumberEntityDescription(
key="ofa_cl_upper",
translation_key="ofa_cl_upper",
entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
),
)


async def async_setup_entry(
hass: HomeAssistant,
config_entry: PooldoseConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up PoolDose number entities from a config entry."""
if TYPE_CHECKING:
assert config_entry.unique_id is not None

coordinator = config_entry.runtime_data
number_data = coordinator.data.get("number", {})
serial_number = config_entry.unique_id

async_add_entities(
PooldoseNumber(coordinator, serial_number, coordinator.device_info, description)
for description in NUMBER_DESCRIPTIONS
if description.key in number_data
)


class PooldoseNumber(PooldoseEntity, NumberEntity):
"""Number entity for the Seko PoolDose Python API."""

def __init__(
self,
coordinator: PooldoseCoordinator,
serial_number: str,
device_info: Any,
description: NumberEntityDescription,
) -> None:
"""Initialize the number."""
super().__init__(coordinator, serial_number, device_info, description, "number")
self._async_update_attrs()

def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
self._async_update_attrs()
super()._handle_coordinator_update()

def _async_update_attrs(self) -> None:
"""Update number attributes."""
data = cast(dict, self.get_data())
self._attr_native_value = data["value"]
self._attr_native_min_value = data["min"]
self._attr_native_max_value = data["max"]
self._attr_native_step = data["step"]

async def async_set_native_value(self, value: float) -> None:
"""Set new value."""
await self.coordinator.client.set_number(self.entity_description.key, value)
self._attr_native_value = value
self.async_write_ha_state()
29 changes: 29 additions & 0 deletions homeassistant/components/pooldose/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,35 @@
"name": "Auxiliary relay 3 status"
}
},
"number": {
"cl_target": {
"name": "Chlorine target"
},
"ofa_cl_lower": {
"name": "Chlorine overfeed alarm lower limit"
},
"ofa_cl_upper": {
"name": "Chlorine overfeed alarm upper limit"
},
"ofa_orp_lower": {
"name": "ORP overfeed alarm lower limit"
},
"ofa_orp_upper": {
"name": "ORP overfeed alarm upper limit"
},
"ofa_ph_lower": {
"name": "pH overfeed alarm lower limit"
},
"ofa_ph_upper": {
"name": "pH overfeed alarm upper limit"
},
"orp_target": {
"name": "ORP target"
},
"ph_target": {
"name": "pH target"
}
},
"sensor": {
"cl": {
"name": "Chlorine"
Expand Down
42 changes: 42 additions & 0 deletions tests/components/pooldose/fixtures/instantvalues.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,48 @@
"min": 0,
"max": 65535,
"step": 0.01
},
"ofa_ph_lower": {
"value": 6,
"unit": null,
"min": 0,
"max": 14,
"step": 0.1
},
"ofa_ph_upper": {
"value": 8,
"unit": null,
"min": 0,
"max": 14,
"step": 0.1
},
"ofa_orp_lower": {
"value": 600,
"unit": "mV",
"min": 0,
"max": 1000,
"step": 1
},
"ofa_orp_upper": {
"value": 800,
"unit": "mV",
"min": 0,
"max": 1000,
"step": 1
},
"ofa_cl_lower": {
"value": 0.2,
"unit": "ppm",
"min": 0,
"max": 10,
"step": 0.1
},
"ofa_cl_upper": {
"value": 0.9,
"unit": "ppm",
"min": 0,
"max": 10,
"step": 0.1
}
},
"switch": {
Expand Down
Loading
Loading