Plugwise test maintenance (#126421)

This commit is contained in:
Bouwe Westerdijk 2024-09-24 18:11:17 +02:00 committed by GitHub
parent 31a1ad8409
commit 962b9915f0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 174 additions and 419 deletions

View File

@ -74,7 +74,7 @@ def mock_smile_config_flow() -> Generator[MagicMock]:
@pytest.fixture @pytest.fixture
def mock_smile_adam() -> Generator[MagicMock]: def mock_smile_adam() -> Generator[MagicMock]:
"""Create a Mock Adam environment for testing exceptions.""" """Create a Mock Adam environment for testing exceptions."""
chosen_env = "adam_multiple_devices_per_zone" chosen_env = "m_adam_multiple_devices_per_zone"
with patch( with patch(
"homeassistant.components.plugwise.coordinator.Smile", autospec=True "homeassistant.components.plugwise.coordinator.Smile", autospec=True
@ -309,6 +309,34 @@ def mock_smile_p1_2() -> Generator[MagicMock]:
yield smile yield smile
@pytest.fixture
def mock_smile_legacy_anna() -> Generator[None, MagicMock, None]:
"""Create a Mock legacy Anna environment for testing exceptions."""
chosen_env = "legacy_anna"
with patch(
"homeassistant.components.plugwise.coordinator.Smile", autospec=True
) as smile_mock:
smile = smile_mock.return_value
smile.gateway_id = "0000aaaa0000aaaa0000aaaa0000aa00"
smile.heater_id = "04e4cbfe7f4340f090f85ec3b9e6a950"
smile.smile_version = "1.8.22"
smile.smile_type = "thermostat"
smile.smile_hostname = "smile98765"
smile.smile_model = "Gateway"
smile.smile_model_id = None
smile.smile_name = "Smile Anna"
smile.connect.return_value = True
all_data = _read_json(chosen_env, "all_data")
smile.async_update.return_value = PlugwiseData(
all_data["gateway"], all_data["devices"]
)
yield smile
@pytest.fixture @pytest.fixture
def mock_stretch() -> Generator[MagicMock]: def mock_stretch() -> Generator[MagicMock]:
"""Create a Mock Stretch environment for testing exceptions.""" """Create a Mock Stretch environment for testing exceptions."""

View File

@ -0,0 +1,68 @@
{
"devices": {
"0000aaaa0000aaaa0000aaaa0000aa00": {
"dev_class": "gateway",
"firmware": "1.8.22",
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
"mac_address": "01:23:45:67:89:AB",
"model": "Gateway",
"name": "Smile Anna",
"vendor": "Plugwise"
},
"04e4cbfe7f4340f090f85ec3b9e6a950": {
"binary_sensors": {
"flame_state": true,
"heating_state": true
},
"dev_class": "heater_central",
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
"maximum_boiler_temperature": {
"lower_bound": 50.0,
"resolution": 1.0,
"setpoint": 50.0,
"upper_bound": 90.0
},
"model": "Generic heater",
"name": "OpenTherm",
"sensors": {
"dhw_temperature": 51.2,
"intended_boiler_temperature": 17.0,
"modulation_level": 0.0,
"return_temperature": 21.7,
"water_pressure": 1.2,
"water_temperature": 23.6
},
"vendor": "Bosch Thermotechniek B.V."
},
"0d266432d64443e283b5d708ae98b455": {
"active_preset": "home",
"dev_class": "thermostat",
"firmware": "2017-03-13T11:54:58+01:00",
"hardware": "6539-1301-500",
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
"mode": "heat",
"model": "ThermoTouch",
"name": "Anna",
"preset_modes": ["away", "vacation", "asleep", "home", "no_frost"],
"sensors": {
"illuminance": 151,
"setpoint": 20.5,
"temperature": 20.4
},
"thermostat": {
"lower_bound": 4.0,
"resolution": 0.1,
"setpoint": 20.5,
"upper_bound": 30.0
},
"vendor": "Plugwise"
}
},
"gateway": {
"cooling_present": false,
"gateway_id": "0000aaaa0000aaaa0000aaaa0000aa00",
"heater_id": "04e4cbfe7f4340f090f85ec3b9e6a950",
"item_count": 41,
"smile_name": "Smile Anna"
}
}

View File

@ -403,14 +403,6 @@
"e7693eb9582644e5b865dba8d4447cf1": { "e7693eb9582644e5b865dba8d4447cf1": {
"active_preset": "no_frost", "active_preset": "no_frost",
"available": true, "available": true,
"available_schedules": [
"CV Roan",
"Bios Schema met Film Avond",
"GF7 Woonkamer",
"Badkamer Schema",
"CV Jessie",
"off"
],
"binary_sensors": { "binary_sensors": {
"low_battery": false "low_battery": false
}, },
@ -423,7 +415,6 @@
"model_id": "106-03", "model_id": "106-03",
"name": "CV Kraan Garage", "name": "CV Kraan Garage",
"preset_modes": ["home", "asleep", "away", "vacation", "no_frost"], "preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
"select_schedule": "off",
"sensors": { "sensors": {
"battery": 68, "battery": 68,
"setpoint": 5.5, "setpoint": 5.5,

View File

@ -1,340 +0,0 @@
{
"devices": {
"0000aaaa0000aaaa0000aaaa0000aa00": {
"dev_class": "gateway",
"firmware": "2.3.12",
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
"mac_address": "01:23:45:67:89:AB",
"model": "Gateway",
"name": "Stretch",
"vendor": "Plugwise",
"zigbee_mac_address": "ABCD012345670101"
},
"09c8ce93d7064fa6a233c0e4c2449bfe": {
"dev_class": "lamp",
"firmware": "2011-06-27T10:52:18+02:00",
"hardware": "0000-0440-0107",
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
"model": "Circle type F",
"name": "kerstboom buiten 043B016",
"sensors": {
"electricity_consumed": 0.0,
"electricity_consumed_interval": 0.0,
"electricity_produced": 0.0
},
"switches": {
"lock": false,
"relay": false
},
"vendor": "Plugwise",
"zigbee_mac_address": "ABCD012345670A01"
},
"199fd4b2caa44197aaf5b3128f6464ed": {
"dev_class": "airconditioner",
"firmware": "2011-06-27T10:52:18+02:00",
"hardware": "6539-0701-4026",
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
"model": "Circle type F",
"name": "Airco 25F69E3",
"sensors": {
"electricity_consumed": 2.06,
"electricity_consumed_interval": 1.62,
"electricity_produced": 0.0,
"electricity_produced_interval": 0.0
},
"switches": {
"lock": false,
"relay": true
},
"vendor": "Plugwise",
"zigbee_mac_address": "ABCD012345670A10"
},
"24b2ed37c8964c73897db6340a39c129": {
"dev_class": "router",
"firmware": "2011-06-27T10:47:37+02:00",
"hardware": "6539-0700-7325",
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
"model": "Circle+ type F",
"name": "MK Netwerk 1A4455E",
"sensors": {
"electricity_consumed": 4.63,
"electricity_consumed_interval": 0.65,
"electricity_produced": 0.0,
"electricity_produced_interval": 0.0
},
"switches": {
"lock": true,
"relay": true
},
"vendor": "Plugwise",
"zigbee_mac_address": "0123456789AB"
},
"2587a7fcdd7e482dab03fda256076b4b": {
"dev_class": "zz_misc",
"firmware": "2011-06-27T10:52:18+02:00",
"hardware": "0000-0440-0107",
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
"model": "Circle type F",
"name": "00469CA1",
"sensors": {
"electricity_consumed": 0.0,
"electricity_consumed_interval": 0.0,
"electricity_produced": 0.0
},
"switches": {
"lock": false,
"relay": true
},
"vendor": "Plugwise",
"zigbee_mac_address": "ABCD012345670A16"
},
"2cc9a0fe70ef4441a9e4f55dfd64b776": {
"dev_class": "lamp",
"firmware": "2011-06-27T10:52:18+02:00",
"hardware": "6539-0701-4026",
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
"model": "Circle type F",
"name": "Lamp TV 025F698F",
"sensors": {
"electricity_consumed": 4.0,
"electricity_consumed_interval": 0.58,
"electricity_produced": 0.0,
"electricity_produced_interval": 0.0
},
"switches": {
"lock": false,
"relay": true
},
"vendor": "Plugwise",
"zigbee_mac_address": "ABCD012345670A15"
},
"305452ce97c243c0a7b4ab2a4ebfe6e3": {
"dev_class": "lamp",
"firmware": "2011-06-27T10:52:18+02:00",
"hardware": "6539-0701-4026",
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
"model": "Circle type F",
"name": "Lamp piano 025F6819",
"sensors": {
"electricity_consumed": 0.0,
"electricity_consumed_interval": 0.0,
"electricity_produced": 0.0,
"electricity_produced_interval": 0.0
},
"switches": {
"lock": false,
"relay": false
},
"vendor": "Plugwise",
"zigbee_mac_address": "ABCD012345670A05"
},
"33a1c784a9ff4c2d8766a0212714be09": {
"dev_class": "lighting",
"firmware": "2011-06-27T10:52:18+02:00",
"hardware": "6539-0701-4026",
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
"model": "Circle type F",
"name": "Barverlichting",
"sensors": {
"electricity_consumed": 0.0,
"electricity_consumed_interval": 0.0,
"electricity_produced": 0.0,
"electricity_produced_interval": 0.0
},
"switches": {
"lock": false,
"relay": false
},
"vendor": "Plugwise",
"zigbee_mac_address": "ABCD012345670A13"
},
"407aa1c1099d463c9137a3a9eda787fd": {
"dev_class": "zz_misc",
"firmware": "2011-06-27T10:52:18+02:00",
"hardware": "0000-0440-0107",
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
"model": "Circle type F",
"name": "0043B013",
"sensors": {
"electricity_consumed": 0.0,
"electricity_consumed_interval": 0.0,
"electricity_produced": 0.0
},
"switches": {
"lock": false,
"relay": false
},
"vendor": "Plugwise",
"zigbee_mac_address": "ABCD012345670A09"
},
"6518f3f72a82486c97b91e26f2e9bd1d": {
"dev_class": "charger",
"firmware": "2011-06-27T10:52:18+02:00",
"hardware": "6539-0701-4026",
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
"model": "Circle type F",
"name": "Bed 025F6768",
"sensors": {
"electricity_consumed": 0.0,
"electricity_consumed_interval": 0.0,
"electricity_produced": 0.0,
"electricity_produced_interval": 0.0
},
"switches": {
"lock": false,
"relay": true
},
"vendor": "Plugwise",
"zigbee_mac_address": "ABCD012345670A14"
},
"713427748874454ca1eb4488d7919cf2": {
"dev_class": "freezer",
"firmware": "2011-06-27T10:52:18+02:00",
"hardware": "0000-0440-0107",
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
"model": "Circle type F",
"name": "Leeg 043220D",
"sensors": {
"electricity_consumed": 0.0,
"electricity_consumed_interval": 0.0,
"electricity_produced": 0.0
},
"switches": {
"lock": false,
"relay": false
},
"vendor": "Plugwise",
"zigbee_mac_address": "ABCD012345670A12"
},
"71e3e65ffc5a41518b19460c6e8ee34f": {
"dev_class": "tv",
"firmware": "2011-06-27T10:52:18+02:00",
"hardware": "0000-0440-0107",
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
"model": "Circle type F",
"name": "Leeg 043AEC6",
"sensors": {
"electricity_consumed": 0.0,
"electricity_consumed_interval": 0.0,
"electricity_produced": 0.0
},
"switches": {
"lock": false,
"relay": false
},
"vendor": "Plugwise",
"zigbee_mac_address": "ABCD012345670A08"
},
"828f6ce1e36744689baacdd6ddb1d12c": {
"dev_class": "washingmachine",
"firmware": "2011-06-27T10:52:18+02:00",
"hardware": "0000-0440-0107",
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
"model": "Circle type F",
"name": "Wasmachine 043AEC7",
"sensors": {
"electricity_consumed": 3.5,
"electricity_consumed_interval": 0.5,
"electricity_produced": 0.0
},
"switches": {
"lock": true,
"relay": true
},
"vendor": "Plugwise",
"zigbee_mac_address": "ABCD012345670A02"
},
"a28e6f5afc0e4fc68498c1f03e82a052": {
"dev_class": "lamp",
"firmware": "2011-06-27T10:52:18+02:00",
"hardware": "6539-0701-4026",
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
"model": "Circle type F",
"name": "Lamp bank 25F67F8",
"sensors": {
"electricity_consumed": 4.19,
"electricity_consumed_interval": 0.62,
"electricity_produced": 0.0,
"electricity_produced_interval": 0.0
},
"switches": {
"lock": false,
"relay": true
},
"vendor": "Plugwise",
"zigbee_mac_address": "ABCD012345670A03"
},
"bc0adbebc50d428d9444a5d805c89da9": {
"dev_class": "watercooker",
"firmware": "2011-06-27T10:52:18+02:00",
"hardware": "0000-0440-0107",
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
"model": "Circle type F",
"name": "Waterkoker 043AF7F",
"sensors": {
"electricity_consumed": 0.0,
"electricity_consumed_interval": 0.0,
"electricity_produced": 0.0
},
"switches": {
"lock": false,
"relay": true
},
"vendor": "Plugwise",
"zigbee_mac_address": "ABCD012345670A07"
},
"c71f1cb2100b42ca942f056dcb7eb01f": {
"dev_class": "tv",
"firmware": "2011-06-27T10:52:18+02:00",
"hardware": "6539-0701-4026",
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
"model": "Circle type F",
"name": "Tv hoek 25F6790",
"sensors": {
"electricity_consumed": 33.3,
"electricity_consumed_interval": 4.93,
"electricity_produced": 0.0,
"electricity_produced_interval": 0.0
},
"switches": {
"lock": false,
"relay": true
},
"vendor": "Plugwise",
"zigbee_mac_address": "ABCD012345670A11"
},
"f7b145c8492f4dd7a4de760456fdef3e": {
"dev_class": "switching",
"members": ["407aa1c1099d463c9137a3a9eda787fd"],
"model": "Switchgroup",
"name": "Test",
"switches": {
"relay": false
}
},
"fd1b74f59e234a9dae4e23b2b5cf07ed": {
"dev_class": "dryer",
"firmware": "2011-06-27T10:52:18+02:00",
"hardware": "0000-0440-0107",
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
"model": "Circle type F",
"name": "Wasdroger 043AECA",
"sensors": {
"electricity_consumed": 1.31,
"electricity_consumed_interval": 0.21,
"electricity_produced": 0.0
},
"switches": {
"lock": true,
"relay": true
},
"vendor": "Plugwise",
"zigbee_mac_address": "ABCD012345670A04"
}
},
"gateway": {
"gateway_id": "0000aaaa0000aaaa0000aaaa0000aa00",
"item_count": 229,
"smile_name": "Stretch"
}
}

View File

@ -423,14 +423,6 @@
'e7693eb9582644e5b865dba8d4447cf1': dict({ 'e7693eb9582644e5b865dba8d4447cf1': dict({
'active_preset': 'no_frost', 'active_preset': 'no_frost',
'available': True, 'available': True,
'available_schedules': list([
'CV Roan',
'Bios Schema met Film Avond',
'GF7 Woonkamer',
'Badkamer Schema',
'CV Jessie',
'off',
]),
'binary_sensors': dict({ 'binary_sensors': dict({
'low_battery': False, 'low_battery': False,
}), }),
@ -449,7 +441,6 @@
'vacation', 'vacation',
'no_frost', 'no_frost',
]), ]),
'select_schedule': 'off',
'sensors': dict({ 'sensors': dict({
'battery': 68, 'battery': 68,
'setpoint': 5.5, 'setpoint': 5.5,

View File

@ -56,7 +56,7 @@ async def test_anna_climate_binary_sensor_change(
async def test_adam_climate_binary_sensor_change( async def test_adam_climate_binary_sensor_change(
hass: HomeAssistant, mock_smile_adam: MagicMock, init_integration: MockConfigEntry hass: HomeAssistant, mock_smile_adam: MagicMock, init_integration: MockConfigEntry
) -> None: ) -> None:
"""Test change of climate related binary_sensor entities.""" """Test of a climate related plugwise-notification binary_sensor."""
state = hass.states.get("binary_sensor.adam_plugwise_notification") state = hass.states.get("binary_sensor.adam_plugwise_notification")
assert state assert state
assert state.state == STATE_ON assert state.state == STATE_ON
@ -64,3 +64,14 @@ async def test_adam_climate_binary_sensor_change(
assert "unreachable" in state.attributes["warning_msg"][0] assert "unreachable" in state.attributes["warning_msg"][0]
assert not state.attributes.get("error_msg") assert not state.attributes.get("error_msg")
assert not state.attributes.get("other_msg") assert not state.attributes.get("other_msg")
async def test_p1_v4_binary_sensor_entity(
hass: HomeAssistant, mock_smile_p1_2: MagicMock, init_integration: MockConfigEntry
) -> None:
"""Test of a Smile P1 related plugwise-notification binary_sensor."""
state = hass.states.get("binary_sensor.smile_p1_plugwise_notification")
assert state
assert state.state == STATE_ON
assert "warning_msg" in state.attributes
assert "connected" in state.attributes["warning_msg"][0]

View File

@ -3,6 +3,7 @@
from datetime import timedelta from datetime import timedelta
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from freezegun.api import FrozenDateTimeFactory
from plugwise.exceptions import PlugwiseError from plugwise.exceptions import PlugwiseError
import pytest import pytest
@ -15,7 +16,6 @@ from homeassistant.components.climate import (
) )
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
from homeassistant.util.dt import utcnow
from tests.common import MockConfigEntry, async_fire_time_changed from tests.common import MockConfigEntry, async_fire_time_changed
@ -90,11 +90,13 @@ async def test_adam_2_climate_entity_attributes(
async def test_adam_3_climate_entity_attributes( async def test_adam_3_climate_entity_attributes(
hass: HomeAssistant, mock_smile_adam_3: MagicMock, init_integration: MockConfigEntry hass: HomeAssistant,
mock_smile_adam_3: MagicMock,
init_integration: MockConfigEntry,
freezer: FrozenDateTimeFactory,
) -> None: ) -> None:
"""Test creation of adam climate device environment.""" """Test creation of adam climate device environment."""
state = hass.states.get("climate.anna") state = hass.states.get("climate.anna")
assert state assert state
assert state.state == HVACMode.COOL assert state.state == HVACMode.COOL
assert state.attributes["hvac_action"] == "cooling" assert state.attributes["hvac_action"] == "cooling"
@ -115,17 +117,20 @@ async def test_adam_3_climate_entity_attributes(
"heating_state" "heating_state"
] = True ] = True
with patch(HA_PLUGWISE_SMILE_ASYNC_UPDATE, return_value=data): with patch(HA_PLUGWISE_SMILE_ASYNC_UPDATE, return_value=data):
async_fire_time_changed(hass, utcnow() + timedelta(minutes=1)) freezer.tick(timedelta(minutes=1))
async_fire_time_changed(hass)
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("climate.anna")
assert state state = hass.states.get("climate.anna")
assert state.state == HVACMode.HEAT assert state
assert state.attributes["hvac_action"] == "heating" assert state.state == HVACMode.HEAT
assert state.attributes["hvac_modes"] == [ assert state.attributes["hvac_action"] == "heating"
HVACMode.OFF, assert state.attributes["hvac_modes"] == [
HVACMode.AUTO, HVACMode.OFF,
HVACMode.HEAT, HVACMode.AUTO,
] HVACMode.HEAT,
]
data = mock_smile_adam_3.async_update.return_value data = mock_smile_adam_3.async_update.return_value
data.devices["da224107914542988a88561b4452b0f6"]["select_regulation_mode"] = ( data.devices["da224107914542988a88561b4452b0f6"]["select_regulation_mode"] = (
"cooling" "cooling"
@ -138,23 +143,25 @@ async def test_adam_3_climate_entity_attributes(
"heating_state" "heating_state"
] = False ] = False
with patch(HA_PLUGWISE_SMILE_ASYNC_UPDATE, return_value=data): with patch(HA_PLUGWISE_SMILE_ASYNC_UPDATE, return_value=data):
async_fire_time_changed(hass, utcnow() + timedelta(minutes=1)) freezer.tick(timedelta(minutes=1))
async_fire_time_changed(hass)
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("climate.anna")
assert state state = hass.states.get("climate.anna")
assert state.state == HVACMode.COOL assert state
assert state.attributes["hvac_action"] == "cooling" assert state.state == HVACMode.COOL
assert state.attributes["hvac_modes"] == [ assert state.attributes["hvac_action"] == "cooling"
HVACMode.OFF, assert state.attributes["hvac_modes"] == [
HVACMode.AUTO, HVACMode.OFF,
HVACMode.COOL, HVACMode.AUTO,
] HVACMode.COOL,
]
async def test_adam_climate_adjust_negative_testing( async def test_adam_climate_adjust_negative_testing(
hass: HomeAssistant, mock_smile_adam: MagicMock, init_integration: MockConfigEntry hass: HomeAssistant, mock_smile_adam: MagicMock, init_integration: MockConfigEntry
) -> None: ) -> None:
"""Test exceptions of climate entities.""" """Test PlugwiseError exception."""
mock_smile_adam.set_temperature.side_effect = PlugwiseError mock_smile_adam.set_temperature.side_effect = PlugwiseError
with pytest.raises(HomeAssistantError): with pytest.raises(HomeAssistantError):
@ -356,6 +363,7 @@ async def test_anna_climate_entity_climate_changes(
hass: HomeAssistant, hass: HomeAssistant,
mock_smile_anna: MagicMock, mock_smile_anna: MagicMock,
init_integration: MockConfigEntry, init_integration: MockConfigEntry,
freezer: FrozenDateTimeFactory,
) -> None: ) -> None:
"""Test handling of user requests in anna climate device environment.""" """Test handling of user requests in anna climate device environment."""
await hass.services.async_call( await hass.services.async_call(
@ -400,11 +408,14 @@ async def test_anna_climate_entity_climate_changes(
mock_smile_anna.set_schedule_state.assert_called_with( mock_smile_anna.set_schedule_state.assert_called_with(
"c784ee9fdab44e1395b8dee7d7a497d5", "off" "c784ee9fdab44e1395b8dee7d7a497d5", "off"
) )
data = mock_smile_anna.async_update.return_value data = mock_smile_anna.async_update.return_value
data.devices["3cb70739631c4d17a86b8b12e8a5161b"].pop("available_schedules") data.devices["3cb70739631c4d17a86b8b12e8a5161b"].pop("available_schedules")
with patch(HA_PLUGWISE_SMILE_ASYNC_UPDATE, return_value=data): with patch(HA_PLUGWISE_SMILE_ASYNC_UPDATE, return_value=data):
async_fire_time_changed(hass, utcnow() + timedelta(minutes=1)) freezer.tick(timedelta(minutes=1))
async_fire_time_changed(hass)
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("climate.anna") state = hass.states.get("climate.anna")
assert state.state == HVACMode.HEAT assert state.state == HVACMode.HEAT
assert state.attributes["hvac_modes"] == [HVACMode.HEAT_COOL] assert state.attributes["hvac_modes"] == [HVACMode.HEAT_COOL]

View File

@ -1,14 +1,13 @@
"""Test the Plugwise config flow.""" """Test the Plugwise config flow."""
from ipaddress import ip_address from ipaddress import ip_address
from unittest.mock import AsyncMock, MagicMock, patch from unittest.mock import AsyncMock, MagicMock
from plugwise.exceptions import ( from plugwise.exceptions import (
ConnectionFailedError, ConnectionFailedError,
InvalidAuthentication, InvalidAuthentication,
InvalidSetupError, InvalidSetupError,
InvalidXMLError, InvalidXMLError,
ResponseError,
UnsupportedDeviceError, UnsupportedDeviceError,
) )
import pytest import pytest
@ -95,22 +94,6 @@ TEST_DISCOVERY_ADAM = ZeroconfServiceInfo(
) )
@pytest.fixture(name="mock_smile")
def mock_smile():
"""Create a Mock Smile for testing exceptions."""
with patch(
"homeassistant.components.plugwise.config_flow.Smile",
) as smile_mock:
smile_mock.ConnectionFailedError = ConnectionFailedError
smile_mock.InvalidAuthentication = InvalidAuthentication
smile_mock.InvalidSetupError = InvalidSetupError
smile_mock.InvalidXMLError = InvalidXMLError
smile_mock.ResponseError = ResponseError
smile_mock.UnsupportedDeviceError = UnsupportedDeviceError
smile_mock.return_value.connect.return_value = True
yield smile_mock.return_value
async def test_form( async def test_form(
hass: HomeAssistant, hass: HomeAssistant,
mock_setup_entry: AsyncMock, mock_setup_entry: AsyncMock,
@ -165,11 +148,12 @@ async def test_zeroconf_flow(
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, DOMAIN,
context={CONF_SOURCE: SOURCE_ZEROCONF}, context={CONF_SOURCE: SOURCE_ZEROCONF},
data=discovery, data=TEST_DISCOVERY,
) )
assert result.get("type") is FlowResultType.FORM assert result.get("type") is FlowResultType.FORM
assert result.get("errors") == {} assert result.get("errors") == {}
assert result.get("step_id") == "user" assert result.get("step_id") == "user"
assert "flow_id" in result
result2 = await hass.config_entries.flow.async_configure( result2 = await hass.config_entries.flow.async_configure(
result["flow_id"], result["flow_id"],
@ -183,7 +167,7 @@ async def test_zeroconf_flow(
CONF_HOST: TEST_HOST, CONF_HOST: TEST_HOST,
CONF_PASSWORD: TEST_PASSWORD, CONF_PASSWORD: TEST_PASSWORD,
CONF_PORT: DEFAULT_PORT, CONF_PORT: DEFAULT_PORT,
CONF_USERNAME: username, CONF_USERNAME: TEST_USERNAME,
PW_TYPE: API, PW_TYPE: API,
} }
@ -205,6 +189,7 @@ async def test_zeroconf_flow_stretch(
assert result.get("type") is FlowResultType.FORM assert result.get("type") is FlowResultType.FORM
assert result.get("errors") == {} assert result.get("errors") == {}
assert result.get("step_id") == "user" assert result.get("step_id") == "user"
assert "flow_id" in result
result2 = await hass.config_entries.flow.async_configure( result2 = await hass.config_entries.flow.async_configure(
result["flow_id"], result["flow_id"],
@ -276,7 +261,6 @@ async def test_zercoconf_discovery_update_configuration(
(InvalidAuthentication, "invalid_auth"), (InvalidAuthentication, "invalid_auth"),
(InvalidSetupError, "invalid_setup"), (InvalidSetupError, "invalid_setup"),
(InvalidXMLError, "response_error"), (InvalidXMLError, "response_error"),
(ResponseError, "response_error"),
(RuntimeError, "unknown"), (RuntimeError, "unknown"),
(UnsupportedDeviceError, "unsupported"), (UnsupportedDeviceError, "unsupported"),
], ],
@ -296,6 +280,7 @@ async def test_flow_errors(
assert result.get("type") is FlowResultType.FORM assert result.get("type") is FlowResultType.FORM
assert result.get("errors") == {} assert result.get("errors") == {}
assert result.get("step_id") == "user" assert result.get("step_id") == "user"
assert "flow_id" in result
mock_smile_config_flow.connect.side_effect = side_effect mock_smile_config_flow.connect.side_effect = side_effect
result2 = await hass.config_entries.flow.async_configure( result2 = await hass.config_entries.flow.async_configure(

View File

@ -77,3 +77,12 @@ async def test_adam_select_regulation_mode(
"heating", "heating",
"on", "on",
) )
async def test_legacy_anna_select_entities(
hass: HomeAssistant,
mock_smile_legacy_anna: MagicMock,
init_integration: MockConfigEntry,
) -> None:
"""Test not creating a select-entity for a legacy Anna without a thermostat-schedule."""
assert not hass.states.get("select.anna_thermostat_schedule")

View File

@ -3,10 +3,10 @@
from unittest.mock import MagicMock from unittest.mock import MagicMock
from homeassistant.components.plugwise.const import DOMAIN from homeassistant.components.plugwise.const import DOMAIN
from homeassistant.const import Platform from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_component import async_update_entity from homeassistant.helpers.entity_component import async_update_entity
import homeassistant.helpers.entity_registry as er
from tests.common import MockConfigEntry from tests.common import MockConfigEntry
@ -58,7 +58,7 @@ async def test_unique_id_migration_humidity(
# Entry to migrate # Entry to migrate
entity_registry.async_get_or_create( entity_registry.async_get_or_create(
Platform.SENSOR, SENSOR_DOMAIN,
DOMAIN, DOMAIN,
"f61f1a2535f54f52ad006a3d18e459ca-relative_humidity", "f61f1a2535f54f52ad006a3d18e459ca-relative_humidity",
config_entry=mock_config_entry, config_entry=mock_config_entry,
@ -67,7 +67,7 @@ async def test_unique_id_migration_humidity(
) )
# Entry not needing migration # Entry not needing migration
entity_registry.async_get_or_create( entity_registry.async_get_or_create(
Platform.SENSOR, SENSOR_DOMAIN,
DOMAIN, DOMAIN,
"f61f1a2535f54f52ad006a3d18e459ca-battery", "f61f1a2535f54f52ad006a3d18e459ca-battery",
config_entry=mock_config_entry, config_entry=mock_config_entry,

View File

@ -11,11 +11,12 @@ from homeassistant.const import (
SERVICE_TOGGLE, SERVICE_TOGGLE,
SERVICE_TURN_OFF, SERVICE_TURN_OFF,
SERVICE_TURN_ON, SERVICE_TURN_ON,
STATE_OFF,
STATE_ON, STATE_ON,
) )
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er import homeassistant.helpers.entity_registry as er
from tests.common import MockConfigEntry from tests.common import MockConfigEntry
@ -49,7 +50,7 @@ async def test_adam_climate_switch_negative_testing(
assert mock_smile_adam.set_switch_state.call_count == 1 assert mock_smile_adam.set_switch_state.call_count == 1
mock_smile_adam.set_switch_state.assert_called_with( mock_smile_adam.set_switch_state.assert_called_with(
"78d1126fc4c743db81b61c20e88342a7", None, "relay", "off" "78d1126fc4c743db81b61c20e88342a7", None, "relay", STATE_OFF
) )
with pytest.raises(HomeAssistantError): with pytest.raises(HomeAssistantError):
@ -62,7 +63,7 @@ async def test_adam_climate_switch_negative_testing(
assert mock_smile_adam.set_switch_state.call_count == 2 assert mock_smile_adam.set_switch_state.call_count == 2
mock_smile_adam.set_switch_state.assert_called_with( mock_smile_adam.set_switch_state.assert_called_with(
"a28f588dc4a049a483fd03a30361ad3a", None, "relay", "on" "a28f588dc4a049a483fd03a30361ad3a", None, "relay", STATE_ON
) )
@ -79,7 +80,7 @@ async def test_adam_climate_switch_changes(
assert mock_smile_adam.set_switch_state.call_count == 1 assert mock_smile_adam.set_switch_state.call_count == 1
mock_smile_adam.set_switch_state.assert_called_with( mock_smile_adam.set_switch_state.assert_called_with(
"78d1126fc4c743db81b61c20e88342a7", None, "relay", "off" "78d1126fc4c743db81b61c20e88342a7", None, "relay", STATE_OFF
) )
await hass.services.async_call( await hass.services.async_call(
@ -91,7 +92,7 @@ async def test_adam_climate_switch_changes(
assert mock_smile_adam.set_switch_state.call_count == 2 assert mock_smile_adam.set_switch_state.call_count == 2
mock_smile_adam.set_switch_state.assert_called_with( mock_smile_adam.set_switch_state.assert_called_with(
"a28f588dc4a049a483fd03a30361ad3a", None, "relay", "off" "a28f588dc4a049a483fd03a30361ad3a", None, "relay", STATE_OFF
) )
await hass.services.async_call( await hass.services.async_call(
@ -103,7 +104,7 @@ async def test_adam_climate_switch_changes(
assert mock_smile_adam.set_switch_state.call_count == 3 assert mock_smile_adam.set_switch_state.call_count == 3
mock_smile_adam.set_switch_state.assert_called_with( mock_smile_adam.set_switch_state.assert_called_with(
"a28f588dc4a049a483fd03a30361ad3a", None, "relay", "on" "a28f588dc4a049a483fd03a30361ad3a", None, "relay", STATE_ON
) )
@ -132,7 +133,7 @@ async def test_stretch_switch_changes(
) )
assert mock_stretch.set_switch_state.call_count == 1 assert mock_stretch.set_switch_state.call_count == 1
mock_stretch.set_switch_state.assert_called_with( mock_stretch.set_switch_state.assert_called_with(
"e1c884e7dede431dadee09506ec4f859", None, "relay", "off" "e1c884e7dede431dadee09506ec4f859", None, "relay", STATE_OFF
) )
await hass.services.async_call( await hass.services.async_call(
@ -143,7 +144,7 @@ async def test_stretch_switch_changes(
) )
assert mock_stretch.set_switch_state.call_count == 2 assert mock_stretch.set_switch_state.call_count == 2
mock_stretch.set_switch_state.assert_called_with( mock_stretch.set_switch_state.assert_called_with(
"cfe95cf3de1948c0b8955125bf754614", None, "relay", "off" "cfe95cf3de1948c0b8955125bf754614", None, "relay", STATE_OFF
) )
await hass.services.async_call( await hass.services.async_call(
@ -154,7 +155,7 @@ async def test_stretch_switch_changes(
) )
assert mock_stretch.set_switch_state.call_count == 3 assert mock_stretch.set_switch_state.call_count == 3
mock_stretch.set_switch_state.assert_called_with( mock_stretch.set_switch_state.assert_called_with(
"cfe95cf3de1948c0b8955125bf754614", None, "relay", "on" "cfe95cf3de1948c0b8955125bf754614", None, "relay", STATE_ON
) )