mirror of
https://github.com/home-assistant/core.git
synced 2025-07-25 22:27:07 +00:00
Add infrared brightness select entity for LIFX Night Vision bulbs (#77943)
* Add infrared brightness select entity for LIFX Night Vision bulbs Signed-off-by: Avi Miller <me@dje.li> * Code refactored from review comments Signed-off-by: Avi Miller <me@dje.li> * Update and refactor from code review feedback Signed-off-by: Avi Miller <me@dje.li> Signed-off-by: Avi Miller <me@dje.li>
This commit is contained in:
parent
ade4fcaebd
commit
c0cf9d8729
@ -57,7 +57,7 @@ CONFIG_SCHEMA = vol.All(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
PLATFORMS = [Platform.BINARY_SENSOR, Platform.BUTTON, Platform.LIGHT]
|
PLATFORMS = [Platform.BINARY_SENSOR, Platform.BUTTON, Platform.LIGHT, Platform.SELECT]
|
||||||
DISCOVERY_INTERVAL = timedelta(minutes=15)
|
DISCOVERY_INTERVAL = timedelta(minutes=15)
|
||||||
MIGRATION_INTERVAL = timedelta(minutes=5)
|
MIGRATION_INTERVAL = timedelta(minutes=5)
|
||||||
|
|
||||||
|
@ -37,7 +37,13 @@ ATTR_REMAINING = "remaining"
|
|||||||
ATTR_ZONES = "zones"
|
ATTR_ZONES = "zones"
|
||||||
|
|
||||||
HEV_CYCLE_STATE = "hev_cycle_state"
|
HEV_CYCLE_STATE = "hev_cycle_state"
|
||||||
|
INFRARED_BRIGHTNESS = "infrared_brightness"
|
||||||
|
INFRARED_BRIGHTNESS_VALUES_MAP = {
|
||||||
|
0: "Disabled",
|
||||||
|
16383: "25%",
|
||||||
|
32767: "50%",
|
||||||
|
65535: "100%",
|
||||||
|
}
|
||||||
DATA_LIFX_MANAGER = "lifx_manager"
|
DATA_LIFX_MANAGER = "lifx_manager"
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__package__)
|
_LOGGER = logging.getLogger(__package__)
|
||||||
|
@ -9,20 +9,29 @@ from typing import Any, cast
|
|||||||
from aiolifx.aiolifx import Light
|
from aiolifx.aiolifx import Light
|
||||||
from aiolifx.connection import LIFXConnection
|
from aiolifx.connection import LIFXConnection
|
||||||
|
|
||||||
|
from homeassistant.const import Platform
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
|
from homeassistant.helpers import entity_registry as er
|
||||||
from homeassistant.helpers.debounce import Debouncer
|
from homeassistant.helpers.debounce import Debouncer
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
_LOGGER,
|
_LOGGER,
|
||||||
ATTR_REMAINING,
|
ATTR_REMAINING,
|
||||||
|
DOMAIN,
|
||||||
IDENTIFY_WAVEFORM,
|
IDENTIFY_WAVEFORM,
|
||||||
MESSAGE_RETRIES,
|
MESSAGE_RETRIES,
|
||||||
MESSAGE_TIMEOUT,
|
MESSAGE_TIMEOUT,
|
||||||
TARGET_ANY,
|
TARGET_ANY,
|
||||||
UNAVAILABLE_GRACE,
|
UNAVAILABLE_GRACE,
|
||||||
)
|
)
|
||||||
from .util import async_execute_lifx, get_real_mac_addr, lifx_features
|
from .util import (
|
||||||
|
async_execute_lifx,
|
||||||
|
get_real_mac_addr,
|
||||||
|
infrared_brightness_option_to_value,
|
||||||
|
infrared_brightness_value_to_option,
|
||||||
|
lifx_features,
|
||||||
|
)
|
||||||
|
|
||||||
REQUEST_REFRESH_DELAY = 0.35
|
REQUEST_REFRESH_DELAY = 0.35
|
||||||
LIFX_IDENTIFY_DELAY = 3.0
|
LIFX_IDENTIFY_DELAY = 3.0
|
||||||
@ -83,6 +92,18 @@ class LIFXUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
"""Return the label of the bulb."""
|
"""Return the label of the bulb."""
|
||||||
return cast(str, self.device.label)
|
return cast(str, self.device.label)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_infrared_brightness(self) -> str | None:
|
||||||
|
"""Return the current infrared brightness as a string."""
|
||||||
|
return infrared_brightness_value_to_option(self.device.infrared_brightness)
|
||||||
|
|
||||||
|
def async_get_entity_id(self, platform: Platform, key: str) -> str | None:
|
||||||
|
"""Return the entity_id from the platform and key provided."""
|
||||||
|
ent_reg = er.async_get(self.hass)
|
||||||
|
return ent_reg.async_get_entity_id(
|
||||||
|
platform, DOMAIN, f"{self.serial_number}_{key}"
|
||||||
|
)
|
||||||
|
|
||||||
async def async_identify_bulb(self) -> None:
|
async def async_identify_bulb(self) -> None:
|
||||||
"""Identify the device by flashing it three times."""
|
"""Identify the device by flashing it three times."""
|
||||||
bulb: Light = self.device
|
bulb: Light = self.device
|
||||||
@ -103,6 +124,7 @@ class LIFXUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
self.device.get_hostfirmware()
|
self.device.get_hostfirmware()
|
||||||
if self.device.product is None:
|
if self.device.product is None:
|
||||||
self.device.get_version()
|
self.device.get_version()
|
||||||
|
|
||||||
response = await async_execute_lifx(self.device.get_color)
|
response = await async_execute_lifx(self.device.get_color)
|
||||||
|
|
||||||
if self.device.product is None:
|
if self.device.product is None:
|
||||||
@ -114,12 +136,16 @@ class LIFXUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
if self.device.mac_addr == TARGET_ANY:
|
if self.device.mac_addr == TARGET_ANY:
|
||||||
self.device.mac_addr = response.target_addr
|
self.device.mac_addr = response.target_addr
|
||||||
|
|
||||||
|
# Update model-specific configuration
|
||||||
if lifx_features(self.device)["multizone"]:
|
if lifx_features(self.device)["multizone"]:
|
||||||
await self.async_update_color_zones()
|
await self.async_update_color_zones()
|
||||||
|
|
||||||
if lifx_features(self.device)["hev"]:
|
if lifx_features(self.device)["hev"]:
|
||||||
await self.async_get_hev_cycle()
|
await self.async_get_hev_cycle()
|
||||||
|
|
||||||
|
if lifx_features(self.device)["infrared"]:
|
||||||
|
response = await async_execute_lifx(self.device.get_infrared)
|
||||||
|
|
||||||
async def async_update_color_zones(self) -> None:
|
async def async_update_color_zones(self) -> None:
|
||||||
"""Get updated color information for each zone."""
|
"""Get updated color information for each zone."""
|
||||||
zone = 0
|
zone = 0
|
||||||
@ -199,3 +225,8 @@ class LIFXUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
await async_execute_lifx(
|
await async_execute_lifx(
|
||||||
partial(self.device.set_hev_cycle, enable=enable, duration=duration)
|
partial(self.device.set_hev_cycle, enable=enable, duration=duration)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def async_set_infrared_brightness(self, option: str) -> None:
|
||||||
|
"""Set infrared brightness."""
|
||||||
|
infrared_brightness = infrared_brightness_option_to_value(option)
|
||||||
|
await async_execute_lifx(partial(self.device.set_infrared, infrared_brightness))
|
||||||
|
@ -19,7 +19,7 @@ from homeassistant.components.light import (
|
|||||||
LightEntityFeature,
|
LightEntityFeature,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import ATTR_ENTITY_ID
|
from homeassistant.const import ATTR_ENTITY_ID, Platform
|
||||||
from homeassistant.core import CALLBACK_TYPE, HomeAssistant
|
from homeassistant.core import CALLBACK_TYPE, HomeAssistant
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers import entity_platform
|
from homeassistant.helpers import entity_platform
|
||||||
@ -29,12 +29,14 @@ from homeassistant.helpers.event import async_track_point_in_utc_time
|
|||||||
import homeassistant.util.color as color_util
|
import homeassistant.util.color as color_util
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
|
_LOGGER,
|
||||||
ATTR_DURATION,
|
ATTR_DURATION,
|
||||||
ATTR_INFRARED,
|
ATTR_INFRARED,
|
||||||
ATTR_POWER,
|
ATTR_POWER,
|
||||||
ATTR_ZONES,
|
ATTR_ZONES,
|
||||||
DATA_LIFX_MANAGER,
|
DATA_LIFX_MANAGER,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
|
INFRARED_BRIGHTNESS,
|
||||||
)
|
)
|
||||||
from .coordinator import LIFXUpdateCoordinator
|
from .coordinator import LIFXUpdateCoordinator
|
||||||
from .entity import LIFXEntity
|
from .entity import LIFXEntity
|
||||||
@ -212,6 +214,13 @@ class LIFXLight(LIFXEntity, LightEntity):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if ATTR_INFRARED in kwargs:
|
if ATTR_INFRARED in kwargs:
|
||||||
|
infrared_entity_id = self.coordinator.async_get_entity_id(
|
||||||
|
Platform.SELECT, INFRARED_BRIGHTNESS
|
||||||
|
)
|
||||||
|
_LOGGER.warning(
|
||||||
|
"The 'infrared' attribute of 'lifx.set_state' is deprecated: call 'select.select_option' targeting '%s' instead",
|
||||||
|
infrared_entity_id,
|
||||||
|
)
|
||||||
bulb.set_infrared(convert_8_to_16(kwargs[ATTR_INFRARED]))
|
bulb.set_infrared(convert_8_to_16(kwargs[ATTR_INFRARED]))
|
||||||
|
|
||||||
if ATTR_TRANSITION in kwargs:
|
if ATTR_TRANSITION in kwargs:
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "LIFX",
|
"name": "LIFX",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/lifx",
|
"documentation": "https://www.home-assistant.io/integrations/lifx",
|
||||||
"requirements": ["aiolifx==0.8.2", "aiolifx_effects==0.2.2"],
|
"requirements": ["aiolifx==0.8.4", "aiolifx_effects==0.2.2"],
|
||||||
"quality_scale": "platinum",
|
"quality_scale": "platinum",
|
||||||
"dependencies": ["network"],
|
"dependencies": ["network"],
|
||||||
"homekit": {
|
"homekit": {
|
||||||
|
69
homeassistant/components/lifx/select.py
Normal file
69
homeassistant/components/lifx/select.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
"""Select sensor entities for LIFX integration."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from homeassistant.components.select import SelectEntity, SelectEntityDescription
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.core import HomeAssistant, callback
|
||||||
|
from homeassistant.helpers.entity import EntityCategory
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
|
from .const import DOMAIN, INFRARED_BRIGHTNESS, INFRARED_BRIGHTNESS_VALUES_MAP
|
||||||
|
from .coordinator import LIFXUpdateCoordinator
|
||||||
|
from .entity import LIFXEntity
|
||||||
|
from .util import lifx_features
|
||||||
|
|
||||||
|
INFRARED_BRIGHTNESS_ENTITY = SelectEntityDescription(
|
||||||
|
key=INFRARED_BRIGHTNESS,
|
||||||
|
name="Infrared brightness",
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
)
|
||||||
|
|
||||||
|
INFRARED_BRIGHTNESS_OPTIONS = list(INFRARED_BRIGHTNESS_VALUES_MAP.values())
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||||
|
) -> None:
|
||||||
|
"""Set up LIFX from a config entry."""
|
||||||
|
coordinator: LIFXUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
||||||
|
|
||||||
|
if lifx_features(coordinator.device)["infrared"]:
|
||||||
|
async_add_entities(
|
||||||
|
[
|
||||||
|
LIFXInfraredBrightnessSelectEntity(
|
||||||
|
coordinator, description=INFRARED_BRIGHTNESS_ENTITY
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class LIFXInfraredBrightnessSelectEntity(LIFXEntity, SelectEntity):
|
||||||
|
"""LIFX Nightvision infrared brightness configuration entity."""
|
||||||
|
|
||||||
|
_attr_has_entity_name = True
|
||||||
|
_attr_options = INFRARED_BRIGHTNESS_OPTIONS
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, coordinator: LIFXUpdateCoordinator, description: SelectEntityDescription
|
||||||
|
) -> None:
|
||||||
|
"""Initialise the IR brightness config entity."""
|
||||||
|
super().__init__(coordinator)
|
||||||
|
self.entity_description = description
|
||||||
|
self._attr_name = description.name
|
||||||
|
self._attr_unique_id = f"{coordinator.serial_number}_{description.key}"
|
||||||
|
self._attr_current_option = coordinator.current_infrared_brightness
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _handle_coordinator_update(self) -> None:
|
||||||
|
"""Handle updated data from the coordinator."""
|
||||||
|
self._async_update_attrs()
|
||||||
|
super()._handle_coordinator_update()
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _async_update_attrs(self) -> None:
|
||||||
|
"""Handle coordinator updates."""
|
||||||
|
self._attr_current_option = self.coordinator.current_infrared_brightness
|
||||||
|
|
||||||
|
async def async_select_option(self, option: str) -> None:
|
||||||
|
"""Update the infrared brightness value."""
|
||||||
|
await self.coordinator.async_set_infrared_brightness(option)
|
@ -25,7 +25,7 @@ from homeassistant.core import HomeAssistant, callback
|
|||||||
from homeassistant.helpers import device_registry as dr
|
from homeassistant.helpers import device_registry as dr
|
||||||
import homeassistant.util.color as color_util
|
import homeassistant.util.color as color_util
|
||||||
|
|
||||||
from .const import _LOGGER, DOMAIN, OVERALL_TIMEOUT
|
from .const import _LOGGER, DOMAIN, INFRARED_BRIGHTNESS_VALUES_MAP, OVERALL_TIMEOUT
|
||||||
|
|
||||||
FIX_MAC_FW = AwesomeVersion("3.70")
|
FIX_MAC_FW = AwesomeVersion("3.70")
|
||||||
|
|
||||||
@ -45,6 +45,17 @@ def async_get_legacy_entry(hass: HomeAssistant) -> ConfigEntry | None:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def infrared_brightness_value_to_option(value: int) -> str | None:
|
||||||
|
"""Convert infrared brightness from value to option."""
|
||||||
|
return INFRARED_BRIGHTNESS_VALUES_MAP.get(value, None)
|
||||||
|
|
||||||
|
|
||||||
|
def infrared_brightness_option_to_value(option: str) -> int | None:
|
||||||
|
"""Convert infrared brightness option to value."""
|
||||||
|
option_values = {v: k for k, v in INFRARED_BRIGHTNESS_VALUES_MAP.items()}
|
||||||
|
return option_values.get(option, None)
|
||||||
|
|
||||||
|
|
||||||
def convert_8_to_16(value: int) -> int:
|
def convert_8_to_16(value: int) -> int:
|
||||||
"""Scale an 8 bit level into 16 bits."""
|
"""Scale an 8 bit level into 16 bits."""
|
||||||
return (value << 8) | value
|
return (value << 8) | value
|
||||||
|
@ -190,7 +190,7 @@ aiokafka==0.7.2
|
|||||||
aiokef==0.2.16
|
aiokef==0.2.16
|
||||||
|
|
||||||
# homeassistant.components.lifx
|
# homeassistant.components.lifx
|
||||||
aiolifx==0.8.2
|
aiolifx==0.8.4
|
||||||
|
|
||||||
# homeassistant.components.lifx
|
# homeassistant.components.lifx
|
||||||
aiolifx_effects==0.2.2
|
aiolifx_effects==0.2.2
|
||||||
|
@ -168,7 +168,7 @@ aiohue==4.5.0
|
|||||||
aiokafka==0.7.2
|
aiokafka==0.7.2
|
||||||
|
|
||||||
# homeassistant.components.lifx
|
# homeassistant.components.lifx
|
||||||
aiolifx==0.8.2
|
aiolifx==0.8.4
|
||||||
|
|
||||||
# homeassistant.components.lifx
|
# homeassistant.components.lifx
|
||||||
aiolifx_effects==0.2.2
|
aiolifx_effects==0.2.2
|
||||||
|
@ -62,6 +62,9 @@ class MockLifxCommand:
|
|||||||
self.bulb = bulb
|
self.bulb = bulb
|
||||||
self.calls = []
|
self.calls = []
|
||||||
self.msg_kwargs = kwargs
|
self.msg_kwargs = kwargs
|
||||||
|
for k, v in kwargs.items():
|
||||||
|
if k != "callb":
|
||||||
|
setattr(self.bulb, k, v)
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs):
|
def __call__(self, *args, **kwargs):
|
||||||
"""Call command."""
|
"""Call command."""
|
||||||
@ -130,6 +133,15 @@ def _mocked_clean_bulb() -> Light:
|
|||||||
return bulb
|
return bulb
|
||||||
|
|
||||||
|
|
||||||
|
def _mocked_infrared_bulb() -> Light:
|
||||||
|
bulb = _mocked_bulb()
|
||||||
|
bulb.product = 29 # LIFX A19 Night Vision
|
||||||
|
bulb.infrared_brightness = 65535
|
||||||
|
bulb.set_infrared = MockLifxCommand(bulb)
|
||||||
|
bulb.get_infrared = MockLifxCommand(bulb, infrared_brightness=65535)
|
||||||
|
return bulb
|
||||||
|
|
||||||
|
|
||||||
def _mocked_light_strip() -> Light:
|
def _mocked_light_strip() -> Light:
|
||||||
bulb = _mocked_bulb()
|
bulb = _mocked_bulb()
|
||||||
bulb.product = 31 # LIFX Z
|
bulb.product = 31 # LIFX Z
|
||||||
|
239
tests/components/lifx/test_select.py
Normal file
239
tests/components/lifx/test_select.py
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
"""Tests for the lifx integration select entity."""
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from homeassistant.components import lifx
|
||||||
|
from homeassistant.components.lifx.const import DOMAIN
|
||||||
|
from homeassistant.components.select import DOMAIN as SELECT_DOMAIN
|
||||||
|
from homeassistant.const import ATTR_ENTITY_ID, CONF_HOST, STATE_UNKNOWN
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import entity_registry as er
|
||||||
|
from homeassistant.setup import async_setup_component
|
||||||
|
from homeassistant.util import dt as dt_util
|
||||||
|
|
||||||
|
from . import (
|
||||||
|
DEFAULT_ENTRY_TITLE,
|
||||||
|
IP_ADDRESS,
|
||||||
|
MAC_ADDRESS,
|
||||||
|
SERIAL,
|
||||||
|
MockLifxCommand,
|
||||||
|
_mocked_infrared_bulb,
|
||||||
|
_patch_config_flow_try_connect,
|
||||||
|
_patch_device,
|
||||||
|
_patch_discovery,
|
||||||
|
)
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||||
|
|
||||||
|
|
||||||
|
async def test_infrared_brightness(hass: HomeAssistant) -> None:
|
||||||
|
"""Test getting and setting infrared brightness."""
|
||||||
|
|
||||||
|
config_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
title=DEFAULT_ENTRY_TITLE,
|
||||||
|
data={CONF_HOST: IP_ADDRESS},
|
||||||
|
unique_id=MAC_ADDRESS,
|
||||||
|
)
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
bulb = _mocked_infrared_bulb()
|
||||||
|
with _patch_discovery(device=bulb), _patch_config_flow_try_connect(
|
||||||
|
device=bulb
|
||||||
|
), _patch_device(device=bulb):
|
||||||
|
await async_setup_component(hass, lifx.DOMAIN, {lifx.DOMAIN: {}})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
unique_id = f"{SERIAL}_infrared_brightness"
|
||||||
|
entity_id = "select.my_bulb_infrared_brightness"
|
||||||
|
|
||||||
|
entity_registry = er.async_get(hass)
|
||||||
|
entity = entity_registry.async_get(entity_id)
|
||||||
|
assert entity
|
||||||
|
assert not entity.disabled
|
||||||
|
assert entity.unique_id == unique_id
|
||||||
|
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state.state == "100%"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_set_infrared_brightness_25_percent(hass: HomeAssistant) -> None:
|
||||||
|
"""Test getting and setting infrared brightness."""
|
||||||
|
|
||||||
|
config_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
title=DEFAULT_ENTRY_TITLE,
|
||||||
|
data={CONF_HOST: IP_ADDRESS},
|
||||||
|
unique_id=MAC_ADDRESS,
|
||||||
|
)
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
bulb = _mocked_infrared_bulb()
|
||||||
|
with _patch_discovery(device=bulb), _patch_config_flow_try_connect(
|
||||||
|
device=bulb
|
||||||
|
), _patch_device(device=bulb):
|
||||||
|
await async_setup_component(hass, lifx.DOMAIN, {lifx.DOMAIN: {}})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
entity_id = "select.my_bulb_infrared_brightness"
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
SELECT_DOMAIN,
|
||||||
|
"select_option",
|
||||||
|
{ATTR_ENTITY_ID: entity_id, "option": "25%"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
bulb.get_infrared = MockLifxCommand(bulb, infrared_brightness=16383)
|
||||||
|
|
||||||
|
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=30))
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert bulb.set_infrared.calls[0][0][0] == 16383
|
||||||
|
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state.state == "25%"
|
||||||
|
|
||||||
|
bulb.set_infrared.reset_mock()
|
||||||
|
|
||||||
|
|
||||||
|
async def test_set_infrared_brightness_50_percent(hass: HomeAssistant) -> None:
|
||||||
|
"""Test getting and setting infrared brightness."""
|
||||||
|
|
||||||
|
config_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
title=DEFAULT_ENTRY_TITLE,
|
||||||
|
data={CONF_HOST: IP_ADDRESS},
|
||||||
|
unique_id=MAC_ADDRESS,
|
||||||
|
)
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
bulb = _mocked_infrared_bulb()
|
||||||
|
with _patch_discovery(device=bulb), _patch_config_flow_try_connect(
|
||||||
|
device=bulb
|
||||||
|
), _patch_device(device=bulb):
|
||||||
|
await async_setup_component(hass, lifx.DOMAIN, {lifx.DOMAIN: {}})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
entity_id = "select.my_bulb_infrared_brightness"
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
SELECT_DOMAIN,
|
||||||
|
"select_option",
|
||||||
|
{ATTR_ENTITY_ID: entity_id, "option": "50%"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
bulb.get_infrared = MockLifxCommand(bulb, infrared_brightness=32767)
|
||||||
|
|
||||||
|
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=30))
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert bulb.set_infrared.calls[0][0][0] == 32767
|
||||||
|
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state.state == "50%"
|
||||||
|
|
||||||
|
bulb.set_infrared.reset_mock()
|
||||||
|
|
||||||
|
|
||||||
|
async def test_set_infrared_brightness_100_percent(hass: HomeAssistant) -> None:
|
||||||
|
"""Test getting and setting infrared brightness."""
|
||||||
|
|
||||||
|
config_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
title=DEFAULT_ENTRY_TITLE,
|
||||||
|
data={CONF_HOST: IP_ADDRESS},
|
||||||
|
unique_id=MAC_ADDRESS,
|
||||||
|
)
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
bulb = _mocked_infrared_bulb()
|
||||||
|
with _patch_discovery(device=bulb), _patch_config_flow_try_connect(
|
||||||
|
device=bulb
|
||||||
|
), _patch_device(device=bulb):
|
||||||
|
await async_setup_component(hass, lifx.DOMAIN, {lifx.DOMAIN: {}})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
entity_id = "select.my_bulb_infrared_brightness"
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
SELECT_DOMAIN,
|
||||||
|
"select_option",
|
||||||
|
{ATTR_ENTITY_ID: entity_id, "option": "100%"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
bulb.get_infrared = MockLifxCommand(bulb, infrared_brightness=65535)
|
||||||
|
|
||||||
|
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=30))
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert bulb.set_infrared.calls[0][0][0] == 65535
|
||||||
|
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state.state == "100%"
|
||||||
|
|
||||||
|
bulb.set_infrared.reset_mock()
|
||||||
|
|
||||||
|
|
||||||
|
async def test_disable_infrared(hass: HomeAssistant) -> None:
|
||||||
|
"""Test getting and setting infrared brightness."""
|
||||||
|
|
||||||
|
config_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
title=DEFAULT_ENTRY_TITLE,
|
||||||
|
data={CONF_HOST: IP_ADDRESS},
|
||||||
|
unique_id=MAC_ADDRESS,
|
||||||
|
)
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
bulb = _mocked_infrared_bulb()
|
||||||
|
with _patch_discovery(device=bulb), _patch_config_flow_try_connect(
|
||||||
|
device=bulb
|
||||||
|
), _patch_device(device=bulb):
|
||||||
|
await async_setup_component(hass, lifx.DOMAIN, {lifx.DOMAIN: {}})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
entity_id = "select.my_bulb_infrared_brightness"
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
SELECT_DOMAIN,
|
||||||
|
"select_option",
|
||||||
|
{ATTR_ENTITY_ID: entity_id, "option": "Disabled"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
bulb.get_infrared = MockLifxCommand(bulb, infrared_brightness=0)
|
||||||
|
|
||||||
|
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=30))
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert bulb.set_infrared.calls[0][0][0] == 0
|
||||||
|
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state.state == "Disabled"
|
||||||
|
|
||||||
|
bulb.set_infrared.reset_mock()
|
||||||
|
|
||||||
|
|
||||||
|
async def test_invalid_infrared_brightness(hass: HomeAssistant) -> None:
|
||||||
|
"""Test getting and setting infrared brightness."""
|
||||||
|
|
||||||
|
config_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
title=DEFAULT_ENTRY_TITLE,
|
||||||
|
data={CONF_HOST: IP_ADDRESS},
|
||||||
|
unique_id=MAC_ADDRESS,
|
||||||
|
)
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
bulb = _mocked_infrared_bulb()
|
||||||
|
with _patch_discovery(device=bulb), _patch_config_flow_try_connect(
|
||||||
|
device=bulb
|
||||||
|
), _patch_device(device=bulb):
|
||||||
|
await async_setup_component(hass, lifx.DOMAIN, {lifx.DOMAIN: {}})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
entity_id = "select.my_bulb_infrared_brightness"
|
||||||
|
|
||||||
|
bulb.get_infrared = MockLifxCommand(bulb, infrared_brightness=12345)
|
||||||
|
|
||||||
|
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=30))
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state.state == STATE_UNKNOWN
|
Loading…
x
Reference in New Issue
Block a user