mirror of
https://github.com/home-assistant/core.git
synced 2025-07-17 10:17:09 +00:00
Add cool mode to HomematicIP climate (#28525)
* Add cool mode to HomematicIP climate * Update test * remove preset_party * Fix profile_names check
This commit is contained in:
parent
899306c8ec
commit
9d3d35ad79
@ -4,13 +4,15 @@ from typing import Awaitable
|
|||||||
|
|
||||||
from homematicip.aio.device import AsyncHeatingThermostat, AsyncHeatingThermostatCompact
|
from homematicip.aio.device import AsyncHeatingThermostat, AsyncHeatingThermostatCompact
|
||||||
from homematicip.aio.group import AsyncHeatingGroup
|
from homematicip.aio.group import AsyncHeatingGroup
|
||||||
from homematicip.base.enums import AbsenceType, GroupType
|
from homematicip.base.enums import AbsenceType
|
||||||
from homematicip.functionalHomes import IndoorClimateHome
|
from homematicip.functionalHomes import IndoorClimateHome
|
||||||
|
|
||||||
from homeassistant.components.climate import ClimateDevice
|
from homeassistant.components.climate import ClimateDevice
|
||||||
from homeassistant.components.climate.const import (
|
from homeassistant.components.climate.const import (
|
||||||
HVAC_MODE_AUTO,
|
HVAC_MODE_AUTO,
|
||||||
|
HVAC_MODE_COOL,
|
||||||
HVAC_MODE_HEAT,
|
HVAC_MODE_HEAT,
|
||||||
|
HVAC_MODE_OFF,
|
||||||
PRESET_AWAY,
|
PRESET_AWAY,
|
||||||
PRESET_BOOST,
|
PRESET_BOOST,
|
||||||
PRESET_ECO,
|
PRESET_ECO,
|
||||||
@ -30,6 +32,9 @@ COOLING_PROFILES = {"PROFILE_4": 3, "PROFILE_5": 4, "PROFILE_6": 5}
|
|||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
ATTR_PRESET_END_TIME = "preset_end_time"
|
||||||
|
PERMANENT_END_TIME = "permanent"
|
||||||
|
|
||||||
HMIP_AUTOMATIC_CM = "AUTOMATIC"
|
HMIP_AUTOMATIC_CM = "AUTOMATIC"
|
||||||
HMIP_MANUAL_CM = "MANUAL"
|
HMIP_MANUAL_CM = "MANUAL"
|
||||||
HMIP_ECO_CM = "ECO"
|
HMIP_ECO_CM = "ECO"
|
||||||
@ -55,15 +60,20 @@ async def async_setup_entry(
|
|||||||
|
|
||||||
|
|
||||||
class HomematicipHeatingGroup(HomematicipGenericDevice, ClimateDevice):
|
class HomematicipHeatingGroup(HomematicipGenericDevice, ClimateDevice):
|
||||||
"""Representation of a HomematicIP heating group."""
|
"""Representation of a HomematicIP heating group.
|
||||||
|
|
||||||
|
Heat mode is supported for all heating devices incl. their defined profiles.
|
||||||
|
Boost is available for radiator thermostats only.
|
||||||
|
Cool mode is only available for floor heating systems, if basically enabled in the hmip app.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, hap: HomematicipHAP, device: AsyncHeatingGroup) -> None:
|
def __init__(self, hap: HomematicipHAP, device: AsyncHeatingGroup) -> None:
|
||||||
"""Initialize heating group."""
|
"""Initialize heating group."""
|
||||||
device.modelType = "HmIP-Heating-Group"
|
device.modelType = "HmIP-Heating-Group"
|
||||||
|
super().__init__(hap, device)
|
||||||
self._simple_heating = None
|
self._simple_heating = None
|
||||||
if device.actualTemperature is None:
|
if device.actualTemperature is None:
|
||||||
self._simple_heating = _get_first_heating_thermostat(device)
|
self._simple_heating = self._get_first_radiator_thermostat()
|
||||||
super().__init__(hap, device)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_info(self):
|
def device_info(self):
|
||||||
@ -105,54 +115,66 @@ class HomematicipHeatingGroup(HomematicipGenericDevice, ClimateDevice):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def hvac_mode(self) -> str:
|
def hvac_mode(self) -> str:
|
||||||
"""Return hvac operation ie. heat, cool mode.
|
"""Return hvac operation ie."""
|
||||||
|
if self._disabled_by_cooling_mode:
|
||||||
Need to be one of HVAC_MODE_*.
|
return HVAC_MODE_OFF
|
||||||
"""
|
|
||||||
if self._device.boostMode:
|
if self._device.boostMode:
|
||||||
return HVAC_MODE_HEAT
|
return HVAC_MODE_HEAT
|
||||||
if self._device.controlMode == HMIP_MANUAL_CM:
|
if self._device.controlMode == HMIP_MANUAL_CM:
|
||||||
return HVAC_MODE_HEAT
|
return HVAC_MODE_HEAT if self._heat_mode_enabled else HVAC_MODE_COOL
|
||||||
|
|
||||||
return HVAC_MODE_AUTO
|
return HVAC_MODE_AUTO
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hvac_modes(self):
|
def hvac_modes(self):
|
||||||
"""Return the list of available hvac operation modes.
|
"""Return the list of available hvac operation modes."""
|
||||||
|
if self._disabled_by_cooling_mode:
|
||||||
|
return [HVAC_MODE_OFF]
|
||||||
|
|
||||||
Need to be a subset of HVAC_MODES.
|
return (
|
||||||
"""
|
[HVAC_MODE_AUTO, HVAC_MODE_HEAT]
|
||||||
return [HVAC_MODE_AUTO, HVAC_MODE_HEAT]
|
if self._heat_mode_enabled
|
||||||
|
else [HVAC_MODE_AUTO, HVAC_MODE_COOL]
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def preset_mode(self):
|
def preset_mode(self):
|
||||||
"""Return the current preset mode, e.g., home, away, temp.
|
"""Return the current preset mode."""
|
||||||
|
|
||||||
Requires SUPPORT_PRESET_MODE.
|
|
||||||
"""
|
|
||||||
if self._device.boostMode:
|
if self._device.boostMode:
|
||||||
return PRESET_BOOST
|
return PRESET_BOOST
|
||||||
if self.hvac_mode == HVAC_MODE_HEAT:
|
if self.hvac_mode in (HVAC_MODE_COOL, HVAC_MODE_HEAT, HVAC_MODE_OFF):
|
||||||
return PRESET_NONE
|
return PRESET_NONE
|
||||||
if self._device.controlMode == HMIP_ECO_CM:
|
if self._device.controlMode == HMIP_ECO_CM:
|
||||||
absence_type = self._home.get_functionalHome(IndoorClimateHome).absenceType
|
if self._indoor_climate.absenceType == AbsenceType.VACATION:
|
||||||
if absence_type == AbsenceType.VACATION:
|
|
||||||
return PRESET_AWAY
|
return PRESET_AWAY
|
||||||
if absence_type in [
|
if self._indoor_climate.absenceType in [
|
||||||
|
AbsenceType.PARTY,
|
||||||
AbsenceType.PERIOD,
|
AbsenceType.PERIOD,
|
||||||
AbsenceType.PERMANENT,
|
AbsenceType.PERMANENT,
|
||||||
AbsenceType.PARTY,
|
|
||||||
]:
|
]:
|
||||||
return PRESET_ECO
|
return PRESET_ECO
|
||||||
|
|
||||||
if self._device.activeProfile:
|
return (
|
||||||
return self._device.activeProfile.name
|
self._device.activeProfile.name
|
||||||
|
if self._device.activeProfile.name in self._device_profile_names
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def preset_modes(self):
|
def preset_modes(self):
|
||||||
"""Return a list of available preset modes incl profiles."""
|
"""Return a list of available preset modes incl. hmip profiles."""
|
||||||
presets = [PRESET_NONE, PRESET_BOOST]
|
# Boost is only available if a radiator thermostat is in the room,
|
||||||
presets.extend(self._device_profile_names)
|
# and heat mode is enabled.
|
||||||
|
profile_names = self._device_profile_names
|
||||||
|
|
||||||
|
presets = []
|
||||||
|
if self._heat_mode_enabled and self._has_radiator_thermostat:
|
||||||
|
if not profile_names:
|
||||||
|
presets.append(PRESET_NONE)
|
||||||
|
presets.append(PRESET_BOOST)
|
||||||
|
|
||||||
|
presets.extend(profile_names)
|
||||||
|
|
||||||
return presets
|
return presets
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -170,10 +192,15 @@ class HomematicipHeatingGroup(HomematicipGenericDevice, ClimateDevice):
|
|||||||
temperature = kwargs.get(ATTR_TEMPERATURE)
|
temperature = kwargs.get(ATTR_TEMPERATURE)
|
||||||
if temperature is None:
|
if temperature is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if self.min_temp <= temperature <= self.max_temp:
|
||||||
await self._device.set_point_temperature(temperature)
|
await self._device.set_point_temperature(temperature)
|
||||||
|
|
||||||
async def async_set_hvac_mode(self, hvac_mode: str) -> Awaitable[None]:
|
async def async_set_hvac_mode(self, hvac_mode: str) -> Awaitable[None]:
|
||||||
"""Set new target hvac mode."""
|
"""Set new target hvac mode."""
|
||||||
|
if hvac_mode not in self.hvac_modes:
|
||||||
|
return
|
||||||
|
|
||||||
if hvac_mode == HVAC_MODE_AUTO:
|
if hvac_mode == HVAC_MODE_AUTO:
|
||||||
await self._device.set_control_mode(HMIP_AUTOMATIC_CM)
|
await self._device.set_control_mode(HMIP_AUTOMATIC_CM)
|
||||||
else:
|
else:
|
||||||
@ -181,18 +208,44 @@ class HomematicipHeatingGroup(HomematicipGenericDevice, ClimateDevice):
|
|||||||
|
|
||||||
async def async_set_preset_mode(self, preset_mode: str) -> Awaitable[None]:
|
async def async_set_preset_mode(self, preset_mode: str) -> Awaitable[None]:
|
||||||
"""Set new preset mode."""
|
"""Set new preset mode."""
|
||||||
|
if preset_mode not in self.preset_modes:
|
||||||
|
return
|
||||||
|
|
||||||
if self._device.boostMode and preset_mode != PRESET_BOOST:
|
if self._device.boostMode and preset_mode != PRESET_BOOST:
|
||||||
await self._device.set_boost(False)
|
await self._device.set_boost(False)
|
||||||
if preset_mode == PRESET_BOOST:
|
if preset_mode == PRESET_BOOST:
|
||||||
await self._device.set_boost()
|
await self._device.set_boost()
|
||||||
if preset_mode in self._device_profile_names:
|
if preset_mode in self._device_profile_names:
|
||||||
profile_idx = self._get_profile_idx_by_name(preset_mode)
|
profile_idx = self._get_profile_idx_by_name(preset_mode)
|
||||||
|
if self._device.controlMode != HMIP_AUTOMATIC_CM:
|
||||||
await self.async_set_hvac_mode(HVAC_MODE_AUTO)
|
await self.async_set_hvac_mode(HVAC_MODE_AUTO)
|
||||||
await self._device.set_active_profile(profile_idx)
|
await self._device.set_active_profile(profile_idx)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_state_attributes(self):
|
||||||
|
"""Return the state attributes of the access point."""
|
||||||
|
state_attr = super().device_state_attributes
|
||||||
|
|
||||||
|
if self._device.controlMode == HMIP_ECO_CM:
|
||||||
|
if self._indoor_climate.absenceType in [
|
||||||
|
AbsenceType.PARTY,
|
||||||
|
AbsenceType.PERIOD,
|
||||||
|
AbsenceType.VACATION,
|
||||||
|
]:
|
||||||
|
state_attr[ATTR_PRESET_END_TIME] = self._indoor_climate.absenceEndTime
|
||||||
|
elif self._indoor_climate.absenceType == AbsenceType.PERMANENT:
|
||||||
|
state_attr[ATTR_PRESET_END_TIME] = PERMANENT_END_TIME
|
||||||
|
|
||||||
|
return state_attr
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _indoor_climate(self):
|
||||||
|
"""Return the hmip indoor climate functional home of this group."""
|
||||||
|
return self._home.get_functionalHome(IndoorClimateHome)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _device_profiles(self):
|
def _device_profiles(self):
|
||||||
"""Return the relevant profiles of the device."""
|
"""Return the relevant profiles."""
|
||||||
return [
|
return [
|
||||||
profile
|
profile
|
||||||
for profile in self._device.profiles
|
for profile in self._device.profiles
|
||||||
@ -218,17 +271,36 @@ class HomematicipHeatingGroup(HomematicipGenericDevice, ClimateDevice):
|
|||||||
return relevant_index[index_name[0]]
|
return relevant_index[index_name[0]]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _relevant_profile_group(self):
|
def _heat_mode_enabled(self):
|
||||||
"""Return the relevant profile groups."""
|
"""Return, if heating mode is enabled."""
|
||||||
return (
|
return not self._device.cooling
|
||||||
HEATING_PROFILES
|
|
||||||
if self._device.groupType == GroupType.HEATING
|
@property
|
||||||
else COOLING_PROFILES
|
def _disabled_by_cooling_mode(self):
|
||||||
|
"""Return, if group is disabled by the cooling mode."""
|
||||||
|
return self._device.cooling and (
|
||||||
|
self._device.coolingIgnored or not self._device.coolingAllowed
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _relevant_profile_group(self):
|
||||||
|
"""Return the relevant profile groups."""
|
||||||
|
if self._disabled_by_cooling_mode:
|
||||||
|
return []
|
||||||
|
|
||||||
def _get_first_heating_thermostat(heating_group: AsyncHeatingGroup):
|
return HEATING_PROFILES if self._heat_mode_enabled else COOLING_PROFILES
|
||||||
"""Return the first HeatingThermostat from a HeatingGroup."""
|
|
||||||
for device in heating_group.devices:
|
@property
|
||||||
if isinstance(device, (AsyncHeatingThermostat, AsyncHeatingThermostatCompact)):
|
def _has_radiator_thermostat(self) -> bool:
|
||||||
|
"""Return, if a radiator thermostat is in the hmip heating group."""
|
||||||
|
return bool(self._get_first_radiator_thermostat())
|
||||||
|
|
||||||
|
def _get_first_radiator_thermostat(self):
|
||||||
|
"""Return the first radiator thermostat from the hmip heating group."""
|
||||||
|
for device in self._device.devices:
|
||||||
|
if isinstance(
|
||||||
|
device, (AsyncHeatingThermostat, AsyncHeatingThermostatCompact)
|
||||||
|
):
|
||||||
return device
|
return device
|
||||||
|
|
||||||
|
return None
|
||||||
|
@ -10,13 +10,18 @@ from homeassistant.components.climate.const import (
|
|||||||
ATTR_PRESET_MODE,
|
ATTR_PRESET_MODE,
|
||||||
ATTR_PRESET_MODES,
|
ATTR_PRESET_MODES,
|
||||||
HVAC_MODE_AUTO,
|
HVAC_MODE_AUTO,
|
||||||
|
HVAC_MODE_COOL,
|
||||||
HVAC_MODE_HEAT,
|
HVAC_MODE_HEAT,
|
||||||
|
HVAC_MODE_OFF,
|
||||||
PRESET_AWAY,
|
PRESET_AWAY,
|
||||||
PRESET_BOOST,
|
PRESET_BOOST,
|
||||||
PRESET_ECO,
|
PRESET_ECO,
|
||||||
PRESET_NONE,
|
|
||||||
)
|
)
|
||||||
from homeassistant.components.homematicip_cloud import DOMAIN as HMIPC_DOMAIN
|
from homeassistant.components.homematicip_cloud import DOMAIN as HMIPC_DOMAIN
|
||||||
|
from homeassistant.components.homematicip_cloud.climate import (
|
||||||
|
ATTR_PRESET_END_TIME,
|
||||||
|
PERMANENT_END_TIME,
|
||||||
|
)
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from .helper import HAPID, async_manipulate_test_data, get_and_check_entity_basics
|
from .helper import HAPID, async_manipulate_test_data, get_and_check_entity_basics
|
||||||
@ -33,7 +38,7 @@ async def test_manually_configured_platform(hass):
|
|||||||
assert not hass.data.get(HMIPC_DOMAIN)
|
assert not hass.data.get(HMIPC_DOMAIN)
|
||||||
|
|
||||||
|
|
||||||
async def test_hmip_heating_group(hass, default_mock_hap):
|
async def test_hmip_heating_group_heat(hass, default_mock_hap):
|
||||||
"""Test HomematicipHeatingGroup."""
|
"""Test HomematicipHeatingGroup."""
|
||||||
entity_id = "climate.badezimmer"
|
entity_id = "climate.badezimmer"
|
||||||
entity_name = "Badezimmer"
|
entity_name = "Badezimmer"
|
||||||
@ -50,12 +55,7 @@ async def test_hmip_heating_group(hass, default_mock_hap):
|
|||||||
assert ha_state.attributes["temperature"] == 5.0
|
assert ha_state.attributes["temperature"] == 5.0
|
||||||
assert ha_state.attributes["current_humidity"] == 47
|
assert ha_state.attributes["current_humidity"] == 47
|
||||||
assert ha_state.attributes[ATTR_PRESET_MODE] == "STD"
|
assert ha_state.attributes[ATTR_PRESET_MODE] == "STD"
|
||||||
assert ha_state.attributes[ATTR_PRESET_MODES] == [
|
assert ha_state.attributes[ATTR_PRESET_MODES] == [PRESET_BOOST, "STD", "Winter"]
|
||||||
PRESET_NONE,
|
|
||||||
PRESET_BOOST,
|
|
||||||
"STD",
|
|
||||||
"Winter",
|
|
||||||
]
|
|
||||||
|
|
||||||
service_call_counter = len(hmip_device.mock_calls)
|
service_call_counter = len(hmip_device.mock_calls)
|
||||||
|
|
||||||
@ -114,12 +114,12 @@ async def test_hmip_heating_group(hass, default_mock_hap):
|
|||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
"climate",
|
"climate",
|
||||||
"set_preset_mode",
|
"set_preset_mode",
|
||||||
{"entity_id": entity_id, "preset_mode": PRESET_NONE},
|
{"entity_id": entity_id, "preset_mode": "STD"},
|
||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
assert len(hmip_device.mock_calls) == service_call_counter + 9
|
assert len(hmip_device.mock_calls) == service_call_counter + 11
|
||||||
assert hmip_device.mock_calls[-1][0] == "set_boost"
|
assert hmip_device.mock_calls[-1][0] == "set_active_profile"
|
||||||
assert hmip_device.mock_calls[-1][1] == (False,)
|
assert hmip_device.mock_calls[-1][1] == (0,)
|
||||||
await async_manipulate_test_data(hass, hmip_device, "boostMode", False)
|
await async_manipulate_test_data(hass, hmip_device, "boostMode", False)
|
||||||
ha_state = hass.states.get(entity_id)
|
ha_state = hass.states.get(entity_id)
|
||||||
assert ha_state.attributes[ATTR_PRESET_MODE] == "STD"
|
assert ha_state.attributes[ATTR_PRESET_MODE] == "STD"
|
||||||
@ -132,7 +132,7 @@ async def test_hmip_heating_group(hass, default_mock_hap):
|
|||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
# No new service call should be in mock_calls.
|
# No new service call should be in mock_calls.
|
||||||
assert len(hmip_device.mock_calls) == service_call_counter + 10
|
assert len(hmip_device.mock_calls) == service_call_counter + 12
|
||||||
# Only fire event from last async_manipulate_test_data available.
|
# Only fire event from last async_manipulate_test_data available.
|
||||||
assert hmip_device.mock_calls[-1][0] == "fire_update_event"
|
assert hmip_device.mock_calls[-1][0] == "fire_update_event"
|
||||||
|
|
||||||
@ -158,7 +158,6 @@ async def test_hmip_heating_group(hass, default_mock_hap):
|
|||||||
ha_state = hass.states.get(entity_id)
|
ha_state = hass.states.get(entity_id)
|
||||||
assert ha_state.attributes[ATTR_PRESET_MODE] == PRESET_ECO
|
assert ha_state.attributes[ATTR_PRESET_MODE] == PRESET_ECO
|
||||||
|
|
||||||
# Not required for hmip, but a posiblity to send no temperature.
|
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
"climate",
|
"climate",
|
||||||
"set_preset_mode",
|
"set_preset_mode",
|
||||||
@ -166,10 +165,173 @@ async def test_hmip_heating_group(hass, default_mock_hap):
|
|||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
assert len(hmip_device.mock_calls) == service_call_counter + 16
|
assert len(hmip_device.mock_calls) == service_call_counter + 18
|
||||||
assert hmip_device.mock_calls[-1][0] == "set_active_profile"
|
assert hmip_device.mock_calls[-1][0] == "set_active_profile"
|
||||||
assert hmip_device.mock_calls[-1][1] == (1,)
|
assert hmip_device.mock_calls[-1][1] == (1,)
|
||||||
|
|
||||||
|
default_mock_hap.home.get_functionalHome(
|
||||||
|
IndoorClimateHome
|
||||||
|
).absenceType = AbsenceType.PERMANENT
|
||||||
|
await async_manipulate_test_data(hass, hmip_device, "controlMode", "ECO")
|
||||||
|
|
||||||
|
ha_state = hass.states.get(entity_id)
|
||||||
|
assert ha_state.attributes[ATTR_PRESET_END_TIME] == PERMANENT_END_TIME
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
"climate",
|
||||||
|
"set_hvac_mode",
|
||||||
|
{"entity_id": entity_id, "hvac_mode": HVAC_MODE_HEAT},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert len(hmip_device.mock_calls) == service_call_counter + 20
|
||||||
|
assert hmip_device.mock_calls[-1][0] == "set_control_mode"
|
||||||
|
assert hmip_device.mock_calls[-1][1] == ("MANUAL",)
|
||||||
|
await async_manipulate_test_data(hass, hmip_device, "controlMode", "MANUAL")
|
||||||
|
ha_state = hass.states.get(entity_id)
|
||||||
|
assert ha_state.state == HVAC_MODE_HEAT
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
"climate",
|
||||||
|
"set_preset_mode",
|
||||||
|
{"entity_id": entity_id, "preset_mode": "Winter"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert len(hmip_device.mock_calls) == service_call_counter + 23
|
||||||
|
assert hmip_device.mock_calls[-1][0] == "set_active_profile"
|
||||||
|
assert hmip_device.mock_calls[-1][1] == (1,)
|
||||||
|
hmip_device.activeProfile = hmip_device.profiles[0]
|
||||||
|
await async_manipulate_test_data(hass, hmip_device, "controlMode", "AUTOMATIC")
|
||||||
|
ha_state = hass.states.get(entity_id)
|
||||||
|
assert ha_state.state == HVAC_MODE_AUTO
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
"climate",
|
||||||
|
"set_hvac_mode",
|
||||||
|
{"entity_id": entity_id, "hvac_mode": "dry"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert len(hmip_device.mock_calls) == service_call_counter + 24
|
||||||
|
# Only fire event from last async_manipulate_test_data available.
|
||||||
|
assert hmip_device.mock_calls[-1][0] == "fire_update_event"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_hmip_heating_group_cool(hass, default_mock_hap):
|
||||||
|
"""Test HomematicipHeatingGroup."""
|
||||||
|
entity_id = "climate.badezimmer"
|
||||||
|
entity_name = "Badezimmer"
|
||||||
|
device_model = None
|
||||||
|
|
||||||
|
ha_state, hmip_device = get_and_check_entity_basics(
|
||||||
|
hass, default_mock_hap, entity_id, entity_name, device_model
|
||||||
|
)
|
||||||
|
|
||||||
|
hmip_device.activeProfile = hmip_device.profiles[3]
|
||||||
|
await async_manipulate_test_data(hass, hmip_device, "cooling", True)
|
||||||
|
await async_manipulate_test_data(hass, hmip_device, "coolingAllowed", True)
|
||||||
|
await async_manipulate_test_data(hass, hmip_device, "coolingIgnored", False)
|
||||||
|
ha_state = hass.states.get(entity_id)
|
||||||
|
|
||||||
|
assert ha_state.state == HVAC_MODE_AUTO
|
||||||
|
assert ha_state.attributes["current_temperature"] == 23.8
|
||||||
|
assert ha_state.attributes["min_temp"] == 5.0
|
||||||
|
assert ha_state.attributes["max_temp"] == 30.0
|
||||||
|
assert ha_state.attributes["temperature"] == 5.0
|
||||||
|
assert ha_state.attributes["current_humidity"] == 47
|
||||||
|
assert ha_state.attributes[ATTR_PRESET_MODE] == "Cool1"
|
||||||
|
assert ha_state.attributes[ATTR_PRESET_MODES] == ["Cool1", "Cool2"]
|
||||||
|
|
||||||
|
service_call_counter = len(hmip_device.mock_calls)
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
"climate",
|
||||||
|
"set_hvac_mode",
|
||||||
|
{"entity_id": entity_id, "hvac_mode": HVAC_MODE_COOL},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert len(hmip_device.mock_calls) == service_call_counter + 1
|
||||||
|
assert hmip_device.mock_calls[-1][0] == "set_control_mode"
|
||||||
|
assert hmip_device.mock_calls[-1][1] == ("MANUAL",)
|
||||||
|
await async_manipulate_test_data(hass, hmip_device, "controlMode", "MANUAL")
|
||||||
|
ha_state = hass.states.get(entity_id)
|
||||||
|
assert ha_state.state == HVAC_MODE_COOL
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
"climate",
|
||||||
|
"set_hvac_mode",
|
||||||
|
{"entity_id": entity_id, "hvac_mode": HVAC_MODE_AUTO},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert len(hmip_device.mock_calls) == service_call_counter + 3
|
||||||
|
assert hmip_device.mock_calls[-1][0] == "set_control_mode"
|
||||||
|
assert hmip_device.mock_calls[-1][1] == ("AUTOMATIC",)
|
||||||
|
await async_manipulate_test_data(hass, hmip_device, "controlMode", "AUTO")
|
||||||
|
ha_state = hass.states.get(entity_id)
|
||||||
|
assert ha_state.state == HVAC_MODE_AUTO
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
"climate",
|
||||||
|
"set_preset_mode",
|
||||||
|
{"entity_id": entity_id, "preset_mode": "Cool2"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert len(hmip_device.mock_calls) == service_call_counter + 6
|
||||||
|
assert hmip_device.mock_calls[-1][0] == "set_active_profile"
|
||||||
|
assert hmip_device.mock_calls[-1][1] == (4,)
|
||||||
|
|
||||||
|
hmip_device.activeProfile = hmip_device.profiles[4]
|
||||||
|
await async_manipulate_test_data(hass, hmip_device, "cooling", True)
|
||||||
|
await async_manipulate_test_data(hass, hmip_device, "coolingAllowed", False)
|
||||||
|
await async_manipulate_test_data(hass, hmip_device, "coolingIgnored", False)
|
||||||
|
ha_state = hass.states.get(entity_id)
|
||||||
|
|
||||||
|
assert ha_state.state == HVAC_MODE_OFF
|
||||||
|
assert ha_state.attributes[ATTR_PRESET_MODE] == "none"
|
||||||
|
assert ha_state.attributes[ATTR_PRESET_MODES] == []
|
||||||
|
|
||||||
|
hmip_device.activeProfile = hmip_device.profiles[4]
|
||||||
|
await async_manipulate_test_data(hass, hmip_device, "cooling", True)
|
||||||
|
await async_manipulate_test_data(hass, hmip_device, "coolingAllowed", True)
|
||||||
|
await async_manipulate_test_data(hass, hmip_device, "coolingIgnored", True)
|
||||||
|
ha_state = hass.states.get(entity_id)
|
||||||
|
|
||||||
|
assert ha_state.state == HVAC_MODE_OFF
|
||||||
|
assert ha_state.attributes[ATTR_PRESET_MODE] == "none"
|
||||||
|
assert ha_state.attributes[ATTR_PRESET_MODES] == []
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
"climate",
|
||||||
|
"set_preset_mode",
|
||||||
|
{"entity_id": entity_id, "preset_mode": "Cool2"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert len(hmip_device.mock_calls) == service_call_counter + 12
|
||||||
|
# fire_update_event shows that set_active_profile has not been called.
|
||||||
|
assert hmip_device.mock_calls[-1][0] == "fire_update_event"
|
||||||
|
|
||||||
|
hmip_device.activeProfile = hmip_device.profiles[4]
|
||||||
|
await async_manipulate_test_data(hass, hmip_device, "cooling", True)
|
||||||
|
await async_manipulate_test_data(hass, hmip_device, "coolingAllowed", True)
|
||||||
|
await async_manipulate_test_data(hass, hmip_device, "coolingIgnored", False)
|
||||||
|
ha_state = hass.states.get(entity_id)
|
||||||
|
|
||||||
|
assert ha_state.state == HVAC_MODE_AUTO
|
||||||
|
assert ha_state.attributes[ATTR_PRESET_MODE] == "Cool2"
|
||||||
|
assert ha_state.attributes[ATTR_PRESET_MODES] == ["Cool1", "Cool2"]
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
"climate",
|
||||||
|
"set_preset_mode",
|
||||||
|
{"entity_id": entity_id, "preset_mode": "Cool2"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert len(hmip_device.mock_calls) == service_call_counter + 17
|
||||||
|
assert hmip_device.mock_calls[-1][0] == "set_active_profile"
|
||||||
|
assert hmip_device.mock_calls[-1][1] == (4,)
|
||||||
|
|
||||||
|
|
||||||
async def test_hmip_climate_services(hass, mock_hap_with_service):
|
async def test_hmip_climate_services(hass, mock_hap_with_service):
|
||||||
"""Test HomematicipHeatingGroup."""
|
"""Test HomematicipHeatingGroup."""
|
||||||
|
6
tests/fixtures/homematicip_cloud.json
vendored
6
tests/fixtures/homematicip_cloud.json
vendored
@ -4662,7 +4662,7 @@
|
|||||||
"enabled": true,
|
"enabled": true,
|
||||||
"groupId": "00000000-0000-0000-0000-000000000021",
|
"groupId": "00000000-0000-0000-0000-000000000021",
|
||||||
"index": "PROFILE_4",
|
"index": "PROFILE_4",
|
||||||
"name": "",
|
"name": "Cool1",
|
||||||
"profileId": "00000000-0000-0000-0000-000000000041",
|
"profileId": "00000000-0000-0000-0000-000000000041",
|
||||||
"visible": true
|
"visible": true
|
||||||
},
|
},
|
||||||
@ -4670,9 +4670,9 @@
|
|||||||
"enabled": true,
|
"enabled": true,
|
||||||
"groupId": "00000000-0000-0000-0000-000000000021",
|
"groupId": "00000000-0000-0000-0000-000000000021",
|
||||||
"index": "PROFILE_5",
|
"index": "PROFILE_5",
|
||||||
"name": "",
|
"name": "Cool2",
|
||||||
"profileId": "00000000-0000-0000-0000-000000000042",
|
"profileId": "00000000-0000-0000-0000-000000000042",
|
||||||
"visible": false
|
"visible": true
|
||||||
},
|
},
|
||||||
"PROFILE_6": {
|
"PROFILE_6": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user