diff --git a/.coveragerc b/.coveragerc index 5b046a7249d..2eebbee3a3e 100644 --- a/.coveragerc +++ b/.coveragerc @@ -262,6 +262,7 @@ omit = homeassistant/components/ecoforest/__init__.py homeassistant/components/ecoforest/coordinator.py homeassistant/components/ecoforest/entity.py + homeassistant/components/ecoforest/number.py homeassistant/components/ecoforest/sensor.py homeassistant/components/econet/__init__.py homeassistant/components/econet/binary_sensor.py diff --git a/homeassistant/components/ecoforest/__init__.py b/homeassistant/components/ecoforest/__init__.py index cc5575248fe..1e2667256b1 100644 --- a/homeassistant/components/ecoforest/__init__.py +++ b/homeassistant/components/ecoforest/__init__.py @@ -18,7 +18,7 @@ from homeassistant.exceptions import ConfigEntryNotReady from .const import DOMAIN from .coordinator import EcoforestCoordinator -PLATFORMS: list[Platform] = [Platform.SENSOR] +PLATFORMS: list[Platform] = [Platform.SENSOR, Platform.NUMBER] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/ecoforest/number.py b/homeassistant/components/ecoforest/number.py new file mode 100644 index 00000000000..90ea0bd4dff --- /dev/null +++ b/homeassistant/components/ecoforest/number.py @@ -0,0 +1,74 @@ +"""Support for Ecoforest number platform.""" +from __future__ import annotations + +from collections.abc import Callable +from dataclasses import dataclass + +from pyecoforest.models.device import Device + +from homeassistant.components.number import NumberEntity, NumberEntityDescription +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from .const import DOMAIN +from .coordinator import EcoforestCoordinator +from .entity import EcoforestEntity + + +@dataclass +class EcoforestRequiredKeysMixin: + """Mixin for required keys.""" + + value_fn: Callable[[Device], float | None] + + +@dataclass +class EcoforestNumberEntityDescription( + NumberEntityDescription, EcoforestRequiredKeysMixin +): + """Describes an ecoforest number entity.""" + + +NUMBER_ENTITIES = ( + EcoforestNumberEntityDescription( + key="power_level", + translation_key="power_level", + native_min_value=1, + native_max_value=9, + native_step=1, + value_fn=lambda data: data.power, + ), +) + + +async def async_setup_entry( + hass: HomeAssistant, + config_entry: ConfigEntry, + async_add_entities: AddEntitiesCallback, +) -> None: + """Set up Ecoforest number platform.""" + coordinator: EcoforestCoordinator = hass.data[DOMAIN][config_entry.entry_id] + + entities = [ + EcoforestNumberEntity(coordinator, description) + for description in NUMBER_ENTITIES + ] + + async_add_entities(entities) + + +class EcoforestNumberEntity(EcoforestEntity, NumberEntity): + """Representation of an Ecoforest number entity.""" + + entity_description: EcoforestNumberEntityDescription + + @property + def native_value(self) -> float | None: + """Return the state of the entity.""" + return self.entity_description.value_fn(self.data) + + async def async_set_native_value(self, value: float) -> None: + """Update the native value.""" + await self.coordinator.api.set_power(int(value)) + await self.coordinator.async_request_refresh() diff --git a/homeassistant/components/ecoforest/strings.json b/homeassistant/components/ecoforest/strings.json index d6e3212b4ea..b35ff1dedf1 100644 --- a/homeassistant/components/ecoforest/strings.json +++ b/homeassistant/components/ecoforest/strings.json @@ -17,5 +17,12 @@ "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]" } + }, + "entity": { + "number": { + "power_level": { + "name": "Power level" + } + } } }