<gh_stars>1000+
"""TOLO Sauna number controls."""
from __future__ import annotations

from collections.abc import Callable
from dataclasses import dataclass
from typing import Any

from tololib import ToloClient
from tololib.message_info import SettingsInfo

from homeassistant.components.number import NumberEntity, NumberEntityDescription
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import TIME_MINUTES
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from . import ToloSaunaCoordinatorEntity, ToloSaunaUpdateCoordinator
from .const import DOMAIN, FAN_TIMER_MAX, POWER_TIMER_MAX, SALT_BATH_TIMER_MAX


@dataclass
class ToloNumberEntityDescriptionBase:
    """Required values when describing TOLO Number entities."""

    getter: Callable[[SettingsInfo], int | None]
    setter: Callable[[ToloClient, int | None], Any]


@dataclass
class ToloNumberEntityDescription(
    NumberEntityDescription, ToloNumberEntityDescriptionBase
):
    """Class describing TOLO Number entities."""

    entity_category = EntityCategory.CONFIG
    native_min_value = 0
    native_step = 1


NUMBERS = (
    ToloNumberEntityDescription(
        key="power_timer",
        icon="mdi:power-settings",
        name="Power Timer",
        native_unit_of_measurement=TIME_MINUTES,
        native_max_value=POWER_TIMER_MAX,
        getter=lambda settings: settings.power_timer,
        setter=lambda client, value: client.set_power_timer(value),
    ),
    ToloNumberEntityDescription(
        key="salt_bath_timer",
        icon="mdi:shaker-outline",
        name="Salt Bath Timer",
        native_unit_of_measurement=TIME_MINUTES,
        native_max_value=SALT_BATH_TIMER_MAX,
        getter=lambda settings: settings.salt_bath_timer,
        setter=lambda client, value: client.set_salt_bath_timer(value),
    ),
    ToloNumberEntityDescription(
        key="fan_timer",
        icon="mdi:fan-auto",
        name="Fan Timer",
        native_unit_of_measurement=TIME_MINUTES,
        native_max_value=FAN_TIMER_MAX,
        getter=lambda settings: settings.fan_timer,
        setter=lambda client, value: client.set_fan_timer(value),
    ),
)


async def async_setup_entry(
    hass: HomeAssistant,
    entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up number controls for TOLO Sauna."""
    coordinator = hass.data[DOMAIN][entry.entry_id]
    async_add_entities(
        ToloNumberEntity(coordinator, entry, description) for description in NUMBERS
    )


class ToloNumberEntity(ToloSaunaCoordinatorEntity, NumberEntity):
    """TOLO Number entity."""

    entity_description: ToloNumberEntityDescription

    def __init__(
        self,
        coordinator: ToloSaunaUpdateCoordinator,
        entry: ConfigEntry,
        entity_description: ToloNumberEntityDescription,
    ) -> None:
        """Initialize TOLO Number entity."""
        super().__init__(coordinator, entry)
        self.entity_description = entity_description
        self._attr_unique_id = f"{entry.entry_id}_{entity_description.key}"

    @property
    def native_value(self) -> float:
        """Return the value of this TOLO Number entity."""
        return self.entity_description.getter(self.coordinator.data.settings) or 0

    def set_native_value(self, value: float) -> None:
        """Set the value of this TOLO Number entity."""
        int_value = int(value)
        if int_value == 0:
            self.entity_description.setter(self.coordinator.client, None)
            return
        self.entity_description.setter(self.coordinator.client, int_value)

"""TOLO Sauna number controls."""
from __future__ import annotations

from collections.abc import Callable
from dataclasses import dataclass
from typing import Any

from tololib import ToloClient
from tololib.message_info import SettingsInfo

from homeassistant.components.number import NumberEntity, NumberEntityDescription
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import TIME_MINUTES
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from . import ToloSaunaCoordinatorEntity, ToloSaunaUpdateCoordinator
from .const import DOMAIN, FAN_TIMER_MAX, POWER_TIMER_MAX, SALT_BATH_TIMER_MAX


@dataclass
class ToloNumberEntityDescriptionBase:
    """Required values when describing TOLO Number entities."""

    getter: Callable[[SettingsInfo], int | None]
    setter: Callable[[ToloClient, int | None], Any]


@dataclass
class ToloNumberEntityDescription(
    NumberEntityDescription, ToloNumberEntityDescriptionBase
):
    """Class describing TOLO Number entities."""

    entity_category = EntityCategory.CONFIG
    native_min_value = 0
    native_step = 1


NUMBERS = (
    ToloNumberEntityDescription(
        key="power_timer",
        icon="mdi:power-settings",
        name="Power Timer",
        native_unit_of_measurement=TIME_MINUTES,
        native_max_value=POWER_TIMER_MAX,
        getter=lambda settings: settings.power_timer,
        setter=lambda client, value: client.set_power_timer(value),
    ),
    ToloNumberEntityDescription(
        key="salt_bath_timer",
        icon="mdi:shaker-outline",
        name="Salt Bath Timer",
        native_unit_of_measurement=TIME_MINUTES,
        native_max_value=SALT_BATH_TIMER_MAX,
        getter=lambda settings: settings.salt_bath_timer,
        setter=lambda client, value: client.set_salt_bath_timer(value),
    ),
    ToloNumberEntityDescription(
        key="fan_timer",
        icon="mdi:fan-auto",
        name="Fan Timer",
        native_unit_of_measurement=TIME_MINUTES,
        native_max_value=FAN_TIMER_MAX,
        getter=lambda settings: settings.fan_timer,
        setter=lambda client, value: client.set_fan_timer(value),
    ),
)


async def async_setup_entry(
    hass: HomeAssistant,
    entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up number controls for TOLO Sauna."""
    coordinator = hass.data[DOMAIN][entry.entry_id]
    async_add_entities(
        ToloNumberEntity(coordinator, entry, description) for description in NUMBERS
    )


class ToloNumberEntity(ToloSaunaCoordinatorEntity, NumberEntity):
    """TOLO Number entity."""

    entity_description: ToloNumberEntityDescription

    def __init__(
        self,
        coordinator: ToloSaunaUpdateCoordinator,
        entry: ConfigEntry,
        entity_description: ToloNumberEntityDescription,
    ) -> None:
        """Initialize TOLO Number entity."""
        super().__init__(coordinator, entry)
        self.entity_description = entity_description
        self._attr_unique_id = f"{entry.entry_id}_{entity_description.key}"

    @property
    def native_value(self) -> float:
        """Return the value of this TOLO Number entity."""
        return self.entity_description.getter(self.coordinator.data.settings) or 0

    def set_native_value(self, value: float) -> None:
        """Set the value of this TOLO Number entity."""
        int_value = int(value)
        if int_value == 0:
            self.entity_description.setter(self.coordinator.client, None)
            return
        self.entity_description.setter(self.coordinator.client, int_value)
TOLO Sauna number controls. Required values when describing TOLO Number entities. Class describing TOLO Number entities. Set up number controls for TOLO Sauna. TOLO Number entity. Initialize TOLO Number entity. Return the value of this TOLO Number entity. Set the value of this TOLO Number entity.