mirror of
https://github.com/home-assistant/core.git
synced 2026-10-06 06:15:47 -04:00
Add HVAC action to MELCloud Home ATW zones (#183771)
This commit is contained in:
@@ -7,6 +7,7 @@ from aiomelcloudhome import (
|
||||
ATAOperationMode,
|
||||
ATAVaneHorizontal,
|
||||
ATAVaneVertical,
|
||||
ATWOperationMode,
|
||||
ATWZoneMode,
|
||||
)
|
||||
|
||||
@@ -14,6 +15,7 @@ from homeassistant.components.climate import (
|
||||
ClimateEntity,
|
||||
ClimateEntityDescription,
|
||||
ClimateEntityFeature,
|
||||
HVACAction,
|
||||
HVACMode,
|
||||
)
|
||||
from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature
|
||||
@@ -92,6 +94,15 @@ HVAC_MODE_TO_ATW_ZONE_MODE: dict[HVACMode, ATWZoneMode] = {
|
||||
HVACMode.COOL: ATWZoneMode.COOL_ROOM_TEMPERATURE,
|
||||
}
|
||||
|
||||
# The unit heats either the tank or the zones, so heating the tank idles the zones
|
||||
ATW_OPERATION_TO_HVAC_ACTION: dict[ATWOperationMode, HVACAction] = {
|
||||
ATWOperationMode.STOP: HVACAction.IDLE,
|
||||
ATWOperationMode.HOT_WATER: HVACAction.IDLE,
|
||||
ATWOperationMode.HEAT: HVACAction.HEATING,
|
||||
ATWOperationMode.HEAT_ZONES: HVACAction.HEATING,
|
||||
ATWOperationMode.COOL: HVACAction.COOLING,
|
||||
}
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
@@ -441,6 +452,16 @@ class ATWZoneClimateEntity(MelCloudHomeATWZoneEntity, ClimateEntity):
|
||||
else HVACMode.OFF
|
||||
)
|
||||
|
||||
@property
|
||||
@override
|
||||
def hvac_action(self) -> HVACAction | None:
|
||||
"""Return what the unit is doing for this zone."""
|
||||
if self.hvac_mode == HVACMode.OFF:
|
||||
return HVACAction.OFF
|
||||
if self.unit.operation_mode is None:
|
||||
return None
|
||||
return ATW_OPERATION_TO_HVAC_ACTION[self.unit.operation_mode]
|
||||
|
||||
@override
|
||||
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
||||
"""Set the HVAC mode."""
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
'attributes': ReadOnlyDict({
|
||||
<ClimateEntityStateAttribute.CURRENT_TEMPERATURE: 'current_temperature'>: 20.0,
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Heat Pump Zone 1',
|
||||
<ClimateEntityStateAttribute.HVAC_ACTION: 'hvac_action'>: <HVACAction.HEATING: 'heating'>,
|
||||
<ClimateEntityCapabilityAttribute.HVAC_MODES: 'hvac_modes'>: list([
|
||||
<HVACMode.OFF: 'off'>,
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
@@ -117,6 +118,7 @@
|
||||
'attributes': ReadOnlyDict({
|
||||
<ClimateEntityStateAttribute.CURRENT_TEMPERATURE: 'current_temperature'>: 21.0,
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Heat Pump Zone 2',
|
||||
<ClimateEntityStateAttribute.HVAC_ACTION: 'hvac_action'>: <HVACAction.HEATING: 'heating'>,
|
||||
<ClimateEntityCapabilityAttribute.HVAC_MODES: 'hvac_modes'>: list([
|
||||
<HVACMode.OFF: 'off'>,
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
|
||||
@@ -19,6 +19,7 @@ import pytest
|
||||
|
||||
from homeassistant.components.climate import (
|
||||
ATTR_FAN_MODE,
|
||||
ATTR_HVAC_ACTION,
|
||||
ATTR_HVAC_MODE,
|
||||
ATTR_SWING_HORIZONTAL_MODE,
|
||||
ATTR_SWING_MODE,
|
||||
@@ -28,6 +29,7 @@ from homeassistant.components.climate import (
|
||||
SERVICE_SET_SWING_HORIZONTAL_MODE,
|
||||
SERVICE_SET_SWING_MODE,
|
||||
SERVICE_SET_TEMPERATURE,
|
||||
HVACAction,
|
||||
HVACMode,
|
||||
)
|
||||
from homeassistant.components.melcloud_home.const import DOMAIN
|
||||
@@ -527,6 +529,47 @@ async def test_atw_zone_temperature_range(
|
||||
assert state2.attributes["max_temp"] == 28.0
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("overrides", "expected_action"),
|
||||
[
|
||||
pytest.param({"OperationMode": "Stop"}, HVACAction.IDLE, id="idle"),
|
||||
pytest.param({"OperationMode": "HotWater"}, HVACAction.IDLE, id="hot_water"),
|
||||
pytest.param({"OperationMode": "Heat"}, HVACAction.HEATING, id="heat"),
|
||||
pytest.param(
|
||||
{"OperationMode": "HeatZones"}, HVACAction.HEATING, id="heat_zones"
|
||||
),
|
||||
pytest.param({"OperationMode": "Cool"}, HVACAction.COOLING, id="cool"),
|
||||
pytest.param({"OperationMode": "Unknown"}, None, id="unknown"),
|
||||
pytest.param(
|
||||
{"OperationMode": "Heat", "Power": "False"}, HVACAction.OFF, id="off"
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_atw_zone_hvac_action(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_melcloud_client: AsyncMock,
|
||||
overrides: dict[str, str],
|
||||
expected_action: HVACAction | None,
|
||||
) -> None:
|
||||
"""Test the ATW zone HVAC action follows the unit's operation mode."""
|
||||
context: dict[str, Any] = await async_load_json_object_fixture(
|
||||
hass, "context.json", DOMAIN
|
||||
)
|
||||
settings = {
|
||||
setting["name"]: setting
|
||||
for setting in context["buildings"][0]["airToWaterUnits"][0]["settings"]
|
||||
}
|
||||
for name, value in overrides.items():
|
||||
settings[name]["value"] = value
|
||||
mock_melcloud_client.get_context.return_value = UserContext.model_validate(context)
|
||||
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
assert (state := hass.states.get(ATW_ZONE1_ENTITY_ID))
|
||||
assert state.attributes.get(ATTR_HVAC_ACTION) == expected_action
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("entity_id", "method", "service", "service_data"),
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user