core/tests/components/blebox/test_light.py

615 lines
18 KiB
Python
Raw Normal View History

"""BleBox light entities tests."""
import logging
2021-01-01 21:31:56 +00:00
from unittest.mock import AsyncMock, PropertyMock
import blebox_uniapi
import pytest
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
ATTR_HS_COLOR,
ATTR_WHITE_VALUE,
SUPPORT_BRIGHTNESS,
SUPPORT_COLOR,
SUPPORT_WHITE_VALUE,
)
from homeassistant.const import (
ATTR_SUPPORTED_FEATURES,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
STATE_OFF,
STATE_ON,
)
from homeassistant.helpers import device_registry as dr
from homeassistant.util import color
from .conftest import async_setup_entity, mock_feature
ALL_LIGHT_FIXTURES = ["dimmer", "wlightbox_s", "wlightbox"]
@pytest.fixture(name="dimmer")
def dimmer_fixture():
"""Return a default light entity mock."""
feature = mock_feature(
"lights",
blebox_uniapi.light.Light,
unique_id="BleBox-dimmerBox-1afe34e750b8-brightness",
full_name="dimmerBox-brightness",
device_class=None,
brightness=65,
is_on=True,
supports_color=False,
supports_white=False,
)
product = feature.product
type(product).name = PropertyMock(return_value="My dimmer")
type(product).model = PropertyMock(return_value="dimmerBox")
return (feature, "light.dimmerbox_brightness")
async def test_dimmer_init(dimmer, hass, config):
"""Test cover default state."""
_, entity_id = dimmer
entry = await async_setup_entity(hass, config, entity_id)
assert entry.unique_id == "BleBox-dimmerBox-1afe34e750b8-brightness"
state = hass.states.get(entity_id)
assert state.name == "dimmerBox-brightness"
supported_features = state.attributes[ATTR_SUPPORTED_FEATURES]
assert supported_features & SUPPORT_BRIGHTNESS
assert state.attributes[ATTR_BRIGHTNESS] == 65
assert state.state == STATE_ON
device_registry = dr.async_get(hass)
device = device_registry.async_get(entry.device_id)
assert device.name == "My dimmer"
assert device.identifiers == {("blebox", "abcd0123ef5678")}
assert device.manufacturer == "BleBox"
assert device.model == "dimmerBox"
assert device.sw_version == "1.23"
async def test_dimmer_update(dimmer, hass, config):
"""Test light updating."""
feature_mock, entity_id = dimmer
def initial_update():
feature_mock.brightness = 53
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
state = hass.states.get(entity_id)
assert state.attributes[ATTR_BRIGHTNESS] == 53
assert state.state == STATE_ON
async def test_dimmer_on(dimmer, hass, config):
"""Test light on."""
feature_mock, entity_id = dimmer
def initial_update():
feature_mock.is_on = False
feature_mock.brightness = 0 # off
feature_mock.sensible_on_value = 254
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
feature_mock.async_update = AsyncMock()
state = hass.states.get(entity_id)
assert state.state == STATE_OFF
def turn_on(brightness):
assert brightness == 254
feature_mock.brightness = 254 # on
feature_mock.is_on = True # on
feature_mock.async_on = AsyncMock(side_effect=turn_on)
await hass.services.async_call(
2020-08-27 11:56:20 +00:00
"light",
SERVICE_TURN_ON,
{"entity_id": entity_id},
blocking=True,
)
state = hass.states.get(entity_id)
assert state.state == STATE_ON
assert state.attributes[ATTR_BRIGHTNESS] == 254
async def test_dimmer_on_with_brightness(dimmer, hass, config):
"""Test light on with a brightness value."""
feature_mock, entity_id = dimmer
def initial_update():
feature_mock.is_on = False
feature_mock.brightness = 0 # off
feature_mock.sensible_on_value = 254
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
feature_mock.async_update = AsyncMock()
state = hass.states.get(entity_id)
assert state.state == STATE_OFF
def turn_on(brightness):
assert brightness == 202
feature_mock.brightness = 202 # on
feature_mock.is_on = True # on
feature_mock.async_on = AsyncMock(side_effect=turn_on)
def apply(value, brightness):
assert value == 254
return brightness
feature_mock.apply_brightness = apply
await hass.services.async_call(
"light",
SERVICE_TURN_ON,
{"entity_id": entity_id, ATTR_BRIGHTNESS: 202},
blocking=True,
)
state = hass.states.get(entity_id)
assert state.attributes[ATTR_BRIGHTNESS] == 202
assert state.state == STATE_ON
async def test_dimmer_off(dimmer, hass, config):
"""Test light off."""
feature_mock, entity_id = dimmer
def initial_update():
feature_mock.is_on = True
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
feature_mock.async_update = AsyncMock()
state = hass.states.get(entity_id)
assert state.state == STATE_ON
def turn_off():
feature_mock.is_on = False
feature_mock.brightness = 0 # off
feature_mock.async_off = AsyncMock(side_effect=turn_off)
await hass.services.async_call(
2020-08-27 11:56:20 +00:00
"light",
SERVICE_TURN_OFF,
{"entity_id": entity_id},
blocking=True,
)
state = hass.states.get(entity_id)
assert state.state == STATE_OFF
assert ATTR_BRIGHTNESS not in state.attributes
@pytest.fixture(name="wlightbox_s")
def wlightboxs_fixture():
"""Return a default light entity mock."""
feature = mock_feature(
"lights",
blebox_uniapi.light.Light,
unique_id="BleBox-wLightBoxS-1afe34e750b8-color",
full_name="wLightBoxS-color",
device_class=None,
brightness=None,
is_on=None,
supports_color=False,
supports_white=False,
)
product = feature.product
type(product).name = PropertyMock(return_value="My wLightBoxS")
type(product).model = PropertyMock(return_value="wLightBoxS")
return (feature, "light.wlightboxs_color")
async def test_wlightbox_s_init(wlightbox_s, hass, config):
"""Test cover default state."""
_, entity_id = wlightbox_s
entry = await async_setup_entity(hass, config, entity_id)
assert entry.unique_id == "BleBox-wLightBoxS-1afe34e750b8-color"
state = hass.states.get(entity_id)
assert state.name == "wLightBoxS-color"
supported_features = state.attributes[ATTR_SUPPORTED_FEATURES]
assert supported_features & SUPPORT_BRIGHTNESS
assert ATTR_BRIGHTNESS not in state.attributes
assert state.state == STATE_OFF
device_registry = dr.async_get(hass)
device = device_registry.async_get(entry.device_id)
assert device.name == "My wLightBoxS"
assert device.identifiers == {("blebox", "abcd0123ef5678")}
assert device.manufacturer == "BleBox"
assert device.model == "wLightBoxS"
assert device.sw_version == "1.23"
async def test_wlightbox_s_update(wlightbox_s, hass, config):
"""Test light updating."""
feature_mock, entity_id = wlightbox_s
def initial_update():
feature_mock.brightness = 0xAB
feature_mock.is_on = True
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
state = hass.states.get(entity_id)
assert state.state == STATE_ON
assert state.attributes[ATTR_BRIGHTNESS] == 0xAB
async def test_wlightbox_s_on(wlightbox_s, hass, config):
"""Test light on."""
feature_mock, entity_id = wlightbox_s
def initial_update():
feature_mock.is_on = False
feature_mock.sensible_on_value = 254
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
feature_mock.async_update = AsyncMock()
state = hass.states.get(entity_id)
assert state.state == STATE_OFF
def turn_on(brightness):
assert brightness == 254
feature_mock.brightness = 254 # on
feature_mock.is_on = True # on
feature_mock.async_on = AsyncMock(side_effect=turn_on)
await hass.services.async_call(
2020-08-27 11:56:20 +00:00
"light",
SERVICE_TURN_ON,
{"entity_id": entity_id},
blocking=True,
)
state = hass.states.get(entity_id)
assert state.attributes[ATTR_BRIGHTNESS] == 254
assert state.state == STATE_ON
@pytest.fixture(name="wlightbox")
def wlightbox_fixture():
"""Return a default light entity mock."""
feature = mock_feature(
"lights",
blebox_uniapi.light.Light,
unique_id="BleBox-wLightBox-1afe34e750b8-color",
full_name="wLightBox-color",
device_class=None,
is_on=None,
supports_color=True,
supports_white=True,
white_value=None,
rgbw_hex=None,
)
product = feature.product
type(product).name = PropertyMock(return_value="My wLightBox")
type(product).model = PropertyMock(return_value="wLightBox")
return (feature, "light.wlightbox_color")
async def test_wlightbox_init(wlightbox, hass, config):
"""Test cover default state."""
_, entity_id = wlightbox
entry = await async_setup_entity(hass, config, entity_id)
assert entry.unique_id == "BleBox-wLightBox-1afe34e750b8-color"
state = hass.states.get(entity_id)
assert state.name == "wLightBox-color"
supported_features = state.attributes[ATTR_SUPPORTED_FEATURES]
assert supported_features & SUPPORT_WHITE_VALUE
assert supported_features & SUPPORT_COLOR
assert ATTR_WHITE_VALUE not in state.attributes
assert ATTR_HS_COLOR not in state.attributes
assert ATTR_BRIGHTNESS not in state.attributes
assert state.state == STATE_OFF
device_registry = dr.async_get(hass)
device = device_registry.async_get(entry.device_id)
assert device.name == "My wLightBox"
assert device.identifiers == {("blebox", "abcd0123ef5678")}
assert device.manufacturer == "BleBox"
assert device.model == "wLightBox"
assert device.sw_version == "1.23"
async def test_wlightbox_update(wlightbox, hass, config):
"""Test light updating."""
feature_mock, entity_id = wlightbox
def initial_update():
feature_mock.is_on = True
feature_mock.rgbw_hex = "fa00203A"
feature_mock.white_value = 0x3A
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
state = hass.states.get(entity_id)
assert state.attributes[ATTR_HS_COLOR] == (352.32, 100.0)
assert state.attributes[ATTR_WHITE_VALUE] == 0x3A
assert state.state == STATE_ON
async def test_wlightbox_on_via_just_whiteness(wlightbox, hass, config):
"""Test light on."""
feature_mock, entity_id = wlightbox
def initial_update():
feature_mock.is_on = False
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
feature_mock.async_update = AsyncMock()
state = hass.states.get(entity_id)
assert state.state == STATE_OFF
def turn_on(value):
feature_mock.is_on = True
assert value == "f1e2d3c7"
feature_mock.white_value = 0xC7 # on
feature_mock.rgbw_hex = "f1e2d3c7"
feature_mock.async_on = AsyncMock(side_effect=turn_on)
def apply_white(value, white):
assert value == "f1e2d305"
assert white == 0xC7
return "f1e2d3c7"
feature_mock.apply_white = apply_white
feature_mock.sensible_on_value = "f1e2d305"
await hass.services.async_call(
"light",
SERVICE_TURN_ON,
{"entity_id": entity_id, ATTR_WHITE_VALUE: 0xC7},
blocking=True,
)
state = hass.states.get(entity_id)
assert state.state == STATE_ON
assert state.attributes[ATTR_WHITE_VALUE] == 0xC7
assert state.attributes[ATTR_HS_COLOR] == color.color_RGB_to_hs(0xF1, 0xE2, 0xD3)
async def test_wlightbox_on_via_reset_whiteness(wlightbox, hass, config):
"""Test light on."""
feature_mock, entity_id = wlightbox
def initial_update():
feature_mock.is_on = False
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
feature_mock.async_update = AsyncMock()
state = hass.states.get(entity_id)
assert state.state == STATE_OFF
def turn_on(value):
feature_mock.is_on = True
feature_mock.white_value = 0x0
assert value == "f1e2d300"
feature_mock.rgbw_hex = "f1e2d300"
feature_mock.async_on = AsyncMock(side_effect=turn_on)
def apply_white(value, white):
assert value == "f1e2d305"
assert white == 0x0
return "f1e2d300"
feature_mock.apply_white = apply_white
feature_mock.sensible_on_value = "f1e2d305"
await hass.services.async_call(
"light",
SERVICE_TURN_ON,
{"entity_id": entity_id, ATTR_WHITE_VALUE: 0x0},
blocking=True,
)
state = hass.states.get(entity_id)
assert state.state == STATE_ON
assert state.attributes[ATTR_WHITE_VALUE] == 0x0
assert state.attributes[ATTR_HS_COLOR] == color.color_RGB_to_hs(0xF1, 0xE2, 0xD3)
async def test_wlightbox_on_via_just_hsl_color(wlightbox, hass, config):
"""Test light on."""
feature_mock, entity_id = wlightbox
def initial_update():
feature_mock.is_on = False
feature_mock.rgbw_hex = "00000000"
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
feature_mock.async_update = AsyncMock()
state = hass.states.get(entity_id)
assert state.state == STATE_OFF
hs_color = color.color_RGB_to_hs(0xFF, 0xA1, 0xB2)
def turn_on(value):
feature_mock.is_on = True
assert value == "ffa1b2e4"
feature_mock.white_value = 0xE4
feature_mock.rgbw_hex = value
feature_mock.async_on = AsyncMock(side_effect=turn_on)
def apply_color(value, color_value):
assert value == "c1a2e3e4"
assert color_value == "ffa0b1"
return "ffa1b2e4"
feature_mock.apply_color = apply_color
feature_mock.sensible_on_value = "c1a2e3e4"
await hass.services.async_call(
"light",
SERVICE_TURN_ON,
{"entity_id": entity_id, ATTR_HS_COLOR: hs_color},
blocking=True,
)
state = hass.states.get(entity_id)
assert state.attributes[ATTR_HS_COLOR] == hs_color
assert state.attributes[ATTR_WHITE_VALUE] == 0xE4
assert state.state == STATE_ON
async def test_wlightbox_on_to_last_color(wlightbox, hass, config):
"""Test light on."""
feature_mock, entity_id = wlightbox
def initial_update():
feature_mock.is_on = False
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
feature_mock.async_update = AsyncMock()
state = hass.states.get(entity_id)
assert state.state == STATE_OFF
def turn_on(value):
feature_mock.is_on = True
assert value == "f1e2d3e4"
feature_mock.white_value = 0xE4
feature_mock.rgbw_hex = value
feature_mock.async_on = AsyncMock(side_effect=turn_on)
feature_mock.sensible_on_value = "f1e2d3e4"
await hass.services.async_call(
2020-08-27 11:56:20 +00:00
"light",
SERVICE_TURN_ON,
{"entity_id": entity_id},
blocking=True,
)
state = hass.states.get(entity_id)
assert state.attributes[ATTR_WHITE_VALUE] == 0xE4
assert state.attributes[ATTR_HS_COLOR] == color.color_RGB_to_hs(0xF1, 0xE2, 0xD3)
assert state.state == STATE_ON
async def test_wlightbox_off(wlightbox, hass, config):
"""Test light off."""
feature_mock, entity_id = wlightbox
def initial_update():
feature_mock.is_on = True
feature_mock.async_update = AsyncMock(side_effect=initial_update)
await async_setup_entity(hass, config, entity_id)
feature_mock.async_update = AsyncMock()
state = hass.states.get(entity_id)
assert state.state == STATE_ON
def turn_off():
feature_mock.is_on = False
feature_mock.white_value = 0x0
feature_mock.rgbw_hex = "00000000"
feature_mock.async_off = AsyncMock(side_effect=turn_off)
await hass.services.async_call(
2020-08-27 11:56:20 +00:00
"light",
SERVICE_TURN_OFF,
{"entity_id": entity_id},
blocking=True,
)
state = hass.states.get(entity_id)
assert ATTR_WHITE_VALUE not in state.attributes
assert ATTR_HS_COLOR not in state.attributes
assert state.state == STATE_OFF
@pytest.mark.parametrize("feature", ALL_LIGHT_FIXTURES, indirect=["feature"])
async def test_update_failure(feature, hass, config, caplog):
"""Test that update failures are logged."""
caplog.set_level(logging.ERROR)
feature_mock, entity_id = feature
feature_mock.async_update = AsyncMock(side_effect=blebox_uniapi.error.ClientError)
await async_setup_entity(hass, config, entity_id)
assert f"Updating '{feature_mock.full_name}' failed: " in caplog.text
@pytest.mark.parametrize("feature", ALL_LIGHT_FIXTURES, indirect=["feature"])
async def test_turn_on_failure(feature, hass, config, caplog):
"""Test that turn_on failures are logged."""
caplog.set_level(logging.ERROR)
feature_mock, entity_id = feature
feature_mock.async_on = AsyncMock(side_effect=blebox_uniapi.error.BadOnValueError)
await async_setup_entity(hass, config, entity_id)
feature_mock.sensible_on_value = 123
await hass.services.async_call(
2020-08-27 11:56:20 +00:00
"light",
SERVICE_TURN_ON,
{"entity_id": entity_id},
blocking=True,
)
assert (
f"Turning on '{feature_mock.full_name}' failed: Bad value 123 ()" in caplog.text
)