Add additional select for dmaker.airfresh.t2017 to xiaomi_miio (#67058)
This commit is contained in:
parent
d50b5cebee
commit
65f86ce44f
4 changed files with 329 additions and 160 deletions
|
@ -1478,7 +1478,6 @@ omit =
|
|||
homeassistant/components/xiaomi_miio/light.py
|
||||
homeassistant/components/xiaomi_miio/number.py
|
||||
homeassistant/components/xiaomi_miio/remote.py
|
||||
homeassistant/components/xiaomi_miio/select.py
|
||||
homeassistant/components/xiaomi_miio/sensor.py
|
||||
homeassistant/components/xiaomi_miio/switch.py
|
||||
homeassistant/components/xiaomi_tv/media_player.py
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
"""Support led_brightness for Mi Air Humidifier."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from dataclasses import dataclass, field
|
||||
from typing import NamedTuple
|
||||
|
||||
from miio.fan_common import LedBrightness as FanLedBrightness
|
||||
from miio.integrations.airpurifier.dmaker.airfresh_t2017 import (
|
||||
DisplayOrientation as AirfreshT2017DisplayOrientation,
|
||||
PtcLevel as AirfreshT2017PtcLevel,
|
||||
)
|
||||
from miio.integrations.airpurifier.zhimi.airfresh import (
|
||||
LedBrightness as AirfreshLedBrightness,
|
||||
)
|
||||
|
@ -31,53 +36,134 @@ from .const import (
|
|||
CONF_DEVICE,
|
||||
CONF_FLOW_TYPE,
|
||||
DOMAIN,
|
||||
FEATURE_SET_LED_BRIGHTNESS,
|
||||
KEY_COORDINATOR,
|
||||
KEY_DEVICE,
|
||||
MODEL_AIRFRESH_T2017,
|
||||
MODEL_AIRFRESH_VA2,
|
||||
MODEL_AIRPURIFIER_3C,
|
||||
MODEL_AIRHUMIDIFIER_CA1,
|
||||
MODEL_AIRHUMIDIFIER_CA4,
|
||||
MODEL_AIRHUMIDIFIER_CB1,
|
||||
MODEL_AIRHUMIDIFIER_V1,
|
||||
MODEL_AIRPURIFIER_3,
|
||||
MODEL_AIRPURIFIER_3H,
|
||||
MODEL_AIRPURIFIER_M1,
|
||||
MODEL_AIRPURIFIER_M2,
|
||||
MODEL_AIRPURIFIER_PROH,
|
||||
MODEL_FAN_SA1,
|
||||
MODEL_FAN_V2,
|
||||
MODEL_FAN_V3,
|
||||
MODEL_FAN_ZA1,
|
||||
MODEL_FAN_ZA3,
|
||||
MODEL_FAN_ZA4,
|
||||
MODELS_HUMIDIFIER_MIIO,
|
||||
MODELS_HUMIDIFIER_MIOT,
|
||||
MODELS_PURIFIER_MIOT,
|
||||
)
|
||||
from .device import XiaomiCoordinatedMiioEntity
|
||||
|
||||
ATTR_DISPLAY_ORIENTATION = "display_orientation"
|
||||
ATTR_LED_BRIGHTNESS = "led_brightness"
|
||||
|
||||
|
||||
LED_BRIGHTNESS_MAP = {"Bright": 0, "Dim": 1, "Off": 2}
|
||||
LED_BRIGHTNESS_MAP_HUMIDIFIER_MIOT = {"Bright": 2, "Dim": 1, "Off": 0}
|
||||
LED_BRIGHTNESS_REVERSE_MAP = {val: key for key, val in LED_BRIGHTNESS_MAP.items()}
|
||||
LED_BRIGHTNESS_REVERSE_MAP_HUMIDIFIER_MIOT = {
|
||||
val: key for key, val in LED_BRIGHTNESS_MAP_HUMIDIFIER_MIOT.items()
|
||||
}
|
||||
ATTR_PTC_LEVEL = "ptc_level"
|
||||
|
||||
|
||||
@dataclass
|
||||
class XiaomiMiioSelectDescription(SelectEntityDescription):
|
||||
"""A class that describes select entities."""
|
||||
|
||||
attr_name: str = ""
|
||||
options_map: dict = field(default_factory=dict)
|
||||
set_method: str = ""
|
||||
set_method_error_message: str = ""
|
||||
options: tuple = ()
|
||||
|
||||
|
||||
SELECTOR_TYPES = {
|
||||
FEATURE_SET_LED_BRIGHTNESS: XiaomiMiioSelectDescription(
|
||||
class AttributeEnumMapping(NamedTuple):
|
||||
"""Class to mapping Attribute to Enum Class."""
|
||||
|
||||
attr_name: str
|
||||
enum_class: type
|
||||
|
||||
|
||||
MODEL_TO_ATTR_MAP: dict[str, list] = {
|
||||
MODEL_AIRFRESH_T2017: [
|
||||
AttributeEnumMapping(ATTR_DISPLAY_ORIENTATION, AirfreshT2017DisplayOrientation),
|
||||
AttributeEnumMapping(ATTR_PTC_LEVEL, AirfreshT2017PtcLevel),
|
||||
],
|
||||
MODEL_AIRFRESH_VA2: [
|
||||
AttributeEnumMapping(ATTR_LED_BRIGHTNESS, AirfreshLedBrightness)
|
||||
],
|
||||
MODEL_AIRHUMIDIFIER_CA1: [
|
||||
AttributeEnumMapping(ATTR_LED_BRIGHTNESS, AirhumidifierLedBrightness)
|
||||
],
|
||||
MODEL_AIRHUMIDIFIER_CA4: [
|
||||
AttributeEnumMapping(ATTR_LED_BRIGHTNESS, AirhumidifierMiotLedBrightness)
|
||||
],
|
||||
MODEL_AIRHUMIDIFIER_CB1: [
|
||||
AttributeEnumMapping(ATTR_LED_BRIGHTNESS, AirhumidifierLedBrightness)
|
||||
],
|
||||
MODEL_AIRHUMIDIFIER_V1: [
|
||||
AttributeEnumMapping(ATTR_LED_BRIGHTNESS, AirhumidifierLedBrightness)
|
||||
],
|
||||
MODEL_AIRPURIFIER_3: [
|
||||
AttributeEnumMapping(ATTR_LED_BRIGHTNESS, AirpurifierMiotLedBrightness)
|
||||
],
|
||||
MODEL_AIRPURIFIER_3H: [
|
||||
AttributeEnumMapping(ATTR_LED_BRIGHTNESS, AirpurifierMiotLedBrightness)
|
||||
],
|
||||
MODEL_AIRPURIFIER_M1: [
|
||||
AttributeEnumMapping(ATTR_LED_BRIGHTNESS, AirpurifierLedBrightness)
|
||||
],
|
||||
MODEL_AIRPURIFIER_M2: [
|
||||
AttributeEnumMapping(ATTR_LED_BRIGHTNESS, AirpurifierLedBrightness)
|
||||
],
|
||||
MODEL_AIRPURIFIER_PROH: [
|
||||
AttributeEnumMapping(ATTR_LED_BRIGHTNESS, AirpurifierMiotLedBrightness)
|
||||
],
|
||||
MODEL_FAN_SA1: [AttributeEnumMapping(ATTR_LED_BRIGHTNESS, FanLedBrightness)],
|
||||
MODEL_FAN_V2: [AttributeEnumMapping(ATTR_LED_BRIGHTNESS, FanLedBrightness)],
|
||||
MODEL_FAN_V3: [AttributeEnumMapping(ATTR_LED_BRIGHTNESS, FanLedBrightness)],
|
||||
MODEL_FAN_ZA1: [AttributeEnumMapping(ATTR_LED_BRIGHTNESS, FanLedBrightness)],
|
||||
MODEL_FAN_ZA3: [AttributeEnumMapping(ATTR_LED_BRIGHTNESS, FanLedBrightness)],
|
||||
MODEL_FAN_ZA4: [AttributeEnumMapping(ATTR_LED_BRIGHTNESS, FanLedBrightness)],
|
||||
}
|
||||
|
||||
SELECTOR_TYPES = (
|
||||
XiaomiMiioSelectDescription(
|
||||
key=ATTR_DISPLAY_ORIENTATION,
|
||||
attr_name=ATTR_DISPLAY_ORIENTATION,
|
||||
name="Display Orientation",
|
||||
options_map={
|
||||
"Portrait": "Forward",
|
||||
"LandscapeLeft": "Left",
|
||||
"LandscapeRight": "Right",
|
||||
},
|
||||
set_method="set_display_orientation",
|
||||
set_method_error_message="Setting the display orientation failed.",
|
||||
icon="mdi:tablet",
|
||||
device_class="xiaomi_miio__display_orientation",
|
||||
options=("forward", "left", "right"),
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
),
|
||||
XiaomiMiioSelectDescription(
|
||||
key=ATTR_LED_BRIGHTNESS,
|
||||
attr_name=ATTR_LED_BRIGHTNESS,
|
||||
name="Led Brightness",
|
||||
set_method="set_led_brightness",
|
||||
set_method_error_message="Setting the led brightness failed.",
|
||||
icon="mdi:brightness-6",
|
||||
device_class="xiaomi_miio__led_brightness",
|
||||
options=("bright", "dim", "off"),
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
),
|
||||
}
|
||||
XiaomiMiioSelectDescription(
|
||||
key=ATTR_PTC_LEVEL,
|
||||
attr_name=ATTR_PTC_LEVEL,
|
||||
name="Auxiliary Heat Level",
|
||||
set_method="set_ptc_level",
|
||||
set_method_error_message="Setting the ptc level failed.",
|
||||
icon="mdi:fire-circle",
|
||||
device_class="xiaomi_miio__ptc_level",
|
||||
options=("low", "medium", "high"),
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
|
@ -89,44 +175,29 @@ async def async_setup_entry(
|
|||
if not config_entry.data[CONF_FLOW_TYPE] == CONF_DEVICE:
|
||||
return
|
||||
|
||||
entities = []
|
||||
model = config_entry.data[CONF_MODEL]
|
||||
if model not in MODEL_TO_ATTR_MAP:
|
||||
return
|
||||
|
||||
entities = []
|
||||
unique_id = config_entry.unique_id
|
||||
device = hass.data[DOMAIN][config_entry.entry_id][KEY_DEVICE]
|
||||
coordinator = hass.data[DOMAIN][config_entry.entry_id][KEY_COORDINATOR]
|
||||
attributes = MODEL_TO_ATTR_MAP[model]
|
||||
|
||||
if model == MODEL_AIRPURIFIER_3C:
|
||||
return
|
||||
if model in MODELS_HUMIDIFIER_MIIO:
|
||||
entity_class = XiaomiAirHumidifierSelector
|
||||
elif model in MODELS_HUMIDIFIER_MIOT:
|
||||
entity_class = XiaomiAirHumidifierMiotSelector
|
||||
elif model in [MODEL_AIRPURIFIER_M1, MODEL_AIRPURIFIER_M2]:
|
||||
entity_class = XiaomiAirPurifierSelector
|
||||
elif model in MODELS_PURIFIER_MIOT:
|
||||
entity_class = XiaomiAirPurifierMiotSelector
|
||||
elif model == MODEL_AIRFRESH_VA2:
|
||||
entity_class = XiaomiAirFreshSelector
|
||||
elif model in (
|
||||
MODEL_FAN_ZA1,
|
||||
MODEL_FAN_ZA3,
|
||||
MODEL_FAN_ZA4,
|
||||
MODEL_FAN_SA1,
|
||||
MODEL_FAN_V2,
|
||||
MODEL_FAN_V3,
|
||||
):
|
||||
entity_class = XiaomiFanSelector
|
||||
else:
|
||||
return
|
||||
|
||||
description = SELECTOR_TYPES[FEATURE_SET_LED_BRIGHTNESS]
|
||||
entities.append(
|
||||
entity_class(
|
||||
device,
|
||||
config_entry,
|
||||
f"{description.key}_{config_entry.unique_id}",
|
||||
hass.data[DOMAIN][config_entry.entry_id][KEY_COORDINATOR],
|
||||
description,
|
||||
)
|
||||
)
|
||||
for description in SELECTOR_TYPES:
|
||||
for attribute in attributes:
|
||||
if description.key == attribute.attr_name:
|
||||
entities.append(
|
||||
XiaomiGenericSelector(
|
||||
device,
|
||||
config_entry,
|
||||
f"{description.key}_{unique_id}",
|
||||
coordinator,
|
||||
description,
|
||||
attribute.enum_class,
|
||||
)
|
||||
)
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
|
@ -141,129 +212,60 @@ class XiaomiSelector(XiaomiCoordinatedMiioEntity, SelectEntity):
|
|||
self.entity_description = description
|
||||
|
||||
|
||||
class XiaomiAirHumidifierSelector(XiaomiSelector):
|
||||
"""Representation of a Xiaomi Air Humidifier selector."""
|
||||
class XiaomiGenericSelector(XiaomiSelector):
|
||||
"""Representation of a Xiaomi generic selector."""
|
||||
|
||||
def __init__(self, device, entry, unique_id, coordinator, description):
|
||||
"""Initialize the plug switch."""
|
||||
entity_description: XiaomiMiioSelectDescription
|
||||
|
||||
def __init__(self, device, entry, unique_id, coordinator, description, enum_class):
|
||||
"""Initialize the generic Xiaomi attribute selector."""
|
||||
super().__init__(device, entry, unique_id, coordinator, description)
|
||||
self._current_led_brightness = self._extract_value_from_attribute(
|
||||
self.coordinator.data, self.entity_description.key
|
||||
self._current_attr = enum_class(
|
||||
self._extract_value_from_attribute(
|
||||
self.coordinator.data, self.entity_description.attr_name
|
||||
)
|
||||
)
|
||||
|
||||
if description.options_map:
|
||||
self._options_map = {}
|
||||
for key, val in enum_class._member_map_.items():
|
||||
self._options_map[description.options_map[key]] = val
|
||||
else:
|
||||
self._options_map = enum_class._member_map_
|
||||
self._reverse_map = {val: key for key, val in self._options_map.items()}
|
||||
self._enum_class = enum_class
|
||||
|
||||
@callback
|
||||
def _handle_coordinator_update(self):
|
||||
"""Fetch state from the device."""
|
||||
led_brightness = self._extract_value_from_attribute(
|
||||
self.coordinator.data, self.entity_description.key
|
||||
attr = self._enum_class(
|
||||
self._extract_value_from_attribute(
|
||||
self.coordinator.data, self.entity_description.attr_name
|
||||
)
|
||||
)
|
||||
# Sometimes (quite rarely) the device returns None as the LED brightness so we
|
||||
# check that the value is not None before updating the state.
|
||||
if led_brightness is not None:
|
||||
self._current_led_brightness = led_brightness
|
||||
if attr is not None:
|
||||
self._current_attr = attr
|
||||
self.async_write_ha_state()
|
||||
|
||||
@property
|
||||
def current_option(self) -> str:
|
||||
def current_option(self) -> str | None:
|
||||
"""Return the current option."""
|
||||
return self.led_brightness.lower()
|
||||
option = self._reverse_map.get(self._current_attr)
|
||||
if option is not None:
|
||||
return option.lower()
|
||||
return None
|
||||
|
||||
async def async_select_option(self, option: str) -> None:
|
||||
"""Set an option of the miio device."""
|
||||
await self.async_set_led_brightness(option.title())
|
||||
await self.async_set_attr(option.title())
|
||||
|
||||
@property
|
||||
def led_brightness(self):
|
||||
"""Return the current led brightness."""
|
||||
return LED_BRIGHTNESS_REVERSE_MAP.get(self._current_led_brightness)
|
||||
|
||||
async def async_set_led_brightness(self, brightness: str):
|
||||
"""Set the led brightness."""
|
||||
async def async_set_attr(self, attr_value: str):
|
||||
"""Set attr."""
|
||||
method = getattr(self._device, self.entity_description.set_method)
|
||||
if await self._try_command(
|
||||
"Setting the led brightness of the miio device failed.",
|
||||
self._device.set_led_brightness,
|
||||
AirhumidifierLedBrightness(LED_BRIGHTNESS_MAP[brightness]),
|
||||
self.entity_description.set_method_error_message,
|
||||
method,
|
||||
self._enum_class(self._options_map[attr_value]),
|
||||
):
|
||||
self._current_led_brightness = LED_BRIGHTNESS_MAP[brightness]
|
||||
self.async_write_ha_state()
|
||||
|
||||
|
||||
class XiaomiAirHumidifierMiotSelector(XiaomiAirHumidifierSelector):
|
||||
"""Representation of a Xiaomi Air Humidifier (MiOT protocol) selector."""
|
||||
|
||||
@property
|
||||
def led_brightness(self):
|
||||
"""Return the current led brightness."""
|
||||
return LED_BRIGHTNESS_REVERSE_MAP_HUMIDIFIER_MIOT.get(
|
||||
self._current_led_brightness
|
||||
)
|
||||
|
||||
async def async_set_led_brightness(self, brightness: str) -> None:
|
||||
"""Set the led brightness."""
|
||||
if await self._try_command(
|
||||
"Setting the led brightness of the miio device failed.",
|
||||
self._device.set_led_brightness,
|
||||
AirhumidifierMiotLedBrightness(
|
||||
LED_BRIGHTNESS_MAP_HUMIDIFIER_MIOT[brightness]
|
||||
),
|
||||
):
|
||||
self._current_led_brightness = LED_BRIGHTNESS_MAP_HUMIDIFIER_MIOT[
|
||||
brightness
|
||||
]
|
||||
self.async_write_ha_state()
|
||||
|
||||
|
||||
class XiaomiAirPurifierSelector(XiaomiAirHumidifierSelector):
|
||||
"""Representation of a Xiaomi Air Purifier (MIIO protocol) selector."""
|
||||
|
||||
async def async_set_led_brightness(self, brightness: str) -> None:
|
||||
"""Set the led brightness."""
|
||||
if await self._try_command(
|
||||
"Setting the led brightness of the miio device failed.",
|
||||
self._device.set_led_brightness,
|
||||
AirpurifierLedBrightness(LED_BRIGHTNESS_MAP[brightness]),
|
||||
):
|
||||
self._current_led_brightness = LED_BRIGHTNESS_MAP[brightness]
|
||||
self.async_write_ha_state()
|
||||
|
||||
|
||||
class XiaomiAirPurifierMiotSelector(XiaomiAirHumidifierSelector):
|
||||
"""Representation of a Xiaomi Air Purifier (MiOT protocol) selector."""
|
||||
|
||||
async def async_set_led_brightness(self, brightness: str) -> None:
|
||||
"""Set the led brightness."""
|
||||
if await self._try_command(
|
||||
"Setting the led brightness of the miio device failed.",
|
||||
self._device.set_led_brightness,
|
||||
AirpurifierMiotLedBrightness(LED_BRIGHTNESS_MAP[brightness]),
|
||||
):
|
||||
self._current_led_brightness = LED_BRIGHTNESS_MAP[brightness]
|
||||
self.async_write_ha_state()
|
||||
|
||||
|
||||
class XiaomiFanSelector(XiaomiAirHumidifierSelector):
|
||||
"""Representation of a Xiaomi Fan (MIIO protocol) selector."""
|
||||
|
||||
async def async_set_led_brightness(self, brightness: str) -> None:
|
||||
"""Set the led brightness."""
|
||||
if await self._try_command(
|
||||
"Setting the led brightness of the miio device failed.",
|
||||
self._device.set_led_brightness,
|
||||
FanLedBrightness(LED_BRIGHTNESS_MAP[brightness]),
|
||||
):
|
||||
self._current_led_brightness = LED_BRIGHTNESS_MAP[brightness]
|
||||
self.async_write_ha_state()
|
||||
|
||||
|
||||
class XiaomiAirFreshSelector(XiaomiAirHumidifierSelector):
|
||||
"""Representation of a Xiaomi Air Fresh selector."""
|
||||
|
||||
async def async_set_led_brightness(self, brightness: str) -> None:
|
||||
"""Set the led brightness."""
|
||||
if await self._try_command(
|
||||
"Setting the led brightness of the miio device failed.",
|
||||
self._device.set_led_brightness,
|
||||
AirfreshLedBrightness(LED_BRIGHTNESS_MAP[brightness]),
|
||||
):
|
||||
self._current_led_brightness = LED_BRIGHTNESS_MAP[brightness]
|
||||
self._current_attr = self._options_map[attr_value]
|
||||
self.async_write_ha_state()
|
||||
|
|
|
@ -4,6 +4,16 @@
|
|||
"bright": "Bright",
|
||||
"dim": "Dim",
|
||||
"off": "Off"
|
||||
},
|
||||
"xiaomi_miio__display_orientation": {
|
||||
"forward": "Forward",
|
||||
"left": "Left",
|
||||
"right": "Right"
|
||||
},
|
||||
"xiaomi_miio__ptc_level": {
|
||||
"low": "Low",
|
||||
"medium": "Medium",
|
||||
"high": "High"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
158
tests/components/xiaomi_miio/test_select.py
Normal file
158
tests/components/xiaomi_miio/test_select.py
Normal file
|
@ -0,0 +1,158 @@
|
|||
"""The tests for the xiaomi_miio select component."""
|
||||
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from arrow import utcnow
|
||||
from miio.integrations.airpurifier.dmaker.airfresh_t2017 import (
|
||||
DisplayOrientation,
|
||||
PtcLevel,
|
||||
)
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.select import DOMAIN
|
||||
from homeassistant.components.select.const import (
|
||||
ATTR_OPTION,
|
||||
ATTR_OPTIONS,
|
||||
SERVICE_SELECT_OPTION,
|
||||
)
|
||||
from homeassistant.components.xiaomi_miio import UPDATE_INTERVAL
|
||||
from homeassistant.components.xiaomi_miio.const import (
|
||||
CONF_DEVICE,
|
||||
CONF_FLOW_TYPE,
|
||||
CONF_MAC,
|
||||
DOMAIN as XIAOMI_DOMAIN,
|
||||
MODEL_AIRFRESH_T2017,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
CONF_HOST,
|
||||
CONF_MODEL,
|
||||
CONF_TOKEN,
|
||||
Platform,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
from tests.components.xiaomi_miio import TEST_MAC
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
async def setup_test(hass: HomeAssistant):
|
||||
"""Initialize test xiaomi_miio for select entity."""
|
||||
|
||||
mock_airfresh = MagicMock()
|
||||
mock_airfresh.status().display_orientation = DisplayOrientation.Portrait
|
||||
mock_airfresh.status().ptc_level = PtcLevel.Low
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.xiaomi_miio.get_platforms",
|
||||
return_value=[
|
||||
Platform.SELECT,
|
||||
],
|
||||
), patch("homeassistant.components.xiaomi_miio.AirFreshT2017") as mock_airfresh_cls:
|
||||
mock_airfresh_cls.return_value = mock_airfresh
|
||||
yield mock_airfresh
|
||||
|
||||
|
||||
async def test_select_params(hass: HomeAssistant) -> None:
|
||||
"""Test the initial parameters."""
|
||||
|
||||
entity_name = "test_airfresh_select"
|
||||
entity_id = await setup_component(hass, entity_name)
|
||||
|
||||
select_entity = hass.states.get(entity_id + "_display_orientation")
|
||||
assert select_entity
|
||||
assert select_entity.state == "forward"
|
||||
assert select_entity.attributes.get(ATTR_OPTIONS) == ["forward", "left", "right"]
|
||||
|
||||
|
||||
async def test_select_bad_attr(hass: HomeAssistant) -> None:
|
||||
"""Test selecting a different option with invalid option value."""
|
||||
|
||||
entity_name = "test_airfresh_select"
|
||||
entity_id = await setup_component(hass, entity_name)
|
||||
|
||||
state = hass.states.get(entity_id + "_display_orientation")
|
||||
assert state
|
||||
assert state.state == "forward"
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
await hass.services.async_call(
|
||||
"select",
|
||||
SERVICE_SELECT_OPTION,
|
||||
{ATTR_OPTION: "up", ATTR_ENTITY_ID: entity_id + "_display_orientation"},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(entity_id + "_display_orientation")
|
||||
assert state
|
||||
assert state.state == "forward"
|
||||
|
||||
|
||||
async def test_select_option(hass: HomeAssistant) -> None:
|
||||
"""Test selecting of a option."""
|
||||
|
||||
entity_name = "test_airfresh_select"
|
||||
entity_id = await setup_component(hass, entity_name)
|
||||
|
||||
state = hass.states.get(entity_id + "_display_orientation")
|
||||
assert state
|
||||
assert state.state == "forward"
|
||||
|
||||
await hass.services.async_call(
|
||||
"select",
|
||||
SERVICE_SELECT_OPTION,
|
||||
{ATTR_OPTION: "left", ATTR_ENTITY_ID: entity_id + "_display_orientation"},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(entity_id + "_display_orientation")
|
||||
assert state
|
||||
assert state.state == "left"
|
||||
|
||||
|
||||
async def test_select_coordinator_update(hass: HomeAssistant, setup_test) -> None:
|
||||
"""Test coordinator update of a option."""
|
||||
|
||||
entity_name = "test_airfresh_select"
|
||||
entity_id = await setup_component(hass, entity_name)
|
||||
|
||||
state = hass.states.get(entity_id + "_display_orientation")
|
||||
assert state
|
||||
assert state.state == "forward"
|
||||
|
||||
# emulate someone change state from device maybe used app
|
||||
setup_test.status().display_orientation = DisplayOrientation.LandscapeLeft
|
||||
|
||||
async_fire_time_changed(hass, utcnow() + UPDATE_INTERVAL)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(entity_id + "_display_orientation")
|
||||
assert state
|
||||
assert state.state == "left"
|
||||
|
||||
|
||||
async def setup_component(hass, entity_name):
|
||||
"""Set up component."""
|
||||
entity_id = f"{DOMAIN}.{entity_name}"
|
||||
|
||||
config_entry = MockConfigEntry(
|
||||
domain=XIAOMI_DOMAIN,
|
||||
unique_id="123456",
|
||||
title=entity_name,
|
||||
data={
|
||||
CONF_FLOW_TYPE: CONF_DEVICE,
|
||||
CONF_HOST: "0.0.0.0",
|
||||
CONF_TOKEN: "12345678901234567890123456789012",
|
||||
CONF_MODEL: MODEL_AIRFRESH_T2017,
|
||||
CONF_MAC: TEST_MAC,
|
||||
},
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
return entity_id
|
Loading…
Add table
Reference in a new issue