mirror of
https://github.com/home-assistant/core.git
synced 2026-09-24 15:31:52 -05:00
Fixes for Plugwise Select (#176787)
This commit is contained in:
@@ -9,6 +9,7 @@ from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .const import (
|
||||
LOCATION,
|
||||
SELECT_DHW_MODE,
|
||||
SELECT_GATEWAY_MODE,
|
||||
SELECT_REGULATION_MODE,
|
||||
@@ -106,9 +107,12 @@ class PlugwiseSelectEntity(PlugwiseEntity, SelectEntity):
|
||||
self._attr_unique_id = f"{device_id}-{entity_description.key}"
|
||||
self.entity_description = entity_description
|
||||
|
||||
self._location = device_id
|
||||
if (location := self.device.get("location")) is not None:
|
||||
self._location = location
|
||||
self._device_or_location = device_id
|
||||
if (
|
||||
self.entity_description.key in (SELECT_SCHEDULE, SELECT_ZONE_PROFILE)
|
||||
and (location := self.device.get(LOCATION)) is not None
|
||||
):
|
||||
self._device_or_location = location
|
||||
|
||||
@property
|
||||
@override
|
||||
@@ -127,8 +131,10 @@ class PlugwiseSelectEntity(PlugwiseEntity, SelectEntity):
|
||||
async def async_select_option(self, option: str) -> None:
|
||||
"""Change to the selected entity option.
|
||||
|
||||
self._location and STATE_ON are required for the thermostat-schedule select.
|
||||
The appliance ID (= device_id) is required for the dhw_mode select.
|
||||
The location ID is required for the thermostat schedule and zone_profile selects.
|
||||
STATE_ON is required for the thermostat schedule select.
|
||||
"""
|
||||
await self.coordinator.api.set_select(
|
||||
self.entity_description.key, self._location, option, STATE_ON
|
||||
self.entity_description.key, self._device_or_location, option, STATE_ON
|
||||
)
|
||||
|
||||
@@ -268,6 +268,34 @@ def mock_smile_anna(chosen_env: str, cooling_present: bool) -> Generator[MagicMo
|
||||
yield api
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_smile_anna_loria() -> Generator[MagicMock]:
|
||||
"""Create a Mock Anna-connected-to-Loria-heatpump type for testing."""
|
||||
chosen_env = "anna_loria_cooling_active"
|
||||
data = _read_json(chosen_env, "data")
|
||||
with patch(
|
||||
"homeassistant.components.plugwise.coordinator.Smile", autospec=True
|
||||
) as api_mock:
|
||||
api = api_mock.return_value
|
||||
|
||||
api.async_update.return_value = data
|
||||
api.connect.return_value = Version("4.3.8")
|
||||
api.cooling_present = True
|
||||
api.gateway_id = "9ff0569b4984459fb243af64c0901894"
|
||||
api.heater_id = "bfb5ee0a88e14e5f97bfa725a760cc49"
|
||||
api.reboot = True
|
||||
api.smile = build_smile(
|
||||
hostname="smile98765",
|
||||
model="Gateway",
|
||||
model_id="smile_thermo",
|
||||
name="Smile Anna",
|
||||
type="thermostat",
|
||||
version="4.3.8",
|
||||
)
|
||||
|
||||
yield api
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_smile_anna_p1() -> Generator[MagicMock]:
|
||||
"""Create a Mock Anna-P1 type for testing."""
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
{
|
||||
"582dfbdace4d4aeb832923ce7d1ddda0": {
|
||||
"active_preset": "home",
|
||||
"available_schedules": ["Winter", "Test ", "off"],
|
||||
"climate_mode": "auto",
|
||||
"control_state": "cooling",
|
||||
"dev_class": "thermostat",
|
||||
"firmware": "2018-02-08T11:15:53+01:00",
|
||||
"hardware": "6539-1301-5002",
|
||||
"location": "15da035090b847e7a21f93e08c015ebc",
|
||||
"model": "ThermoTouch",
|
||||
"name": "Anna",
|
||||
"preset_modes": ["away", "vacation", "no_frost", "home", "asleep"],
|
||||
"select_schedule": "Winter",
|
||||
"sensors": {
|
||||
"illuminance": 45.0,
|
||||
"setpoint_high": 23.5,
|
||||
"setpoint_low": 4.0,
|
||||
"temperature": 24.1
|
||||
},
|
||||
"temperature_offset": {
|
||||
"lower_bound": -2.0,
|
||||
"resolution": 0.1,
|
||||
"setpoint": 0.0,
|
||||
"upper_bound": 2.0
|
||||
},
|
||||
"thermostat": {
|
||||
"lower_bound": 4.0,
|
||||
"resolution": 0.1,
|
||||
"setpoint_high": 23.5,
|
||||
"setpoint_low": 4.0,
|
||||
"upper_bound": 30.0
|
||||
},
|
||||
"vendor": "Plugwise"
|
||||
},
|
||||
"9ff0569b4984459fb243af64c0901894": {
|
||||
"binary_sensors": {
|
||||
"plugwise_notification": false
|
||||
},
|
||||
"dev_class": "gateway",
|
||||
"firmware": "4.3.8",
|
||||
"hardware": "AME Smile 2.0 board",
|
||||
"location": "674b657c138a41a291d315d7471deb06",
|
||||
"mac_address": "C493000278E2",
|
||||
"model": "Gateway",
|
||||
"model_id": "smile_thermo",
|
||||
"name": "Smile Anna",
|
||||
"notifications": {},
|
||||
"sensors": {
|
||||
"outdoor_temperature": 15.5
|
||||
},
|
||||
"vendor": "Plugwise"
|
||||
},
|
||||
"bfb5ee0a88e14e5f97bfa725a760cc49": {
|
||||
"available": true,
|
||||
"binary_sensors": {
|
||||
"cooling_enabled": true,
|
||||
"cooling_state": true,
|
||||
"dhw_state": false,
|
||||
"flame_state": false,
|
||||
"heating_state": false
|
||||
},
|
||||
"dev_class": "heater_central",
|
||||
"dhw_modes": ["off", "auto", "boost", "eco", "comfort"],
|
||||
"location": "674b657c138a41a291d315d7471deb06",
|
||||
"max_dhw_temperature": {
|
||||
"lower_bound": 35.0,
|
||||
"resolution": 0.01,
|
||||
"setpoint": 53.0,
|
||||
"upper_bound": 60.0
|
||||
},
|
||||
"maximum_boiler_temperature": {
|
||||
"lower_bound": 25.0,
|
||||
"resolution": 0.01,
|
||||
"setpoint": 40.0,
|
||||
"upper_bound": 45.0
|
||||
},
|
||||
"model": "Generic heater/cooler",
|
||||
"model_id": "173",
|
||||
"name": "OpenTherm",
|
||||
"select_dhw_mode": "auto",
|
||||
"sensors": {
|
||||
"dhw_temperature": 52.9,
|
||||
"intended_boiler_temperature": 0.0,
|
||||
"modulation_level": 100,
|
||||
"outdoor_air_temperature": 17.2,
|
||||
"return_temperature": 26.3,
|
||||
"water_temperature": 25.3
|
||||
},
|
||||
"switches": {
|
||||
"cooling_ena_switch": true,
|
||||
"dhw_cm_switch": true
|
||||
},
|
||||
"vendor": "Atlantic"
|
||||
}
|
||||
}
|
||||
@@ -645,3 +645,129 @@
|
||||
'state': 'GF7 Woonkamer',
|
||||
})
|
||||
# ---
|
||||
# name: test_anna_entities_with_dhw_mode_select[platforms0-True-anna_loria_cooling_active][select.anna_thermostat_schedule-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
<SelectEntityCapabilityAttribute.OPTIONS: 'options'>: list([
|
||||
'Winter',
|
||||
'Test ',
|
||||
'off',
|
||||
]),
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'select',
|
||||
'entity_category': None,
|
||||
'entity_id': 'select.anna_thermostat_schedule',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Thermostat schedule',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Thermostat schedule',
|
||||
'platform': 'plugwise',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'select_schedule',
|
||||
'unique_id': '582dfbdace4d4aeb832923ce7d1ddda0-select_schedule',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_anna_entities_with_dhw_mode_select[platforms0-True-anna_loria_cooling_active][select.anna_thermostat_schedule-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Anna Thermostat schedule',
|
||||
<SelectEntityCapabilityAttribute.OPTIONS: 'options'>: list([
|
||||
'Winter',
|
||||
'Test ',
|
||||
'off',
|
||||
]),
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'select.anna_thermostat_schedule',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'Winter',
|
||||
})
|
||||
# ---
|
||||
# name: test_anna_entities_with_dhw_mode_select[platforms0-True-anna_loria_cooling_active][select.opentherm_dhw_mode-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
<SelectEntityCapabilityAttribute.OPTIONS: 'options'>: list([
|
||||
'off',
|
||||
'auto',
|
||||
'boost',
|
||||
'eco',
|
||||
'comfort',
|
||||
]),
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'select',
|
||||
'entity_category': <EntityCategory.CONFIG: 'config'>,
|
||||
'entity_id': 'select.opentherm_dhw_mode',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'DHW mode',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'DHW mode',
|
||||
'platform': 'plugwise',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'select_dhw_mode',
|
||||
'unique_id': 'bfb5ee0a88e14e5f97bfa725a760cc49-select_dhw_mode',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_anna_entities_with_dhw_mode_select[platforms0-True-anna_loria_cooling_active][select.opentherm_dhw_mode-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'OpenTherm DHW mode',
|
||||
<SelectEntityCapabilityAttribute.OPTIONS: 'options'>: list([
|
||||
'off',
|
||||
'auto',
|
||||
'boost',
|
||||
'eco',
|
||||
'comfort',
|
||||
]),
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'select.opentherm_dhw_mode',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'auto',
|
||||
})
|
||||
# ---
|
||||
|
||||
@@ -6,6 +6,8 @@ import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.plugwise.const import (
|
||||
SELECT_DHW_MODE,
|
||||
SELECT_GATEWAY_MODE,
|
||||
SELECT_REGULATION_MODE,
|
||||
SELECT_SCHEDULE,
|
||||
SELECT_ZONE_PROFILE,
|
||||
@@ -97,11 +99,28 @@ async def test_adam_select_regulation_mode(
|
||||
assert mock_smile_adam_heat_cool.set_select.call_count == 1
|
||||
mock_smile_adam_heat_cool.set_select.assert_called_with(
|
||||
SELECT_REGULATION_MODE,
|
||||
"bc93488efab249e5bc54fd7e175a6f91",
|
||||
"da224107914542988a88561b4452b0f6",
|
||||
"heating",
|
||||
"on",
|
||||
)
|
||||
|
||||
await hass.services.async_call(
|
||||
SELECT_DOMAIN,
|
||||
SERVICE_SELECT_OPTION,
|
||||
{
|
||||
ATTR_ENTITY_ID: "select.adam_gateway_mode",
|
||||
ATTR_OPTION: "vacation",
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
assert mock_smile_adam_heat_cool.set_select.call_count == 2
|
||||
mock_smile_adam_heat_cool.set_select.assert_called_with(
|
||||
SELECT_GATEWAY_MODE,
|
||||
"da224107914542988a88561b4452b0f6",
|
||||
"vacation",
|
||||
"on",
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("chosen_env", ["m_adam_heating"], indirect=True)
|
||||
@pytest.mark.parametrize("cooling_present", [True], indirect=True)
|
||||
@@ -155,3 +174,42 @@ async def test_anna_select_unavailable_schedule_mode(
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("chosen_env", ["anna_loria_cooling_active"], indirect=True)
|
||||
@pytest.mark.parametrize("cooling_present", [True], indirect=True)
|
||||
@pytest.mark.parametrize("platforms", [(SELECT_DOMAIN,)])
|
||||
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||
async def test_anna_entities_with_dhw_mode_select(
|
||||
hass: HomeAssistant,
|
||||
mock_smile_anna: MagicMock,
|
||||
snapshot: SnapshotAssertion,
|
||||
entity_registry: er.EntityRegistry,
|
||||
setup_platform: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test Anna select snapshot with multiple dhw_modes."""
|
||||
await snapshot_platform(hass, entity_registry, snapshot, setup_platform.entry_id)
|
||||
|
||||
|
||||
async def test_anna_select_dhw_mode(
|
||||
hass: HomeAssistant,
|
||||
mock_smile_anna_loria: MagicMock,
|
||||
init_integration: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test changing the dhw_mode select."""
|
||||
await hass.services.async_call(
|
||||
SELECT_DOMAIN,
|
||||
SERVICE_SELECT_OPTION,
|
||||
{
|
||||
ATTR_ENTITY_ID: "select.opentherm_dhw_mode",
|
||||
ATTR_OPTION: "boost",
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
assert mock_smile_anna_loria.set_select.call_count == 1
|
||||
mock_smile_anna_loria.set_select.assert_called_with(
|
||||
SELECT_DHW_MODE,
|
||||
"bfb5ee0a88e14e5f97bfa725a760cc49",
|
||||
"boost",
|
||||
"on",
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user