diff --git a/homeassistant/components/midea/select.py b/homeassistant/components/midea/select.py index 02f3c0db46a4..b2ef4afcaba0 100644 --- a/homeassistant/components/midea/select.py +++ b/homeassistant/components/midea/select.py @@ -21,6 +21,8 @@ class MideaSelectEntityDescription(SelectEntityDescription): models: list[DeviceType] options_attribute: str """Device property name returning the list of valid option strings.""" + requires_power: bool = False + """Entity is only operable while the device's ``power`` attribute is on.""" SELECTS: list[MideaSelectEntityDescription] = [ @@ -47,18 +49,21 @@ SELECTS: list[MideaSelectEntityDescription] = [ translation_key="wind_lr_angle", models=[DeviceType.AC], options_attribute="wind_lr_angles", + requires_power=True, ), MideaSelectEntityDescription( key="wind_ud_angle", translation_key="wind_ud_angle", models=[DeviceType.AC], options_attribute="wind_ud_angles", + requires_power=True, ), MideaSelectEntityDescription( key="rate_select", translation_key="rate_select", models=[DeviceType.AC], options_attribute="rate_selects", + requires_power=True, ), MideaSelectEntityDescription( key="silent_level", @@ -126,6 +131,16 @@ class MideaSelect(MideaEntity, SelectEntity): entity_description: MideaSelectEntityDescription + @property + @override + def available(self) -> bool: + """Return entity availability.""" + if not super().available: + return False + if self.entity_description.requires_power: + return bool(self._device.get_attribute("power")) + return True + @property @override def options(self) -> list[str]: diff --git a/tests/components/midea/test_select.py b/tests/components/midea/test_select.py index 29259f2cfd86..b6dd04cc09b5 100644 --- a/tests/components/midea/test_select.py +++ b/tests/components/midea/test_select.py @@ -22,13 +22,13 @@ from homeassistant.components.select import ( DOMAIN as SELECT_DOMAIN, SERVICE_SELECT_OPTION, ) -from homeassistant.const import ATTR_ENTITY_ID, Platform +from homeassistant.const import ATTR_ENTITY_ID, STATE_UNAVAILABLE, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import entity_registry as er from . import setup_integration -from .conftest import DummyDevice, entity_entries +from .conftest import DummyDevice, SetDeviceAttribute, entity_entries from .const import TEST_DEVICE_ID from tests.common import MockConfigEntry, snapshot_platform @@ -230,6 +230,45 @@ async def test_ac_angle_and_rate_selects( ) +@pytest.mark.parametrize( + "unique_id", + [ + f"{TEST_DEVICE_ID}_wind_lr_angle", + f"{TEST_DEVICE_ID}_wind_ud_angle", + f"{TEST_DEVICE_ID}_rate_select", + ], +) +async def test_ac_selects_unavailable_when_power_off( + hass: HomeAssistant, + mock_config_entry: Callable[[DummyDevice], MockConfigEntry], + set_device_attribute: SetDeviceAttribute, + unique_id: str, +) -> None: + """Test AC angle/rate selects are unavailable while the unit is powered off.""" + device = _ac_device() + config_entry = mock_config_entry(device) + with patch("homeassistant.components.midea._PLATFORMS", [Platform.SELECT]): + await setup_integration(hass, config_entry, device) + + entity_id = entity_entries(hass, config_entry)[unique_id].entity_id + assert (state := hass.states.get(entity_id)) is not None + assert state.state != STATE_UNAVAILABLE + + await set_device_attribute(device, ACAttributes.power, False) + assert (state := hass.states.get(entity_id)) is not None + assert state.state == STATE_UNAVAILABLE + + await set_device_attribute(device, ACAttributes.power, True) + assert (state := hass.states.get(entity_id)) is not None + assert state.state != STATE_UNAVAILABLE + + device.available = False + device.notify_update({"available": False}) + await hass.async_block_till_done() + assert (state := hass.states.get(entity_id)) is not None + assert state.state == STATE_UNAVAILABLE + + async def test_fa_selects_do_not_overlap_fan_platform( hass: HomeAssistant, mock_config_entry: Callable[[DummyDevice], MockConfigEntry],