"""Support for Huum wifi-enabled sauna.""" from typing import Any, override from huum.const import SaunaStatus from huum.exceptions import SafetyException from homeassistant.components.climate import ( ClimateEntity, ClimateEntityFeature, HVACMode, ) from homeassistant.const import ATTR_TEMPERATURE, PRECISION_WHOLE, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import CONFIG_DEFAULT_MAX_TEMP, CONFIG_DEFAULT_MIN_TEMP, DOMAIN from .coordinator import HuumConfigEntry, HuumDataUpdateCoordinator from .entity import HuumBaseEntity PARALLEL_UPDATES = 1 async def async_setup_entry( hass: HomeAssistant, entry: HuumConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up the Huum sauna with config flow.""" async_add_entities([HuumDevice(entry.runtime_data)]) class HuumDevice(HuumBaseEntity, ClimateEntity): """Representation of a heater.""" _attr_hvac_modes = [HVACMode.HEAT, HVACMode.OFF] _attr_supported_features = ( ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.TURN_OFF | ClimateEntityFeature.TURN_ON ) _attr_target_temperature_step = PRECISION_WHOLE _attr_temperature_unit = UnitOfTemperature.CELSIUS _attr_name = None def __init__(self, coordinator: HuumDataUpdateCoordinator) -> None: """Initialize the heater.""" super().__init__(coordinator) self._attr_unique_id = coordinator.config_entry.entry_id @property @override def min_temp(self) -> int: """Return configured minimal temperature.""" sauna_config = self.coordinator.data.sauna_config if sauna_config is None: return CONFIG_DEFAULT_MIN_TEMP return sauna_config.min_temp or CONFIG_DEFAULT_MIN_TEMP @property @override def max_temp(self) -> int: """Return configured maximum temperature.""" sauna_config = self.coordinator.data.sauna_config if sauna_config is None: return CONFIG_DEFAULT_MAX_TEMP return sauna_config.max_temp or CONFIG_DEFAULT_MAX_TEMP @property @override def hvac_mode(self) -> HVACMode: """Return hvac operation ie. heat, cool mode.""" if self.coordinator.data.status == SaunaStatus.ONLINE_HEATING: return HVACMode.HEAT return HVACMode.OFF @property @override def current_temperature(self) -> int | None: """Return the current temperature.""" return self.coordinator.data.temperature @property @override def target_temperature(self) -> int: """Return the temperature we try to reach.""" return self.coordinator.data.target_temperature or int(self.min_temp) @override async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None: """Set hvac mode.""" if hvac_mode == HVACMode.HEAT: # Make sure to send integers # The temperature is not always an integer if the user uses Fahrenheit temperature = int(self.target_temperature) await self._turn_on(temperature) elif hvac_mode == HVACMode.OFF: await self.coordinator.huum.turn_off() await self.coordinator.async_refresh() @override async def async_set_temperature(self, **kwargs: Any) -> None: """Set new target temperature.""" temperature = kwargs.get(ATTR_TEMPERATURE) if temperature is None or self.hvac_mode != HVACMode.HEAT: return temperature = int(temperature) await self._turn_on(temperature) await self.coordinator.async_refresh() async def _turn_on(self, temperature: int) -> None: try: await self.coordinator.huum.turn_on(temperature) except (ValueError, SafetyException) as err: raise HomeAssistantError( translation_domain=DOMAIN, translation_key="unable_to_turn_on", ) from err