Add test to Homematic IP Cloud climate (#27472)
This commit is contained in:
parent
6317ef1324
commit
f979eca83a
4 changed files with 360 additions and 3 deletions
|
@ -220,6 +220,7 @@ class HomematicipHAP:
|
|||
await self.hass.config_entries.async_forward_entry_unload(
|
||||
self.config_entry, component
|
||||
)
|
||||
self.hmip_device_by_entity_id = {}
|
||||
return True
|
||||
|
||||
async def get_hap(
|
||||
|
|
|
@ -35,6 +35,7 @@ def get_and_check_entity_basics(
|
|||
assert ha_state.name == entity_name
|
||||
|
||||
hmip_device = default_mock_hap.hmip_device_by_entity_id.get(entity_id)
|
||||
|
||||
if hmip_device:
|
||||
if isinstance(hmip_device, AsyncDevice):
|
||||
assert ha_state.attributes[ATTR_IS_GROUP] is False
|
||||
|
@ -85,14 +86,20 @@ class HomeTemplate(Home):
|
|||
super().__init__(connection=connection)
|
||||
self.label = "Access Point"
|
||||
self.model_type = "HmIP-HAP"
|
||||
self.init_json_state = None
|
||||
|
||||
def init_home(self, json_path=HOME_JSON):
|
||||
"""Init template with json."""
|
||||
json_state = json.loads(load_fixture(HOME_JSON), encoding="UTF-8")
|
||||
self.update_home(json_state=json_state, clearConfig=True)
|
||||
self._generate_mocks()
|
||||
self.init_json_state = json.loads(load_fixture(HOME_JSON), encoding="UTF-8")
|
||||
self.update_home(json_state=self.init_json_state, clearConfig=True)
|
||||
return self
|
||||
|
||||
def update_home(self, json_state, clearConfig: bool = False):
|
||||
"""Update home and ensure that mocks are created."""
|
||||
result = super().update_home(json_state, clearConfig)
|
||||
self._generate_mocks()
|
||||
return result
|
||||
|
||||
def _generate_mocks(self):
|
||||
"""Generate mocks for groups and devices."""
|
||||
mock_devices = []
|
||||
|
@ -105,6 +112,10 @@ class HomeTemplate(Home):
|
|||
mock_groups.append(_get_mock(group))
|
||||
self.groups = mock_groups
|
||||
|
||||
def download_configuration(self):
|
||||
"""Return the initial json config."""
|
||||
return self.init_json_state
|
||||
|
||||
def get_async_home_mock(self):
|
||||
"""
|
||||
Create Mock for Async_Home. based on template to be used for testing.
|
||||
|
@ -123,6 +134,10 @@ class HomeTemplate(Home):
|
|||
|
||||
def _get_mock(instance):
|
||||
"""Create a mock and copy instance attributes over mock."""
|
||||
if isinstance(instance, Mock):
|
||||
instance.__dict__.update(instance._mock_wraps.__dict__) # pylint: disable=W0212
|
||||
return instance
|
||||
|
||||
mock = Mock(spec=instance, wraps=instance)
|
||||
mock.__dict__.update(instance.__dict__)
|
||||
return mock
|
||||
|
|
230
tests/components/homematicip_cloud/test_climate.py
Normal file
230
tests/components/homematicip_cloud/test_climate.py
Normal file
|
@ -0,0 +1,230 @@
|
|||
"""Tests for HomematicIP Cloud climate."""
|
||||
import datetime
|
||||
|
||||
from homematicip.base.enums import AbsenceType
|
||||
from homematicip.functionalHomes import IndoorClimateHome
|
||||
|
||||
from homeassistant.components.climate.const import (
|
||||
ATTR_CURRENT_TEMPERATURE,
|
||||
ATTR_PRESET_MODE,
|
||||
ATTR_PRESET_MODES,
|
||||
HVAC_MODE_AUTO,
|
||||
HVAC_MODE_HEAT,
|
||||
PRESET_AWAY,
|
||||
PRESET_BOOST,
|
||||
PRESET_ECO,
|
||||
PRESET_NONE,
|
||||
)
|
||||
|
||||
from .helper import HAPID, async_manipulate_test_data, get_and_check_entity_basics
|
||||
|
||||
|
||||
async def test_hmip_heating_group(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
|
||||
)
|
||||
|
||||
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] == PRESET_NONE
|
||||
assert ha_state.attributes[ATTR_PRESET_MODES] == [PRESET_NONE, PRESET_BOOST]
|
||||
|
||||
service_call_counter = len(hmip_device.mock_calls)
|
||||
|
||||
await hass.services.async_call(
|
||||
"climate",
|
||||
"set_temperature",
|
||||
{"entity_id": entity_id, "temperature": 22.5},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(hmip_device.mock_calls) == service_call_counter + 1
|
||||
assert hmip_device.mock_calls[-1][0] == "set_point_temperature"
|
||||
assert hmip_device.mock_calls[-1][1] == (22.5,)
|
||||
await async_manipulate_test_data(hass, hmip_device, "actualTemperature", 22.5)
|
||||
ha_state = hass.states.get(entity_id)
|
||||
assert ha_state.attributes[ATTR_CURRENT_TEMPERATURE] == 22.5
|
||||
|
||||
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 + 3
|
||||
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_hvac_mode",
|
||||
{"entity_id": entity_id, "hvac_mode": HVAC_MODE_AUTO},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(hmip_device.mock_calls) == service_call_counter + 5
|
||||
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": PRESET_BOOST},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(hmip_device.mock_calls) == service_call_counter + 7
|
||||
assert hmip_device.mock_calls[-1][0] == "set_boost"
|
||||
assert hmip_device.mock_calls[-1][1] == ()
|
||||
await async_manipulate_test_data(hass, hmip_device, "boostMode", True)
|
||||
ha_state = hass.states.get(entity_id)
|
||||
assert ha_state.attributes[ATTR_PRESET_MODE] == PRESET_BOOST
|
||||
|
||||
await hass.services.async_call(
|
||||
"climate",
|
||||
"set_preset_mode",
|
||||
{"entity_id": entity_id, "preset_mode": PRESET_NONE},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(hmip_device.mock_calls) == service_call_counter + 9
|
||||
assert hmip_device.mock_calls[-1][0] == "set_boost"
|
||||
assert hmip_device.mock_calls[-1][1] == (False,)
|
||||
await async_manipulate_test_data(hass, hmip_device, "boostMode", False)
|
||||
ha_state = hass.states.get(entity_id)
|
||||
assert ha_state.attributes[ATTR_PRESET_MODE] == PRESET_NONE
|
||||
|
||||
# Not required for hmip, but a posiblity to send no temperature.
|
||||
await hass.services.async_call(
|
||||
"climate",
|
||||
"set_temperature",
|
||||
{"entity_id": entity_id, "target_temp_low": 10, "target_temp_high": 10},
|
||||
blocking=True,
|
||||
)
|
||||
# No new service call should be in mock_calls.
|
||||
assert len(hmip_device.mock_calls) == service_call_counter + 10
|
||||
# Only fire event from last async_manipulate_test_data available.
|
||||
assert hmip_device.mock_calls[-1][0] == "fire_update_event"
|
||||
|
||||
await async_manipulate_test_data(hass, hmip_device, "controlMode", "ECO")
|
||||
await async_manipulate_test_data(
|
||||
hass,
|
||||
default_mock_hap.home.get_functionalHome(IndoorClimateHome),
|
||||
"absenceType",
|
||||
AbsenceType.VACATION,
|
||||
fire_device=hmip_device,
|
||||
)
|
||||
ha_state = hass.states.get(entity_id)
|
||||
assert ha_state.attributes[ATTR_PRESET_MODE] == PRESET_AWAY
|
||||
|
||||
await async_manipulate_test_data(hass, hmip_device, "controlMode", "ECO")
|
||||
await async_manipulate_test_data(
|
||||
hass,
|
||||
default_mock_hap.home.get_functionalHome(IndoorClimateHome),
|
||||
"absenceType",
|
||||
AbsenceType.PERIOD,
|
||||
fire_device=hmip_device,
|
||||
)
|
||||
ha_state = hass.states.get(entity_id)
|
||||
assert ha_state.attributes[ATTR_PRESET_MODE] == PRESET_ECO
|
||||
|
||||
|
||||
async def test_hmip_climate_services(hass, mock_hap_with_service):
|
||||
"""Test HomematicipHeatingGroup."""
|
||||
|
||||
home = mock_hap_with_service.home
|
||||
|
||||
await hass.services.async_call(
|
||||
"homematicip_cloud",
|
||||
"activate_eco_mode_with_duration",
|
||||
{"duration": 60, "accesspoint_id": HAPID},
|
||||
blocking=True,
|
||||
)
|
||||
assert home.mock_calls[-1][0] == "activate_absence_with_duration"
|
||||
assert home.mock_calls[-1][1] == (60,)
|
||||
|
||||
await hass.services.async_call(
|
||||
"homematicip_cloud",
|
||||
"activate_eco_mode_with_duration",
|
||||
{"duration": 60},
|
||||
blocking=True,
|
||||
)
|
||||
assert home.mock_calls[-1][0] == "activate_absence_with_duration"
|
||||
assert home.mock_calls[-1][1] == (60,)
|
||||
|
||||
await hass.services.async_call(
|
||||
"homematicip_cloud",
|
||||
"activate_eco_mode_with_period",
|
||||
{"endtime": "2019-02-17 14:00", "accesspoint_id": HAPID},
|
||||
blocking=True,
|
||||
)
|
||||
assert home.mock_calls[-1][0] == "activate_absence_with_period"
|
||||
assert home.mock_calls[-1][1] == (datetime.datetime(2019, 2, 17, 14, 0),)
|
||||
|
||||
await hass.services.async_call(
|
||||
"homematicip_cloud",
|
||||
"activate_eco_mode_with_period",
|
||||
{"endtime": "2019-02-17 14:00"},
|
||||
blocking=True,
|
||||
)
|
||||
assert home.mock_calls[-1][0] == "activate_absence_with_period"
|
||||
assert home.mock_calls[-1][1] == (datetime.datetime(2019, 2, 17, 14, 0),)
|
||||
|
||||
await hass.services.async_call(
|
||||
"homematicip_cloud",
|
||||
"activate_vacation",
|
||||
{"endtime": "2019-02-17 14:00", "temperature": 18.5, "accesspoint_id": HAPID},
|
||||
blocking=True,
|
||||
)
|
||||
assert home.mock_calls[-1][0] == "activate_vacation"
|
||||
assert home.mock_calls[-1][1] == (datetime.datetime(2019, 2, 17, 14, 0), 18.5)
|
||||
|
||||
await hass.services.async_call(
|
||||
"homematicip_cloud",
|
||||
"activate_vacation",
|
||||
{"endtime": "2019-02-17 14:00", "temperature": 18.5},
|
||||
blocking=True,
|
||||
)
|
||||
assert home.mock_calls[-1][0] == "activate_vacation"
|
||||
assert home.mock_calls[-1][1] == (datetime.datetime(2019, 2, 17, 14, 0), 18.5)
|
||||
|
||||
await hass.services.async_call(
|
||||
"homematicip_cloud",
|
||||
"deactivate_eco_mode",
|
||||
{"accesspoint_id": HAPID},
|
||||
blocking=True,
|
||||
)
|
||||
assert home.mock_calls[-1][0] == "deactivate_absence"
|
||||
assert home.mock_calls[-1][1] == ()
|
||||
|
||||
await hass.services.async_call(
|
||||
"homematicip_cloud", "deactivate_eco_mode", blocking=True
|
||||
)
|
||||
assert home.mock_calls[-1][0] == "deactivate_absence"
|
||||
assert home.mock_calls[-1][1] == ()
|
||||
|
||||
await hass.services.async_call(
|
||||
"homematicip_cloud",
|
||||
"deactivate_vacation",
|
||||
{"accesspoint_id": HAPID},
|
||||
blocking=True,
|
||||
)
|
||||
assert home.mock_calls[-1][0] == "deactivate_vacation"
|
||||
assert home.mock_calls[-1][1] == ()
|
||||
|
||||
await hass.services.async_call(
|
||||
"homematicip_cloud", "deactivate_vacation", blocking=True
|
||||
)
|
||||
assert home.mock_calls[-1][0] == "deactivate_vacation"
|
||||
assert home.mock_calls[-1][1] == ()
|
111
tests/components/homematicip_cloud/test_device.py
Normal file
111
tests/components/homematicip_cloud/test_device.py
Normal file
|
@ -0,0 +1,111 @@
|
|||
"""Common tests for HomematicIP devices."""
|
||||
from homeassistant.const import STATE_ON, STATE_UNAVAILABLE
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
|
||||
from .helper import async_manipulate_test_data, get_and_check_entity_basics
|
||||
|
||||
|
||||
async def test_hmip_remove_device(hass, default_mock_hap):
|
||||
"""Test Remove of hmip device."""
|
||||
entity_id = "light.treppe"
|
||||
entity_name = "Treppe"
|
||||
device_model = "HmIP-BSL"
|
||||
|
||||
ha_state, hmip_device = get_and_check_entity_basics(
|
||||
hass, default_mock_hap, entity_id, entity_name, device_model
|
||||
)
|
||||
|
||||
assert ha_state.state == STATE_ON
|
||||
assert hmip_device
|
||||
|
||||
device_registry = await dr.async_get_registry(hass)
|
||||
entity_registry = await er.async_get_registry(hass)
|
||||
|
||||
pre_device_count = len(device_registry.devices)
|
||||
pre_entity_count = len(entity_registry.entities)
|
||||
pre_mapping_count = len(default_mock_hap.hmip_device_by_entity_id)
|
||||
|
||||
hmip_device.fire_remove_event()
|
||||
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(device_registry.devices) == pre_device_count - 1
|
||||
assert len(entity_registry.entities) == pre_entity_count - 3
|
||||
assert len(default_mock_hap.hmip_device_by_entity_id) == pre_mapping_count - 3
|
||||
|
||||
|
||||
async def test_hmip_remove_group(hass, default_mock_hap):
|
||||
"""Test Remove of hmip group."""
|
||||
entity_id = "switch.strom_group"
|
||||
entity_name = "Strom Group"
|
||||
device_model = None
|
||||
|
||||
ha_state, hmip_device = get_and_check_entity_basics(
|
||||
hass, default_mock_hap, entity_id, entity_name, device_model
|
||||
)
|
||||
|
||||
assert ha_state.state == STATE_ON
|
||||
assert hmip_device
|
||||
|
||||
device_registry = await dr.async_get_registry(hass)
|
||||
entity_registry = await er.async_get_registry(hass)
|
||||
|
||||
pre_device_count = len(device_registry.devices)
|
||||
pre_entity_count = len(entity_registry.entities)
|
||||
pre_mapping_count = len(default_mock_hap.hmip_device_by_entity_id)
|
||||
|
||||
hmip_device.fire_remove_event()
|
||||
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(device_registry.devices) == pre_device_count
|
||||
assert len(entity_registry.entities) == pre_entity_count - 1
|
||||
assert len(default_mock_hap.hmip_device_by_entity_id) == pre_mapping_count - 1
|
||||
|
||||
|
||||
async def test_all_devices_unavailable_when_hap_not_connected(hass, default_mock_hap):
|
||||
"""Test make all devices unavaulable when hap is not connected."""
|
||||
entity_id = "light.treppe"
|
||||
entity_name = "Treppe"
|
||||
device_model = "HmIP-BSL"
|
||||
|
||||
ha_state, hmip_device = get_and_check_entity_basics(
|
||||
hass, default_mock_hap, entity_id, entity_name, device_model
|
||||
)
|
||||
|
||||
assert ha_state.state == STATE_ON
|
||||
assert hmip_device
|
||||
|
||||
assert default_mock_hap.home.connected
|
||||
|
||||
await async_manipulate_test_data(hass, default_mock_hap.home, "connected", False)
|
||||
|
||||
ha_state = hass.states.get(entity_id)
|
||||
assert ha_state.state == STATE_UNAVAILABLE
|
||||
|
||||
|
||||
async def test_hap_reconnected(hass, default_mock_hap):
|
||||
"""Test reconnect hap."""
|
||||
entity_id = "light.treppe"
|
||||
entity_name = "Treppe"
|
||||
device_model = "HmIP-BSL"
|
||||
|
||||
ha_state, hmip_device = get_and_check_entity_basics(
|
||||
hass, default_mock_hap, entity_id, entity_name, device_model
|
||||
)
|
||||
|
||||
assert ha_state.state == STATE_ON
|
||||
assert hmip_device
|
||||
|
||||
assert default_mock_hap.home.connected
|
||||
|
||||
await async_manipulate_test_data(hass, default_mock_hap.home, "connected", False)
|
||||
|
||||
ha_state = hass.states.get(entity_id)
|
||||
assert ha_state.state == STATE_UNAVAILABLE
|
||||
|
||||
default_mock_hap._accesspoint_connected = False # pylint: disable=W0212
|
||||
await async_manipulate_test_data(hass, default_mock_hap.home, "connected", True)
|
||||
await hass.async_block_till_done()
|
||||
ha_state = hass.states.get(entity_id)
|
||||
assert ha_state.state == STATE_ON
|
Loading…
Add table
Reference in a new issue