mirror of
https://github.com/home-assistant/core.git
synced 2026-09-25 17:04:04 -04:00
Add light platform to Midea (#179243)
This commit is contained in:
@@ -29,6 +29,7 @@ _PLATFORMS: list[Platform] = [
|
||||
Platform.CLIMATE,
|
||||
Platform.FAN,
|
||||
Platform.HUMIDIFIER,
|
||||
Platform.LIGHT,
|
||||
Platform.NUMBER,
|
||||
Platform.SELECT,
|
||||
Platform.SWITCH,
|
||||
|
||||
@@ -8,6 +8,7 @@ MIDEA_DEVICE_NAMES: dict[DeviceType, str] = {
|
||||
DeviceType.CC: "MDV Wi-Fi Controller",
|
||||
DeviceType.CF: "Heat Pump",
|
||||
DeviceType.FB: "Electric Heater",
|
||||
DeviceType.X13: "Light",
|
||||
DeviceType.C2: "Toilet",
|
||||
DeviceType.CD: "Heat Pump Water Heater",
|
||||
DeviceType.ED: "Water Drinking Appliance",
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
"""Light for Midea."""
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, cast, override
|
||||
|
||||
from midealocal.const import DeviceType
|
||||
from midealocal.devices.x13 import Midea13Device
|
||||
|
||||
from homeassistant.components.light import (
|
||||
ATTR_BRIGHTNESS,
|
||||
ATTR_COLOR_TEMP_KELVIN,
|
||||
ATTR_EFFECT,
|
||||
EFFECT_OFF,
|
||||
ColorMode,
|
||||
LightEntity,
|
||||
LightEntityDescription,
|
||||
LightEntityFeature,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .entity import MideaConfigEntry, MideaEntity, midea_api_call
|
||||
|
||||
PARALLEL_UPDATES = 0
|
||||
|
||||
|
||||
@dataclass(kw_only=True, frozen=True)
|
||||
class MideaLightEntityDescription(LightEntityDescription):
|
||||
"""Description for a Midea light entity."""
|
||||
|
||||
models: list[DeviceType]
|
||||
|
||||
|
||||
LIGHTS: list[MideaLightEntityDescription] = [
|
||||
MideaLightEntityDescription(
|
||||
key="light",
|
||||
models=[DeviceType.X13],
|
||||
translation_key="light",
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MideaConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up lights for device."""
|
||||
device = config_entry.runtime_data
|
||||
|
||||
async_add_entities(
|
||||
MideaLight(cast(Midea13Device, device), description)
|
||||
for description in LIGHTS
|
||||
if device.device_type in description.models
|
||||
)
|
||||
|
||||
|
||||
class MideaLight(MideaEntity, LightEntity):
|
||||
"""Represent a Midea light."""
|
||||
|
||||
_device: Midea13Device
|
||||
|
||||
@property
|
||||
@override
|
||||
def supported_features(self) -> LightEntityFeature:
|
||||
"""Midea light supported features."""
|
||||
if self._device.get_attribute("effect") is not None:
|
||||
return LightEntityFeature.EFFECT
|
||||
return LightEntityFeature(0)
|
||||
|
||||
@property
|
||||
@override
|
||||
def supported_color_modes(self) -> set[ColorMode]:
|
||||
"""Midea light supported color modes."""
|
||||
if self._device.get_attribute("color_temperature") is not None:
|
||||
return {ColorMode.COLOR_TEMP}
|
||||
if self._device.get_attribute("brightness") is not None:
|
||||
return {ColorMode.BRIGHTNESS}
|
||||
return {ColorMode.ONOFF}
|
||||
|
||||
@property
|
||||
@override
|
||||
def color_mode(self) -> ColorMode:
|
||||
"""Midea light current color mode."""
|
||||
supported = self.supported_color_modes
|
||||
if ColorMode.COLOR_TEMP in supported and self.color_temp_kelvin is not None:
|
||||
return ColorMode.COLOR_TEMP
|
||||
if ColorMode.BRIGHTNESS in supported and self.brightness is not None:
|
||||
return ColorMode.BRIGHTNESS
|
||||
return ColorMode.ONOFF
|
||||
|
||||
@property
|
||||
@override
|
||||
def is_on(self) -> bool | None:
|
||||
"""Midea light is on."""
|
||||
power = self._device.get_attribute("power")
|
||||
if not isinstance(power, bool):
|
||||
return None
|
||||
return power
|
||||
|
||||
@property
|
||||
@override
|
||||
def brightness(self) -> int | None:
|
||||
"""Midea light brightness."""
|
||||
value = self._device.get_attribute("brightness")
|
||||
return value if isinstance(value, int) else None
|
||||
|
||||
@property
|
||||
@override
|
||||
def color_temp_kelvin(self) -> int | None:
|
||||
"""Midea light color temperature."""
|
||||
value = self._device.get_attribute("color_temperature")
|
||||
return value if isinstance(value, int) else None
|
||||
|
||||
@property
|
||||
@override
|
||||
def min_color_temp_kelvin(self) -> int:
|
||||
"""Midea light min color temperature."""
|
||||
return self._device.color_temp_range[0]
|
||||
|
||||
@property
|
||||
@override
|
||||
def max_color_temp_kelvin(self) -> int:
|
||||
"""Midea light max color temperature."""
|
||||
return self._device.color_temp_range[1]
|
||||
|
||||
@property
|
||||
@override
|
||||
def effect_list(self) -> list[str]:
|
||||
"""Midea light effect list."""
|
||||
return [EFFECT_OFF if e == "none" else e for e in self._device.effects]
|
||||
|
||||
@property
|
||||
@override
|
||||
def effect(self) -> str | None:
|
||||
"""Midea light current effect."""
|
||||
value = self._device.get_attribute("effect")
|
||||
if not isinstance(value, str):
|
||||
return None
|
||||
return EFFECT_OFF if value == "none" else value
|
||||
|
||||
@override
|
||||
def turn_on(self, **kwargs: Any) -> None:
|
||||
"""Midea light turn on."""
|
||||
with midea_api_call():
|
||||
if not self.is_on:
|
||||
self._device.set_attribute(attr="power", value=True)
|
||||
if ATTR_BRIGHTNESS in kwargs:
|
||||
self._device.set_attribute(
|
||||
attr="brightness", value=kwargs[ATTR_BRIGHTNESS]
|
||||
)
|
||||
if ATTR_COLOR_TEMP_KELVIN in kwargs:
|
||||
self._device.set_attribute(
|
||||
attr="color_temperature", value=kwargs[ATTR_COLOR_TEMP_KELVIN]
|
||||
)
|
||||
if ATTR_EFFECT in kwargs:
|
||||
effect = kwargs[ATTR_EFFECT]
|
||||
self._device.set_attribute(
|
||||
attr="effect",
|
||||
value="none" if effect == EFFECT_OFF else effect,
|
||||
)
|
||||
|
||||
@override
|
||||
def turn_off(self, **kwargs: Any) -> None:
|
||||
"""Midea light turn off."""
|
||||
with midea_api_call():
|
||||
self._device.set_attribute(attr="power", value=False)
|
||||
@@ -129,6 +129,21 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"light": {
|
||||
"light": {
|
||||
"state_attributes": {
|
||||
"effect": {
|
||||
"state": {
|
||||
"cinema": "Cinema",
|
||||
"living": "Living",
|
||||
"mildly": "Mildly",
|
||||
"night": "Night",
|
||||
"reading": "Reading"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"number": {
|
||||
"dry_level": {
|
||||
"name": "Dry level"
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
# serializer version: 1
|
||||
# name: test_light_state_snapshot[light.bedroom_ac-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
<LightEntityCapabilityAttribute.EFFECT_LIST: 'effect_list'>: list([
|
||||
'off',
|
||||
'living',
|
||||
'reading',
|
||||
'mildly',
|
||||
'cinema',
|
||||
'night',
|
||||
]),
|
||||
<LightEntityCapabilityAttribute.MAX_COLOR_TEMP_KELVIN: 'max_color_temp_kelvin'>: 6500,
|
||||
<LightEntityCapabilityAttribute.MIN_COLOR_TEMP_KELVIN: 'min_color_temp_kelvin'>: 2700,
|
||||
<LightEntityCapabilityAttribute.SUPPORTED_COLOR_MODES: 'supported_color_modes'>: list([
|
||||
<ColorMode.COLOR_TEMP: 'color_temp'>,
|
||||
]),
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'light',
|
||||
'entity_category': None,
|
||||
'entity_id': 'light.bedroom_ac',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'midea',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': <LightEntityFeature: 4>,
|
||||
'translation_key': 'light',
|
||||
'unique_id': '12345678_light',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_light_state_snapshot[light.bedroom_ac-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<LightEntityStateAttribute.BRIGHTNESS: 'brightness'>: 128,
|
||||
<LightEntityStateAttribute.COLOR_MODE: 'color_mode'>: <ColorMode.COLOR_TEMP: 'color_temp'>,
|
||||
<LightEntityStateAttribute.COLOR_TEMP_KELVIN: 'color_temp_kelvin'>: 4000,
|
||||
<LightEntityStateAttribute.EFFECT: 'effect'>: 'off',
|
||||
<LightEntityCapabilityAttribute.EFFECT_LIST: 'effect_list'>: list([
|
||||
'off',
|
||||
'living',
|
||||
'reading',
|
||||
'mildly',
|
||||
'cinema',
|
||||
'night',
|
||||
]),
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Bedroom AC',
|
||||
<LightEntityStateAttribute.HS_COLOR: 'hs_color'>: tuple(
|
||||
26.812,
|
||||
34.87,
|
||||
),
|
||||
<LightEntityCapabilityAttribute.MAX_COLOR_TEMP_KELVIN: 'max_color_temp_kelvin'>: 6500,
|
||||
<LightEntityCapabilityAttribute.MIN_COLOR_TEMP_KELVIN: 'min_color_temp_kelvin'>: 2700,
|
||||
<LightEntityStateAttribute.RGB_COLOR: 'rgb_color'>: tuple(
|
||||
255,
|
||||
206,
|
||||
166,
|
||||
),
|
||||
<LightEntityCapabilityAttribute.SUPPORTED_COLOR_MODES: 'supported_color_modes'>: list([
|
||||
<ColorMode.COLOR_TEMP: 'color_temp'>,
|
||||
]),
|
||||
<EntityStateAttribute.SUPPORTED_FEATURES: 'supported_features'>: <LightEntityFeature: 4>,
|
||||
<LightEntityStateAttribute.XY_COLOR: 'xy_color'>: tuple(
|
||||
0.42,
|
||||
0.365,
|
||||
),
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'light.bedroom_ac',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
@@ -0,0 +1,301 @@
|
||||
"""Tests for midea light.py."""
|
||||
|
||||
from collections.abc import Callable
|
||||
from typing import Any
|
||||
from unittest.mock import patch
|
||||
|
||||
from midealocal.const import DeviceType
|
||||
from midealocal.devices.ac import DeviceAttributes as ACAttributes
|
||||
from midealocal.devices.x13 import DeviceAttributes as X13Attributes, Midea13Device
|
||||
from midealocal.exceptions import SocketException
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.light import (
|
||||
ATTR_BRIGHTNESS,
|
||||
ATTR_COLOR_MODE,
|
||||
ATTR_COLOR_TEMP_KELVIN,
|
||||
ATTR_EFFECT,
|
||||
ATTR_EFFECT_LIST,
|
||||
ATTR_MAX_COLOR_TEMP_KELVIN,
|
||||
ATTR_MIN_COLOR_TEMP_KELVIN,
|
||||
ATTR_SUPPORTED_COLOR_MODES,
|
||||
DOMAIN as LIGHT_DOMAIN,
|
||||
EFFECT_OFF,
|
||||
ColorMode,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
SERVICE_TURN_OFF,
|
||||
SERVICE_TURN_ON,
|
||||
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 .const import TEST_DEVICE_ID
|
||||
|
||||
from tests.common import MockConfigEntry, snapshot_platform
|
||||
|
||||
X13_EFFECTS = list(Midea13Device._effects)
|
||||
|
||||
|
||||
def _x13_device() -> DummyDevice:
|
||||
device = DummyDevice(
|
||||
DeviceType.X13,
|
||||
attributes={
|
||||
X13Attributes.power: True,
|
||||
X13Attributes.brightness: 128,
|
||||
X13Attributes.color_temperature: 4000,
|
||||
X13Attributes.effect: "none",
|
||||
X13Attributes.rgb_color: None,
|
||||
},
|
||||
)
|
||||
device.color_temp_range = [2700, 6500]
|
||||
device.effects = X13_EFFECTS
|
||||
return device
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||
async def test_light_state_snapshot(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: Callable[[DummyDevice], MockConfigEntry],
|
||||
snapshot: SnapshotAssertion,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test async_setup_entry creates the light entity for an X13 device."""
|
||||
device = _x13_device()
|
||||
config_entry = mock_config_entry(device)
|
||||
with patch("homeassistant.components.midea._PLATFORMS", [Platform.LIGHT]):
|
||||
await setup_integration(hass, config_entry, device)
|
||||
|
||||
await snapshot_platform(hass, entity_registry, snapshot, config_entry.entry_id)
|
||||
|
||||
|
||||
async def test_light_state_and_services(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: Callable[[DummyDevice], MockConfigEntry],
|
||||
) -> None:
|
||||
"""Test light state attributes and service calls reach the device."""
|
||||
device = _x13_device()
|
||||
config_entry = mock_config_entry(device)
|
||||
with patch("homeassistant.components.midea._PLATFORMS", [Platform.LIGHT]):
|
||||
await setup_integration(hass, config_entry, device)
|
||||
|
||||
entity_entry = entity_entries(hass, config_entry)[f"{TEST_DEVICE_ID}_light"]
|
||||
|
||||
assert (state := hass.states.get(entity_entry.entity_id)) is not None
|
||||
assert state.state == "on"
|
||||
assert state.attributes[ATTR_BRIGHTNESS] == 128
|
||||
assert state.attributes[ATTR_COLOR_TEMP_KELVIN] == 4000
|
||||
assert state.attributes[ATTR_MIN_COLOR_TEMP_KELVIN] == 2700
|
||||
assert state.attributes[ATTR_MAX_COLOR_TEMP_KELVIN] == 6500
|
||||
assert state.attributes[ATTR_EFFECT] == EFFECT_OFF
|
||||
assert state.attributes[ATTR_EFFECT_LIST] == [
|
||||
EFFECT_OFF,
|
||||
*(effect for effect in X13_EFFECTS if effect != "none"),
|
||||
]
|
||||
assert state.attributes[ATTR_COLOR_MODE] == ColorMode.COLOR_TEMP
|
||||
assert state.attributes[ATTR_SUPPORTED_COLOR_MODES] == [ColorMode.COLOR_TEMP]
|
||||
|
||||
device.calls.clear()
|
||||
await hass.services.async_call(
|
||||
LIGHT_DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{
|
||||
ATTR_ENTITY_ID: entity_entry.entity_id,
|
||||
ATTR_BRIGHTNESS: 200,
|
||||
ATTR_COLOR_TEMP_KELVIN: 5000,
|
||||
ATTR_EFFECT: "cinema",
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
assert device.calls == [
|
||||
("set_attribute", "brightness", 200),
|
||||
("set_attribute", "color_temperature", 5000),
|
||||
("set_attribute", "effect", "cinema"),
|
||||
]
|
||||
|
||||
device.calls.clear()
|
||||
await hass.services.async_call(
|
||||
LIGHT_DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: entity_entry.entity_id, ATTR_EFFECT: EFFECT_OFF},
|
||||
blocking=True,
|
||||
)
|
||||
assert device.calls == [("set_attribute", "effect", "none")]
|
||||
|
||||
device.calls.clear()
|
||||
await hass.services.async_call(
|
||||
LIGHT_DOMAIN,
|
||||
SERVICE_TURN_OFF,
|
||||
{ATTR_ENTITY_ID: entity_entry.entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
assert device.calls == [("set_attribute", "power", False)]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("initial_power", "service_data", "expected_calls"),
|
||||
[
|
||||
pytest.param(
|
||||
True,
|
||||
{ATTR_BRIGHTNESS: 50},
|
||||
[("set_attribute", "brightness", 50)],
|
||||
id="already_on_skips_repower",
|
||||
),
|
||||
pytest.param(
|
||||
False,
|
||||
{},
|
||||
[("set_attribute", "power", True)],
|
||||
id="off_powers_on",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_light_turn_on_power_handling(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: Callable[[DummyDevice], MockConfigEntry],
|
||||
initial_power: bool,
|
||||
service_data: dict[str, Any],
|
||||
expected_calls: list[tuple],
|
||||
) -> None:
|
||||
"""Test turn_on only resends power when the device is currently off."""
|
||||
device = _x13_device()
|
||||
device.attributes[X13Attributes.power] = initial_power
|
||||
config_entry = mock_config_entry(device)
|
||||
with patch("homeassistant.components.midea._PLATFORMS", [Platform.LIGHT]):
|
||||
await setup_integration(hass, config_entry, device)
|
||||
|
||||
entity_entry = entity_entries(hass, config_entry)[f"{TEST_DEVICE_ID}_light"]
|
||||
|
||||
device.calls.clear()
|
||||
await hass.services.async_call(
|
||||
LIGHT_DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: entity_entry.entity_id, **service_data},
|
||||
blocking=True,
|
||||
)
|
||||
assert device.calls == expected_calls
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
(
|
||||
"attributes",
|
||||
"expected_state",
|
||||
"expected_color_mode",
|
||||
"expected_supported_color_modes",
|
||||
"expected_has_effect",
|
||||
),
|
||||
[
|
||||
pytest.param(
|
||||
{},
|
||||
"unknown",
|
||||
# HA only reports a color_mode while is_on is True.
|
||||
None,
|
||||
[ColorMode.ONOFF],
|
||||
False,
|
||||
id="before_first_status",
|
||||
),
|
||||
pytest.param(
|
||||
{
|
||||
X13Attributes.power: True,
|
||||
X13Attributes.brightness: None,
|
||||
X13Attributes.color_temperature: None,
|
||||
X13Attributes.effect: None,
|
||||
X13Attributes.rgb_color: None,
|
||||
},
|
||||
"on",
|
||||
ColorMode.ONOFF,
|
||||
[ColorMode.ONOFF],
|
||||
False,
|
||||
id="onoff_only",
|
||||
),
|
||||
pytest.param(
|
||||
{
|
||||
X13Attributes.power: True,
|
||||
X13Attributes.brightness: 50,
|
||||
X13Attributes.color_temperature: None,
|
||||
X13Attributes.effect: None,
|
||||
X13Attributes.rgb_color: None,
|
||||
},
|
||||
"on",
|
||||
ColorMode.BRIGHTNESS,
|
||||
[ColorMode.BRIGHTNESS],
|
||||
False,
|
||||
id="brightness_only",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_light_color_mode_fallbacks(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: Callable[[DummyDevice], MockConfigEntry],
|
||||
attributes: dict[X13Attributes, Any],
|
||||
expected_state: str,
|
||||
expected_color_mode: ColorMode | None,
|
||||
expected_supported_color_modes: list[ColorMode],
|
||||
expected_has_effect: bool,
|
||||
) -> None:
|
||||
"""Test the light falls back to the correct color mode based on reported capability."""
|
||||
device = DummyDevice(DeviceType.X13, attributes=attributes)
|
||||
device.color_temp_range = [2700, 6500]
|
||||
device.effects = X13_EFFECTS
|
||||
config_entry = mock_config_entry(device)
|
||||
with patch("homeassistant.components.midea._PLATFORMS", [Platform.LIGHT]):
|
||||
await setup_integration(hass, config_entry, device)
|
||||
|
||||
entity_entry = entity_entries(hass, config_entry)[f"{TEST_DEVICE_ID}_light"]
|
||||
assert (state := hass.states.get(entity_entry.entity_id)) is not None
|
||||
assert state.state == expected_state
|
||||
assert state.attributes[ATTR_COLOR_MODE] == expected_color_mode
|
||||
assert (
|
||||
state.attributes[ATTR_SUPPORTED_COLOR_MODES] == expected_supported_color_modes
|
||||
)
|
||||
assert (ATTR_EFFECT in state.attributes) == expected_has_effect
|
||||
|
||||
|
||||
async def test_light_not_created_for_other_device_type(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: Callable[[DummyDevice], MockConfigEntry],
|
||||
) -> None:
|
||||
"""Test no light entity is created for a device type without one."""
|
||||
device = DummyDevice(
|
||||
DeviceType.AC,
|
||||
attributes={
|
||||
ACAttributes.power: True,
|
||||
ACAttributes.mode: 1,
|
||||
ACAttributes.target_temperature: 22.0,
|
||||
ACAttributes.indoor_temperature: 21.0,
|
||||
},
|
||||
)
|
||||
config_entry = mock_config_entry(device)
|
||||
with patch("homeassistant.components.midea._PLATFORMS", [Platform.LIGHT]):
|
||||
await setup_integration(hass, config_entry, device)
|
||||
|
||||
assert entity_entries(hass, config_entry) == {}
|
||||
|
||||
|
||||
async def test_light_turn_on_raises_on_device_communication_error(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: Callable[[DummyDevice], MockConfigEntry],
|
||||
) -> None:
|
||||
"""Test a device communication failure surfaces as a HomeAssistantError."""
|
||||
device = _x13_device()
|
||||
config_entry = mock_config_entry(device)
|
||||
with patch("homeassistant.components.midea._PLATFORMS", [Platform.LIGHT]):
|
||||
await setup_integration(hass, config_entry, device)
|
||||
|
||||
entity_entry = entity_entries(hass, config_entry)[f"{TEST_DEVICE_ID}_light"]
|
||||
|
||||
with (
|
||||
patch.object(device, "set_attribute", side_effect=SocketException("offline")),
|
||||
pytest.raises(HomeAssistantError),
|
||||
):
|
||||
await hass.services.async_call(
|
||||
LIGHT_DOMAIN,
|
||||
SERVICE_TURN_OFF,
|
||||
{ATTR_ENTITY_ID: entity_entry.entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
Reference in New Issue
Block a user