Improve AtlanticDomesticHotWaterProductionMBLComponent support in Overkiz (#114178)

* add overkiz AtlanticDHW support

Adds support of Overkiz water heater entity selection based on device controllable_name
Adds support of Atlantic water heater based on Atlantic Steatite Cube WI-FI VM 150 S4CS 2400W
Adds more Overkiz water heater binary_sensors, numbers, and sensors

* Changed class annotation

* min_temp and max_temp as properties

* reverted binary_sensors, number, sensor to make separate PRs

* Update homeassistant/components/overkiz/water_heater_entities/atlantic_dhw.py

Co-authored-by: Mick Vleeshouwer <mick@imick.nl>

* Update homeassistant/components/overkiz/water_heater_entities/atlantic_dhw.py

Co-authored-by: Mick Vleeshouwer <mick@imick.nl>

* Update homeassistant/components/overkiz/water_heater_entities/atlantic_dhw.py

Co-authored-by: Mick Vleeshouwer <mick@imick.nl>

* Update homeassistant/components/overkiz/water_heater.py

Co-authored-by: Mick Vleeshouwer <mick@imick.nl>

* Update homeassistant/components/overkiz/water_heater_entities/atlantic_dhw.py

Co-authored-by: Mick Vleeshouwer <mick@imick.nl>

* Update homeassistant/components/overkiz/water_heater_entities/atlantic_dhw.py

Co-authored-by: Mick Vleeshouwer <mick@imick.nl>

* review fixes, typos, and pylint

* review fix

* review fix

* ruff

* temperature properties changed to constructor attributes

* logger removed

* constants usage consistency

* redundant mapping removed

* Update homeassistant/components/overkiz/water_heater_entities/atlantic_dhw.py

Co-authored-by: Mick Vleeshouwer <mick@imick.nl>

* boost mode method annotation typo

* removed away mode for atlantic dwh

* absence and boost mode attributes now support 'prog' state

* heating status bugfix

* electrical consumption sensor

* warm water remaining volume sensor

* away mode reintroduced

* mypy check

* boost plus state support

* Update homeassistant/components/overkiz/sensor.py

Co-authored-by: Mick Vleeshouwer <mick@imick.nl>

* sensors reverted to separate them into their own PR

* check away and boost modes on before switching them off

* atlantic_dhw renamed to atlantic_domestic_hot_water_production

* annotation changed

* AtlanticDomesticHotWaterProductionMBLComponent file renamed, annotation change reverted

---------

Co-authored-by: Mick Vleeshouwer <mick@imick.nl>
This commit is contained in:
Alexey ALERT Rubashёff 2024-06-27 23:05:58 +03:00 committed by Franck Nijhof
parent 53e49861a1
commit 2c2261254b
No known key found for this signature in database
GPG Key ID: D62583BA8AB11CA3
4 changed files with 216 additions and 11 deletions

View File

@ -109,17 +109,20 @@ BINARY_SENSOR_DESCRIPTIONS: list[OverkizBinarySensorDescription] = [
key=OverkizState.CORE_HEATING_STATUS,
name="Heating status",
device_class=BinarySensorDeviceClass.HEAT,
value_fn=lambda state: state == OverkizCommandParam.ON,
value_fn=lambda state: cast(str, state).lower()
in (OverkizCommandParam.ON, OverkizCommandParam.HEATING),
),
OverkizBinarySensorDescription(
key=OverkizState.MODBUSLINK_DHW_ABSENCE_MODE,
name="Absence mode",
value_fn=lambda state: state == OverkizCommandParam.ON,
value_fn=lambda state: state
in (OverkizCommandParam.ON, OverkizCommandParam.PROG),
),
OverkizBinarySensorDescription(
key=OverkizState.MODBUSLINK_DHW_BOOST_MODE,
name="Boost mode",
value_fn=lambda state: state == OverkizCommandParam.ON,
value_fn=lambda state: state
in (OverkizCommandParam.ON, OverkizCommandParam.PROG),
),
]

View File

@ -9,7 +9,11 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import HomeAssistantOverkizData
from .const import DOMAIN
from .water_heater_entities import WIDGET_TO_WATER_HEATER_ENTITY
from .entity import OverkizEntity
from .water_heater_entities import (
CONTROLLABLE_NAME_TO_WATER_HEATER_ENTITY,
WIDGET_TO_WATER_HEATER_ENTITY,
)
async def async_setup_entry(
@ -19,11 +23,20 @@ async def async_setup_entry(
) -> None:
"""Set up the Overkiz DHW from a config entry."""
data: HomeAssistantOverkizData = hass.data[DOMAIN][entry.entry_id]
entities: list[OverkizEntity] = []
async_add_entities(
WIDGET_TO_WATER_HEATER_ENTITY[device.widget](
device.device_url, data.coordinator
)
for device in data.platforms[Platform.WATER_HEATER]
if device.widget in WIDGET_TO_WATER_HEATER_ENTITY
)
for device in data.platforms[Platform.WATER_HEATER]:
if device.controllable_name in CONTROLLABLE_NAME_TO_WATER_HEATER_ENTITY:
entities.append(
CONTROLLABLE_NAME_TO_WATER_HEATER_ENTITY[device.controllable_name](
device.device_url, data.coordinator
)
)
elif device.widget in WIDGET_TO_WATER_HEATER_ENTITY:
entities.append(
WIDGET_TO_WATER_HEATER_ENTITY[device.widget](
device.device_url, data.coordinator
)
)
async_add_entities(entities)

View File

@ -2,6 +2,9 @@
from pyoverkiz.enums.ui import UIWidget
from .atlantic_domestic_hot_water_production_mlb_component import (
AtlanticDomesticHotWaterProductionMBLComponent,
)
from .atlantic_pass_apc_dhw import AtlanticPassAPCDHW
from .domestic_hot_water_production import DomesticHotWaterProduction
from .hitachi_dhw import HitachiDHW
@ -11,3 +14,7 @@ WIDGET_TO_WATER_HEATER_ENTITY = {
UIWidget.DOMESTIC_HOT_WATER_PRODUCTION: DomesticHotWaterProduction,
UIWidget.HITACHI_DHW: HitachiDHW,
}
CONTROLLABLE_NAME_TO_WATER_HEATER_ENTITY = {
"modbuslink:AtlanticDomesticHotWaterProductionMBLComponent": AtlanticDomesticHotWaterProductionMBLComponent,
}

View File

@ -0,0 +1,182 @@
"""Support for AtlanticDomesticHotWaterProductionMBLComponent."""
from typing import Any, cast
from pyoverkiz.enums import OverkizCommand, OverkizCommandParam, OverkizState
from homeassistant.components.water_heater import (
STATE_ECO,
STATE_OFF,
STATE_PERFORMANCE,
WaterHeaterEntity,
WaterHeaterEntityFeature,
)
from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature
from .. import OverkizDataUpdateCoordinator
from ..entity import OverkizEntity
class AtlanticDomesticHotWaterProductionMBLComponent(OverkizEntity, WaterHeaterEntity):
"""Representation of AtlanticDomesticHotWaterProductionMBLComponent (modbuslink)."""
_attr_temperature_unit = UnitOfTemperature.CELSIUS
_attr_supported_features = (
WaterHeaterEntityFeature.TARGET_TEMPERATURE
| WaterHeaterEntityFeature.OPERATION_MODE
| WaterHeaterEntityFeature.AWAY_MODE
| WaterHeaterEntityFeature.ON_OFF
)
_attr_operation_list = [
OverkizCommandParam.PERFORMANCE,
OverkizCommandParam.ECO,
OverkizCommandParam.MANUAL,
]
def __init__(
self, device_url: str, coordinator: OverkizDataUpdateCoordinator
) -> None:
"""Init method."""
super().__init__(device_url, coordinator)
self._attr_max_temp = cast(
float,
self.executor.select_state(
OverkizState.CORE_MAXIMAL_TEMPERATURE_MANUAL_MODE
),
)
self._attr_min_temp = cast(
float,
self.executor.select_state(
OverkizState.CORE_MINIMAL_TEMPERATURE_MANUAL_MODE
),
)
@property
def current_temperature(self) -> float:
"""Return the current temperature."""
return cast(
float,
self.executor.select_state(
OverkizState.MODBUSLINK_MIDDLE_WATER_TEMPERATURE
),
)
@property
def target_temperature(self) -> float:
"""Return the temperature corresponding to the PRESET."""
return cast(
float,
self.executor.select_state(OverkizState.CORE_WATER_TARGET_TEMPERATURE),
)
async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set new temperature."""
temperature = kwargs[ATTR_TEMPERATURE]
await self.executor.async_execute_command(
OverkizCommand.SET_TARGET_DHW_TEMPERATURE, temperature
)
@property
def is_boost_mode_on(self) -> bool:
"""Return true if boost mode is on."""
return self.executor.select_state(OverkizState.MODBUSLINK_DHW_BOOST_MODE) in (
OverkizCommandParam.ON,
OverkizCommandParam.PROG,
)
@property
def is_eco_mode_on(self) -> bool:
"""Return true if eco mode is on."""
return self.executor.select_state(OverkizState.MODBUSLINK_DHW_MODE) in (
OverkizCommandParam.MANUAL_ECO_ACTIVE,
OverkizCommandParam.AUTO_MODE,
)
@property
def is_away_mode_on(self) -> bool:
"""Return true if away mode is on."""
return (
self.executor.select_state(OverkizState.MODBUSLINK_DHW_ABSENCE_MODE)
== OverkizCommandParam.ON
)
@property
def current_operation(self) -> str:
"""Return current operation."""
if self.is_away_mode_on:
return STATE_OFF
if self.is_boost_mode_on:
return STATE_PERFORMANCE
if self.is_eco_mode_on:
return STATE_ECO
if (
cast(str, self.executor.select_state(OverkizState.MODBUSLINK_DHW_MODE))
== OverkizCommandParam.MANUAL_ECO_INACTIVE
):
return OverkizCommandParam.MANUAL
return STATE_OFF
async def async_set_operation_mode(self, operation_mode: str) -> None:
"""Set new operation mode."""
if operation_mode in (STATE_PERFORMANCE, OverkizCommandParam.BOOST):
if self.is_away_mode_on:
await self.async_turn_away_mode_off()
await self.async_turn_boost_mode_on()
elif operation_mode in (
OverkizCommandParam.ECO,
OverkizCommandParam.MANUAL_ECO_ACTIVE,
):
if self.is_away_mode_on:
await self.async_turn_away_mode_off()
if self.is_boost_mode_on:
await self.async_turn_boost_mode_off()
await self.executor.async_execute_command(
OverkizCommand.SET_DHW_MODE, OverkizCommandParam.AUTO_MODE
)
elif operation_mode in (
OverkizCommandParam.MANUAL,
OverkizCommandParam.MANUAL_ECO_INACTIVE,
):
if self.is_away_mode_on:
await self.async_turn_away_mode_off()
if self.is_boost_mode_on:
await self.async_turn_boost_mode_off()
await self.executor.async_execute_command(
OverkizCommand.SET_DHW_MODE, OverkizCommandParam.MANUAL_ECO_INACTIVE
)
else:
if self.is_away_mode_on:
await self.async_turn_away_mode_off()
if self.is_boost_mode_on:
await self.async_turn_boost_mode_off()
await self.executor.async_execute_command(
OverkizCommand.SET_DHW_MODE, operation_mode
)
async def async_turn_away_mode_on(self) -> None:
"""Turn away mode on."""
await self.executor.async_execute_command(
OverkizCommand.SET_ABSENCE_MODE, OverkizCommandParam.ON
)
async def async_turn_away_mode_off(self) -> None:
"""Turn away mode off."""
await self.executor.async_execute_command(
OverkizCommand.SET_ABSENCE_MODE, OverkizCommandParam.OFF
)
async def async_turn_boost_mode_on(self) -> None:
"""Turn boost mode on."""
await self.executor.async_execute_command(
OverkizCommand.SET_BOOST_MODE, OverkizCommandParam.ON
)
async def async_turn_boost_mode_off(self) -> None:
"""Turn boost mode off."""
await self.executor.async_execute_command(
OverkizCommand.SET_BOOST_MODE, OverkizCommandParam.OFF
)