Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for EvoHomeController in Overkiz #133777

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions homeassistant/components/overkiz/climate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from .atlantic_pass_apc_heating_zone import AtlanticPassAPCHeatingZone
from .atlantic_pass_apc_zone_control import AtlanticPassAPCZoneControl
from .atlantic_pass_apc_zone_control_zone import AtlanticPassAPCZoneControlZone
from .evo_home_controller import EvoHomeController
from .hitachi_air_to_air_heat_pump_hlrrwifi import HitachiAirToAirHeatPumpHLRRWIFI
from .hitachi_air_to_air_heat_pump_ovp import HitachiAirToAirHeatPumpOVP
from .hitachi_air_to_water_heating_zone import HitachiAirToWaterHeatingZone
Expand Down Expand Up @@ -53,6 +54,7 @@ class Controllable(StrEnum):
UIWidget.ATLANTIC_PASS_APC_HEATING_ZONE: AtlanticPassAPCHeatingZone,
UIWidget.ATLANTIC_PASS_APC_ZONE_CONTROL: AtlanticPassAPCZoneControl,
UIWidget.HITACHI_AIR_TO_WATER_HEATING_ZONE: HitachiAirToWaterHeatingZone,
UIWidget.EVO_HOME_CONTROLLER: EvoHomeController,
UIWidget.SOMFY_HEATING_TEMPERATURE_INTERFACE: SomfyHeatingTemperatureInterface,
UIWidget.SOMFY_THERMOSTAT: SomfyThermostat,
UIWidget.VALVE_HEATING_TEMPERATURE_INTERFACE: ValveHeatingTemperatureInterface,
Expand Down
101 changes: 101 additions & 0 deletions homeassistant/components/overkiz/climate/evo_home_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
"""Support for EvoHomeController."""

from datetime import timedelta

from pyoverkiz.enums import OverkizCommand, OverkizCommandParam, OverkizState

from homeassistant.components.climate import (
PRESET_NONE,
ClimateEntity,
ClimateEntityFeature,
HVACMode,
)
from homeassistant.const import UnitOfTemperature
import homeassistant.util.dt as dt_util

from ..entity import OverkizDataUpdateCoordinator, OverkizEntity

PRESET_DAY_OFF = "day-off"
PRESET_HOLIDAYS = "holidays"

OVERKIZ_TO_HVAC_MODES: dict[str, HVACMode] = {
OverkizCommandParam.AUTO: HVACMode.AUTO,
OverkizCommandParam.OFF: HVACMode.OFF,
}
HVAC_MODES_TO_OVERKIZ = {v: k for k, v in OVERKIZ_TO_HVAC_MODES.items()}

OVERKIZ_TO_PRESET_MODES: dict[str, str] = {
OverkizCommandParam.DAY_OFF: PRESET_DAY_OFF,
OverkizCommandParam.HOLIDAYS: PRESET_HOLIDAYS,
}
PRESET_MODES_TO_OVERKIZ = {v: k for k, v in OVERKIZ_TO_PRESET_MODES.items()}


class EvoHomeController(OverkizEntity, ClimateEntity):
"""Representation of EvoHomeController device."""

_attr_hvac_modes = [*HVAC_MODES_TO_OVERKIZ]
_attr_preset_modes = [*PRESET_MODES_TO_OVERKIZ]
_attr_supported_features = (
ClimateEntityFeature.PRESET_MODE | ClimateEntityFeature.TURN_OFF
)
_attr_temperature_unit = UnitOfTemperature.CELSIUS

def __init__(
self, device_url: str, coordinator: OverkizDataUpdateCoordinator
) -> None:
"""Init method."""
super().__init__(device_url, coordinator)

Check warning on line 48 in homeassistant/components/overkiz/climate/evo_home_controller.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/overkiz/climate/evo_home_controller.py#L48

Added line #L48 was not covered by tests

if self._attr_device_info:
self._attr_device_info["manufacturer"] = "EvoHome"

Check warning on line 51 in homeassistant/components/overkiz/climate/evo_home_controller.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/overkiz/climate/evo_home_controller.py#L50-L51

Added lines #L50 - L51 were not covered by tests

@property
def hvac_mode(self) -> HVACMode:
"""Return hvac operation ie. heat, cool mode."""
if state := self.device.states.get(OverkizState.RAMSES_RAMSES_OPERATING_MODE):
operating_mode = state.value_as_str

Check warning on line 57 in homeassistant/components/overkiz/climate/evo_home_controller.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/overkiz/climate/evo_home_controller.py#L56-L57

Added lines #L56 - L57 were not covered by tests

if operating_mode in OVERKIZ_TO_HVAC_MODES:
return OVERKIZ_TO_HVAC_MODES[operating_mode]

Check warning on line 60 in homeassistant/components/overkiz/climate/evo_home_controller.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/overkiz/climate/evo_home_controller.py#L59-L60

Added lines #L59 - L60 were not covered by tests

if operating_mode in OVERKIZ_TO_PRESET_MODES:
return HVACMode.OFF

Check warning on line 63 in homeassistant/components/overkiz/climate/evo_home_controller.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/overkiz/climate/evo_home_controller.py#L62-L63

Added lines #L62 - L63 were not covered by tests

return HVACMode.OFF

Check warning on line 65 in homeassistant/components/overkiz/climate/evo_home_controller.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/overkiz/climate/evo_home_controller.py#L65

Added line #L65 was not covered by tests

async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set new target hvac mode."""
await self.executor.async_execute_command(

Check warning on line 69 in homeassistant/components/overkiz/climate/evo_home_controller.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/overkiz/climate/evo_home_controller.py#L69

Added line #L69 was not covered by tests
OverkizCommand.SET_OPERATING_MODE, HVAC_MODES_TO_OVERKIZ[hvac_mode]
)

@property
def preset_mode(self) -> str | None:
"""Return the current preset mode, e.g., home, away, temp."""
if (

Check warning on line 76 in homeassistant/components/overkiz/climate/evo_home_controller.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/overkiz/climate/evo_home_controller.py#L76

Added line #L76 was not covered by tests
state := self.device.states[OverkizState.RAMSES_RAMSES_OPERATING_MODE]
) and state.value_as_str in OVERKIZ_TO_PRESET_MODES:
return OVERKIZ_TO_PRESET_MODES[state.value_as_str]

Check warning on line 79 in homeassistant/components/overkiz/climate/evo_home_controller.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/overkiz/climate/evo_home_controller.py#L79

Added line #L79 was not covered by tests

return PRESET_NONE

Check warning on line 81 in homeassistant/components/overkiz/climate/evo_home_controller.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/overkiz/climate/evo_home_controller.py#L81

Added line #L81 was not covered by tests

async def async_set_preset_mode(self, preset_mode: str) -> None:
"""Set new preset mode."""
if preset_mode == PRESET_DAY_OFF:
today_end_of_day = dt_util.now().replace(

Check warning on line 86 in homeassistant/components/overkiz/climate/evo_home_controller.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/overkiz/climate/evo_home_controller.py#L85-L86

Added lines #L85 - L86 were not covered by tests
hour=0, minute=0, second=0, microsecond=0
) + timedelta(days=1)
time_interval = today_end_of_day

Check warning on line 89 in homeassistant/components/overkiz/climate/evo_home_controller.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/overkiz/climate/evo_home_controller.py#L89

Added line #L89 was not covered by tests

if preset_mode == PRESET_HOLIDAYS:
one_week_from_now = dt_util.now().replace(

Check warning on line 92 in homeassistant/components/overkiz/climate/evo_home_controller.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/overkiz/climate/evo_home_controller.py#L91-L92

Added lines #L91 - L92 were not covered by tests
hour=0, minute=0, second=0, microsecond=0
) + timedelta(days=7)
time_interval = one_week_from_now

Check warning on line 95 in homeassistant/components/overkiz/climate/evo_home_controller.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/overkiz/climate/evo_home_controller.py#L95

Added line #L95 was not covered by tests

await self.executor.async_execute_command(

Check warning on line 97 in homeassistant/components/overkiz/climate/evo_home_controller.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/overkiz/climate/evo_home_controller.py#L97

Added line #L97 was not covered by tests
OverkizCommand.SET_OPERATING_MODE,
PRESET_MODES_TO_OVERKIZ[preset_mode],
time_interval.strftime("%Y/%m/%d %H:%M"),
)
1 change: 1 addition & 0 deletions homeassistant/components/overkiz/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
UIWidget.ATLANTIC_PASS_APC_ZONE_CONTROL: Platform.CLIMATE, # widgetName, uiClass is HeatingSystem (not supported)
UIWidget.DOMESTIC_HOT_WATER_PRODUCTION: Platform.WATER_HEATER, # widgetName, uiClass is WaterHeatingSystem (not supported)
UIWidget.DOMESTIC_HOT_WATER_TANK: Platform.SWITCH, # widgetName, uiClass is WaterHeatingSystem (not supported)
UIWidget.EVO_HOME_CONTROLLER: Platform.CLIMATE, # widgetName, uiClass is EvoHome (not supported)
UIWidget.HITACHI_AIR_TO_AIR_HEAT_PUMP: Platform.CLIMATE, # widgetName, uiClass is HeatingSystem (not supported)
UIWidget.HITACHI_AIR_TO_WATER_HEATING_ZONE: Platform.CLIMATE, # widgetName, uiClass is HeatingSystem (not supported)
UIWidget.HITACHI_DHW: Platform.WATER_HEATER, # widgetName, uiClass is HitachiHeatingSystem (not supported)
Expand Down