diff --git a/.coveragerc b/.coveragerc index 752ea5ca7bc571..c72c570feab67c 100644 --- a/.coveragerc +++ b/.coveragerc @@ -246,6 +246,7 @@ omit = homeassistant/components/duotecno/switch.py homeassistant/components/duotecno/cover.py homeassistant/components/duotecno/light.py + homeassistant/components/duotecno/climate.py homeassistant/components/dwd_weather_warnings/const.py homeassistant/components/dwd_weather_warnings/coordinator.py homeassistant/components/dwd_weather_warnings/sensor.py diff --git a/homeassistant/components/duotecno/__init__.py b/homeassistant/components/duotecno/__init__.py index 4c8060b468dd84..bc7d519aa9c3ad 100644 --- a/homeassistant/components/duotecno/__init__.py +++ b/homeassistant/components/duotecno/__init__.py @@ -11,7 +11,12 @@ from .const import DOMAIN -PLATFORMS: list[Platform] = [Platform.SWITCH, Platform.COVER, Platform.LIGHT] +PLATFORMS: list[Platform] = [ + Platform.SWITCH, + Platform.COVER, + Platform.LIGHT, + Platform.CLIMATE, +] async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: diff --git a/homeassistant/components/duotecno/climate.py b/homeassistant/components/duotecno/climate.py new file mode 100644 index 00000000000000..e7dfa53e53c0a3 --- /dev/null +++ b/homeassistant/components/duotecno/climate.py @@ -0,0 +1,92 @@ +"""Support for Duotecno climate devices.""" +from typing import Any, Final + +from duotecno.unit import SensUnit + +from homeassistant.components.climate import ( + ClimateEntity, + ClimateEntityFeature, + HVACMode, +) +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from .const import DOMAIN +from .entity import DuotecnoEntity, api_call + +HVACMODE: Final = { + 0: HVACMode.OFF, + 1: HVACMode.HEAT, + 2: HVACMode.COOL, +} +HVACMODE_REVERSE: Final = {value: key for key, value in HVACMODE.items()} + +PRESETMODES: Final = { + "sun": 0, + "half_sun": 1, + "moon": 2, + "half_moon": 3, +} +PRESETMODES_REVERSE: Final = {value: key for key, value in PRESETMODES.items()} + + +async def async_setup_entry( + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: AddEntitiesCallback, +) -> None: + """Set up Duotecno climate based on config_entry.""" + cntrl = hass.data[DOMAIN][entry.entry_id] + async_add_entities( + DuotecnoClimate(channel) for channel in cntrl.get_units(["SensUnit"]) + ) + + +class DuotecnoClimate(DuotecnoEntity, ClimateEntity): + """Representation of a Duotecno climate entity.""" + + _unit: SensUnit + _attr_supported_features = ( + ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.PRESET_MODE + ) + _attr_temperature_unit = UnitOfTemperature.CELSIUS + _attr_hvac_modes = list(HVACMODE_REVERSE) + _attr_preset_modes = list(PRESETMODES) + _attr_translation_key = "duotecno" + + @property + def current_temperature(self) -> int | None: + """Get the current temperature.""" + return self._unit.get_cur_temp() + + @property + def target_temperature(self) -> float | None: + """Get the target temperature.""" + return self._unit.get_target_temp() + + @property + def hvac_mode(self) -> HVACMode: + """Get the current hvac_mode.""" + return HVACMODE[self._unit.get_state()] + + @property + def preset_mode(self) -> str: + """Get the preset mode.""" + return PRESETMODES_REVERSE[self._unit.get_preset()] + + @api_call + async def async_set_temperature(self, **kwargs: Any) -> None: + """Set new target temperatures.""" + if (temp := kwargs.get(ATTR_TEMPERATURE)) is None: + return + await self._unit.set_temp(temp) + + @api_call + async def async_set_preset_mode(self, preset_mode: str) -> None: + """Set the preset mode.""" + await self._unit.set_preset(PRESETMODES[preset_mode]) + + async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None: + """Duotecno does not support setting this, we can only display it.""" diff --git a/homeassistant/components/duotecno/const.py b/homeassistant/components/duotecno/const.py index 114867b8d95219..6bffe2358e173d 100644 --- a/homeassistant/components/duotecno/const.py +++ b/homeassistant/components/duotecno/const.py @@ -1,3 +1,4 @@ """Constants for the duotecno integration.""" +from typing import Final -DOMAIN = "duotecno" +DOMAIN: Final = "duotecno" diff --git a/homeassistant/components/duotecno/strings.json b/homeassistant/components/duotecno/strings.json index 379291eb626330..a00647993a8b70 100644 --- a/homeassistant/components/duotecno/strings.json +++ b/homeassistant/components/duotecno/strings.json @@ -14,5 +14,21 @@ "invalid_auth": "[%key:common::config_flow::error::invalid_auth%]", "unknown": "[%key:common::config_flow::error::unknown%]" } + }, + "entity": { + "climate": { + "duotecno": { + "state_attributes": { + "preset_mode": { + "state": { + "sun": "Sun", + "half_sun": "Half sun", + "moon": "Moon", + "half_moon": "Half moon" + } + } + } + } + } } }