diff --git a/homeassistant/components/overkiz/const.py b/homeassistant/components/overkiz/const.py index f207fc305e0..bf9ca3b343f 100644 --- a/homeassistant/components/overkiz/const.py +++ b/homeassistant/components/overkiz/const.py @@ -70,6 +70,7 @@ OVERKIZ_DEVICE_TO_PLATFORM: dict[UIClass | UIWidget, Platform | None] = { UIWidget.ATLANTIC_PASS_APC_HEATING_AND_COOLING_ZONE: Platform.CLIMATE, # widgetName, uiClass is HeatingSystem (not supported) UIWidget.ATLANTIC_PASS_APC_ZONE_CONTROL: Platform.CLIMATE, # widgetName, uiClass is HeatingSystem (not supported) UIWidget.DOMESTIC_HOT_WATER_TANK: Platform.SWITCH, # widgetName, uiClass is WaterHeatingSystem (not supported) + UIWidget.HITACHI_DHW: Platform.WATER_HEATER, # widgetName, uiClass is HitachiHeatingSystem (not supported) UIWidget.MY_FOX_ALARM_CONTROLLER: Platform.ALARM_CONTROL_PANEL, # widgetName, uiClass is Alarm (not supported) UIWidget.MY_FOX_SECURITY_CAMERA: Platform.SWITCH, # widgetName, uiClass is Camera (not supported) UIWidget.RTD_INDOOR_SIREN: Platform.SWITCH, # widgetName, uiClass is Siren (not supported) diff --git a/homeassistant/components/overkiz/water_heater_entities/__init__.py b/homeassistant/components/overkiz/water_heater_entities/__init__.py index e03585da56d..abf9db78116 100644 --- a/homeassistant/components/overkiz/water_heater_entities/__init__.py +++ b/homeassistant/components/overkiz/water_heater_entities/__init__.py @@ -2,7 +2,9 @@ from pyoverkiz.enums.ui import UIWidget from .atlantic_pass_apc_dhw import AtlanticPassAPCDHW +from .hitachi_dhw import HitachiDHW WIDGET_TO_WATER_HEATER_ENTITY = { UIWidget.ATLANTIC_PASS_APC_DHW: AtlanticPassAPCDHW, + UIWidget.HITACHI_DHW: HitachiDHW, } diff --git a/homeassistant/components/overkiz/water_heater_entities/hitachi_dhw.py b/homeassistant/components/overkiz/water_heater_entities/hitachi_dhw.py new file mode 100644 index 00000000000..fa8c128e0c1 --- /dev/null +++ b/homeassistant/components/overkiz/water_heater_entities/hitachi_dhw.py @@ -0,0 +1,101 @@ +"""Support for Hitachi DHW.""" +from __future__ import annotations + +from typing import Any, cast + +from pyoverkiz.enums import OverkizCommand, OverkizCommandParam, OverkizState + +from homeassistant.components.water_heater import ( + STATE_HIGH_DEMAND, + WaterHeaterEntity, + WaterHeaterEntityFeature, +) +from homeassistant.const import ( + ATTR_TEMPERATURE, + PRECISION_WHOLE, + STATE_OFF, + STATE_ON, + TEMP_CELSIUS, +) + +from ..entity import OverkizEntity + +OVERKIZ_TO_OPERATION_MODE: dict[str, str] = { + OverkizCommandParam.STANDARD: STATE_ON, + OverkizCommandParam.HIGH_DEMAND: STATE_HIGH_DEMAND, + OverkizCommandParam.STOP: STATE_OFF, +} + +OPERATION_MODE_TO_OVERKIZ = {v: k for k, v in OVERKIZ_TO_OPERATION_MODE.items()} + + +class HitachiDHW(OverkizEntity, WaterHeaterEntity): + """Representation of Hitachi DHW.""" + + _attr_min_temp = 30.0 + _attr_max_temp = 70.0 + _attr_precision = PRECISION_WHOLE + + _attr_temperature_unit = TEMP_CELSIUS + _attr_supported_features = ( + WaterHeaterEntityFeature.TARGET_TEMPERATURE + | WaterHeaterEntityFeature.OPERATION_MODE + ) + _attr_operation_list = [*OPERATION_MODE_TO_OVERKIZ] + + @property + def current_temperature(self) -> float | None: + """Return the current temperature.""" + current_temperature = self.device.states[OverkizState.CORE_DHW_TEMPERATURE] + if current_temperature: + return current_temperature.value_as_float + return None + + @property + def target_temperature(self) -> float | None: + """Return the temperature we try to reach.""" + target_temperature = self.device.states[ + OverkizState.MODBUS_CONTROL_DHW_SETTING_TEMPERATURE + ] + if target_temperature: + return target_temperature.value_as_float + return None + + async def async_set_temperature(self, **kwargs: Any) -> None: + """Set new target temperature.""" + temperature = cast(float, kwargs.get(ATTR_TEMPERATURE)) + await self.executor.async_execute_command( + OverkizCommand.SET_CONTROL_DHW_SETTING_TEMPERATURE, int(temperature) + ) + + @property + def current_operation(self) -> str | None: + """Return current operation ie. eco, electric, performance, ...""" + modbus_control = self.device.states[OverkizState.MODBUS_CONTROL_DHW] + if modbus_control and modbus_control.value_as_str == OverkizCommandParam.STOP: + return STATE_OFF + + current_mode = self.device.states[OverkizState.MODBUS_DHW_MODE] + if current_mode and current_mode.value_as_str in OVERKIZ_TO_OPERATION_MODE: + return OVERKIZ_TO_OPERATION_MODE[current_mode.value_as_str] + + return None + + async def async_set_operation_mode(self, operation_mode: str) -> None: + """Set new target operation mode.""" + # Turn water heater off + if operation_mode == OverkizCommandParam.OFF: + return await self.executor.async_execute_command( + OverkizCommand.SET_CONTROL_DHW, OverkizCommandParam.STOP + ) + + # Turn water heater on, when off + if self.current_operation == OverkizCommandParam.OFF: + await self.executor.async_execute_command( + OverkizCommand.SET_CONTROL_DHW, OverkizCommandParam.ON + ) + + # Change operation mode + await self.executor.async_execute_command( + OverkizCommand.SET_DHW_MODE, OPERATION_MODE_TO_OVERKIZ[operation_mode] + )