mirror of
https://github.com/home-assistant/core.git
synced 2025-07-18 18:57:06 +00:00
Use feature checks in tplink integration (#133795)
Clean up to use new upstream API: * Use Feature attributes to check for supported * Use color_temp range and update tests
This commit is contained in:
parent
26d5c55d11
commit
3cc75c3cf6
@ -200,14 +200,13 @@ class TPLinkLightEntity(CoordinatedTPLinkEntity, LightEntity):
|
|||||||
# If _attr_name is None the entity name will be the device name
|
# If _attr_name is None the entity name will be the device name
|
||||||
self._attr_name = None if parent is None else device.alias
|
self._attr_name = None if parent is None else device.alias
|
||||||
modes: set[ColorMode] = {ColorMode.ONOFF}
|
modes: set[ColorMode] = {ColorMode.ONOFF}
|
||||||
if light_module.is_variable_color_temp:
|
if color_temp_feat := light_module.get_feature("color_temp"):
|
||||||
modes.add(ColorMode.COLOR_TEMP)
|
modes.add(ColorMode.COLOR_TEMP)
|
||||||
temp_range = light_module.valid_temperature_range
|
self._attr_min_color_temp_kelvin = color_temp_feat.minimum_value
|
||||||
self._attr_min_color_temp_kelvin = temp_range.min
|
self._attr_max_color_temp_kelvin = color_temp_feat.maximum_value
|
||||||
self._attr_max_color_temp_kelvin = temp_range.max
|
if light_module.has_feature("hsv"):
|
||||||
if light_module.is_color:
|
|
||||||
modes.add(ColorMode.HS)
|
modes.add(ColorMode.HS)
|
||||||
if light_module.is_dimmable:
|
if light_module.has_feature("brightness"):
|
||||||
modes.add(ColorMode.BRIGHTNESS)
|
modes.add(ColorMode.BRIGHTNESS)
|
||||||
self._attr_supported_color_modes = filter_supported_color_modes(modes)
|
self._attr_supported_color_modes = filter_supported_color_modes(modes)
|
||||||
if len(self._attr_supported_color_modes) == 1:
|
if len(self._attr_supported_color_modes) == 1:
|
||||||
@ -270,15 +269,17 @@ class TPLinkLightEntity(CoordinatedTPLinkEntity, LightEntity):
|
|||||||
self, color_temp: float, brightness: int | None, transition: int | None
|
self, color_temp: float, brightness: int | None, transition: int | None
|
||||||
) -> None:
|
) -> None:
|
||||||
light_module = self._light_module
|
light_module = self._light_module
|
||||||
valid_temperature_range = light_module.valid_temperature_range
|
color_temp_feat = light_module.get_feature("color_temp")
|
||||||
|
assert color_temp_feat
|
||||||
|
|
||||||
requested_color_temp = round(color_temp)
|
requested_color_temp = round(color_temp)
|
||||||
# Clamp color temp to valid range
|
# Clamp color temp to valid range
|
||||||
# since if the light in a group we will
|
# since if the light in a group we will
|
||||||
# get requests for color temps for the range
|
# get requests for color temps for the range
|
||||||
# of the group and not the light
|
# of the group and not the light
|
||||||
clamped_color_temp = min(
|
clamped_color_temp = min(
|
||||||
valid_temperature_range.max,
|
color_temp_feat.maximum_value,
|
||||||
max(valid_temperature_range.min, requested_color_temp),
|
max(color_temp_feat.minimum_value, requested_color_temp),
|
||||||
)
|
)
|
||||||
await light_module.set_color_temp(
|
await light_module.set_color_temp(
|
||||||
clamped_color_temp,
|
clamped_color_temp,
|
||||||
@ -325,8 +326,11 @@ class TPLinkLightEntity(CoordinatedTPLinkEntity, LightEntity):
|
|||||||
# The light supports only a single color mode, return it
|
# The light supports only a single color mode, return it
|
||||||
return self._fixed_color_mode
|
return self._fixed_color_mode
|
||||||
|
|
||||||
# The light supports both color temp and color, determine which on is active
|
# The light supports both color temp and color, determine which one is active
|
||||||
if self._light_module.is_variable_color_temp and self._light_module.color_temp:
|
if (
|
||||||
|
self._light_module.has_feature("color_temp")
|
||||||
|
and self._light_module.color_temp
|
||||||
|
):
|
||||||
return ColorMode.COLOR_TEMP
|
return ColorMode.COLOR_TEMP
|
||||||
return ColorMode.HS
|
return ColorMode.HS
|
||||||
|
|
||||||
@ -335,7 +339,7 @@ class TPLinkLightEntity(CoordinatedTPLinkEntity, LightEntity):
|
|||||||
"""Update the entity's attributes."""
|
"""Update the entity's attributes."""
|
||||||
light_module = self._light_module
|
light_module = self._light_module
|
||||||
self._attr_is_on = light_module.state.light_on is True
|
self._attr_is_on = light_module.state.light_on is True
|
||||||
if light_module.is_dimmable:
|
if light_module.has_feature("brightness"):
|
||||||
self._attr_brightness = round((light_module.brightness * 255.0) / 100.0)
|
self._attr_brightness = round((light_module.brightness * 255.0) / 100.0)
|
||||||
color_mode = self._determine_color_mode()
|
color_mode = self._determine_color_mode()
|
||||||
self._attr_color_mode = color_mode
|
self._attr_color_mode = color_mode
|
||||||
|
@ -257,20 +257,27 @@ def _mocked_device(
|
|||||||
for module_name in modules
|
for module_name in modules
|
||||||
}
|
}
|
||||||
|
|
||||||
|
device_features = {}
|
||||||
if features:
|
if features:
|
||||||
device.features = {
|
device_features = {
|
||||||
feature_id: _mocked_feature(feature_id, require_fixture=True)
|
feature_id: _mocked_feature(feature_id, require_fixture=True)
|
||||||
for feature_id in features
|
for feature_id in features
|
||||||
if isinstance(feature_id, str)
|
if isinstance(feature_id, str)
|
||||||
}
|
}
|
||||||
|
|
||||||
device.features.update(
|
device_features.update(
|
||||||
{
|
{
|
||||||
feature.id: feature
|
feature.id: feature
|
||||||
for feature in features
|
for feature in features
|
||||||
if isinstance(feature, Feature)
|
if isinstance(feature, Feature)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
device.features = device_features
|
||||||
|
|
||||||
|
for mod in device.modules.values():
|
||||||
|
mod.get_feature.side_effect = device_features.get
|
||||||
|
mod.has_feature.side_effect = lambda id: id in device_features
|
||||||
|
|
||||||
device.children = []
|
device.children = []
|
||||||
if children:
|
if children:
|
||||||
for child in children:
|
for child in children:
|
||||||
@ -289,6 +296,7 @@ def _mocked_device(
|
|||||||
device.protocol = _mock_protocol()
|
device.protocol = _mock_protocol()
|
||||||
device.config = device_config
|
device.config = device_config
|
||||||
device.credentials_hash = credentials_hash
|
device.credentials_hash = credentials_hash
|
||||||
|
|
||||||
return device
|
return device
|
||||||
|
|
||||||
|
|
||||||
@ -303,8 +311,8 @@ def _mocked_feature(
|
|||||||
precision_hint=None,
|
precision_hint=None,
|
||||||
choices=None,
|
choices=None,
|
||||||
unit=None,
|
unit=None,
|
||||||
minimum_value=0,
|
minimum_value=None,
|
||||||
maximum_value=2**16, # Arbitrary max
|
maximum_value=None,
|
||||||
) -> Feature:
|
) -> Feature:
|
||||||
"""Get a mocked feature.
|
"""Get a mocked feature.
|
||||||
|
|
||||||
@ -334,11 +342,14 @@ def _mocked_feature(
|
|||||||
feature.unit = unit or fixture.get("unit")
|
feature.unit = unit or fixture.get("unit")
|
||||||
|
|
||||||
# number
|
# number
|
||||||
feature.minimum_value = minimum_value or fixture.get("minimum_value")
|
min_val = minimum_value or fixture.get("minimum_value")
|
||||||
feature.maximum_value = maximum_value or fixture.get("maximum_value")
|
feature.minimum_value = 0 if min_val is None else min_val
|
||||||
|
max_val = maximum_value or fixture.get("maximum_value")
|
||||||
|
feature.maximum_value = 2**16 if max_val is None else max_val
|
||||||
|
|
||||||
# select
|
# select
|
||||||
feature.choices = choices or fixture.get("choices")
|
feature.choices = choices or fixture.get("choices")
|
||||||
|
|
||||||
return feature
|
return feature
|
||||||
|
|
||||||
|
|
||||||
@ -350,13 +361,7 @@ def _mocked_light_module(device) -> Light:
|
|||||||
light.state = LightState(
|
light.state = LightState(
|
||||||
light_on=True, brightness=light.brightness, color_temp=light.color_temp
|
light_on=True, brightness=light.brightness, color_temp=light.color_temp
|
||||||
)
|
)
|
||||||
light.is_color = True
|
|
||||||
light.is_variable_color_temp = True
|
|
||||||
light.is_dimmable = True
|
|
||||||
light.is_brightness = True
|
|
||||||
light.has_effects = False
|
|
||||||
light.hsv = (10, 30, 5)
|
light.hsv = (10, 30, 5)
|
||||||
light.valid_temperature_range = ColorTempRange(min=4000, max=9000)
|
|
||||||
light.hw_info = {"sw_ver": "1.0.0", "hw_ver": "1.0.0"}
|
light.hw_info = {"sw_ver": "1.0.0", "hw_ver": "1.0.0"}
|
||||||
|
|
||||||
async def _set_state(state, *_, **__):
|
async def _set_state(state, *_, **__):
|
||||||
@ -389,7 +394,6 @@ def _mocked_light_module(device) -> Light:
|
|||||||
|
|
||||||
def _mocked_light_effect_module(device) -> LightEffect:
|
def _mocked_light_effect_module(device) -> LightEffect:
|
||||||
effect = MagicMock(spec=LightEffect, name="Mocked light effect")
|
effect = MagicMock(spec=LightEffect, name="Mocked light effect")
|
||||||
effect.has_effects = True
|
|
||||||
effect.has_custom_effects = True
|
effect.has_custom_effects = True
|
||||||
effect.effect = "Effect1"
|
effect.effect = "Effect1"
|
||||||
effect.effect_list = ["Off", "Effect1", "Effect2"]
|
effect.effect_list = ["Off", "Effect1", "Effect2"]
|
||||||
|
@ -267,7 +267,9 @@
|
|||||||
"target_temperature": {
|
"target_temperature": {
|
||||||
"value": false,
|
"value": false,
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"category": "Primary"
|
"category": "Primary",
|
||||||
|
"minimum_value": 5,
|
||||||
|
"maximum_value": 30
|
||||||
},
|
},
|
||||||
"fan_speed_level": {
|
"fan_speed_level": {
|
||||||
"value": 2,
|
"value": 2,
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
<HVACMode.HEAT: 'heat'>,
|
<HVACMode.HEAT: 'heat'>,
|
||||||
<HVACMode.OFF: 'off'>,
|
<HVACMode.OFF: 'off'>,
|
||||||
]),
|
]),
|
||||||
'max_temp': 65536,
|
'max_temp': 30,
|
||||||
'min_temp': None,
|
'min_temp': 5,
|
||||||
}),
|
}),
|
||||||
'config_entry_id': <ANY>,
|
'config_entry_id': <ANY>,
|
||||||
'device_class': None,
|
'device_class': None,
|
||||||
@ -49,8 +49,8 @@
|
|||||||
<HVACMode.HEAT: 'heat'>,
|
<HVACMode.HEAT: 'heat'>,
|
||||||
<HVACMode.OFF: 'off'>,
|
<HVACMode.OFF: 'off'>,
|
||||||
]),
|
]),
|
||||||
'max_temp': 65536,
|
'max_temp': 30,
|
||||||
'min_temp': None,
|
'min_temp': 5,
|
||||||
'supported_features': <ClimateEntityFeature: 385>,
|
'supported_features': <ClimateEntityFeature: 385>,
|
||||||
'temperature': 22.2,
|
'temperature': 22.2,
|
||||||
}),
|
}),
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
}),
|
}),
|
||||||
'area_id': None,
|
'area_id': None,
|
||||||
'capabilities': dict({
|
'capabilities': dict({
|
||||||
'max': 65536,
|
'max': 60,
|
||||||
'min': 0,
|
'min': 0,
|
||||||
'mode': <NumberMode.BOX: 'box'>,
|
'mode': <NumberMode.BOX: 'box'>,
|
||||||
'step': 1.0,
|
'step': 1.0,
|
||||||
@ -77,7 +77,7 @@
|
|||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'friendly_name': 'my_device Smooth off',
|
'friendly_name': 'my_device Smooth off',
|
||||||
'max': 65536,
|
'max': 60,
|
||||||
'min': 0,
|
'min': 0,
|
||||||
'mode': <NumberMode.BOX: 'box'>,
|
'mode': <NumberMode.BOX: 'box'>,
|
||||||
'step': 1.0,
|
'step': 1.0,
|
||||||
@ -96,7 +96,7 @@
|
|||||||
}),
|
}),
|
||||||
'area_id': None,
|
'area_id': None,
|
||||||
'capabilities': dict({
|
'capabilities': dict({
|
||||||
'max': 65536,
|
'max': 60,
|
||||||
'min': 0,
|
'min': 0,
|
||||||
'mode': <NumberMode.BOX: 'box'>,
|
'mode': <NumberMode.BOX: 'box'>,
|
||||||
'step': 1.0,
|
'step': 1.0,
|
||||||
@ -132,7 +132,7 @@
|
|||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'friendly_name': 'my_device Smooth on',
|
'friendly_name': 'my_device Smooth on',
|
||||||
'max': 65536,
|
'max': 60,
|
||||||
'min': 0,
|
'min': 0,
|
||||||
'mode': <NumberMode.BOX: 'box'>,
|
'mode': <NumberMode.BOX: 'box'>,
|
||||||
'step': 1.0,
|
'step': 1.0,
|
||||||
@ -151,7 +151,7 @@
|
|||||||
}),
|
}),
|
||||||
'area_id': None,
|
'area_id': None,
|
||||||
'capabilities': dict({
|
'capabilities': dict({
|
||||||
'max': 65536,
|
'max': 10,
|
||||||
'min': -10,
|
'min': -10,
|
||||||
'mode': <NumberMode.BOX: 'box'>,
|
'mode': <NumberMode.BOX: 'box'>,
|
||||||
'step': 1.0,
|
'step': 1.0,
|
||||||
@ -187,7 +187,7 @@
|
|||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'friendly_name': 'my_device Temperature offset',
|
'friendly_name': 'my_device Temperature offset',
|
||||||
'max': 65536,
|
'max': 10,
|
||||||
'min': -10,
|
'min': -10,
|
||||||
'mode': <NumberMode.BOX: 'box'>,
|
'mode': <NumberMode.BOX: 'box'>,
|
||||||
'step': 1.0,
|
'step': 1.0,
|
||||||
@ -206,7 +206,7 @@
|
|||||||
}),
|
}),
|
||||||
'area_id': None,
|
'area_id': None,
|
||||||
'capabilities': dict({
|
'capabilities': dict({
|
||||||
'max': 65536,
|
'max': 60,
|
||||||
'min': 0,
|
'min': 0,
|
||||||
'mode': <NumberMode.BOX: 'box'>,
|
'mode': <NumberMode.BOX: 'box'>,
|
||||||
'step': 1.0,
|
'step': 1.0,
|
||||||
@ -242,7 +242,7 @@
|
|||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'friendly_name': 'my_device Turn off in',
|
'friendly_name': 'my_device Turn off in',
|
||||||
'max': 65536,
|
'max': 60,
|
||||||
'min': 0,
|
'min': 0,
|
||||||
'mode': <NumberMode.BOX: 'box'>,
|
'mode': <NumberMode.BOX: 'box'>,
|
||||||
'step': 1.0,
|
'step': 1.0,
|
||||||
|
@ -54,6 +54,7 @@ from . import (
|
|||||||
MAC_ADDRESS,
|
MAC_ADDRESS,
|
||||||
MODEL,
|
MODEL,
|
||||||
_mocked_device,
|
_mocked_device,
|
||||||
|
_mocked_feature,
|
||||||
_patch_connect,
|
_patch_connect,
|
||||||
_patch_discovery,
|
_patch_discovery,
|
||||||
_patch_single_discovery,
|
_patch_single_discovery,
|
||||||
@ -335,7 +336,14 @@ async def test_update_attrs_fails_in_init(
|
|||||||
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
|
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
|
||||||
)
|
)
|
||||||
config_entry.add_to_hass(hass)
|
config_entry.add_to_hass(hass)
|
||||||
light = _mocked_device(modules=[Module.Light], alias="my_light")
|
features = [
|
||||||
|
_mocked_feature("brightness", value=50),
|
||||||
|
_mocked_feature("hsv", value=(10, 30, 5)),
|
||||||
|
_mocked_feature(
|
||||||
|
"color_temp", value=4000, minimum_value=4000, maximum_value=9000
|
||||||
|
),
|
||||||
|
]
|
||||||
|
light = _mocked_device(modules=[Module.Light], alias="my_light", features=features)
|
||||||
light_module = light.modules[Module.Light]
|
light_module = light.modules[Module.Light]
|
||||||
p = PropertyMock(side_effect=KasaException)
|
p = PropertyMock(side_effect=KasaException)
|
||||||
type(light_module).color_temp = p
|
type(light_module).color_temp = p
|
||||||
@ -363,7 +371,14 @@ async def test_update_attrs_fails_on_update(
|
|||||||
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
|
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
|
||||||
)
|
)
|
||||||
config_entry.add_to_hass(hass)
|
config_entry.add_to_hass(hass)
|
||||||
light = _mocked_device(modules=[Module.Light], alias="my_light")
|
features = [
|
||||||
|
_mocked_feature("brightness", value=50),
|
||||||
|
_mocked_feature("hsv", value=(10, 30, 5)),
|
||||||
|
_mocked_feature(
|
||||||
|
"color_temp", value=4000, minimum_value=4000, maximum_value=9000
|
||||||
|
),
|
||||||
|
]
|
||||||
|
light = _mocked_device(modules=[Module.Light], alias="my_light", features=features)
|
||||||
light_module = light.modules[Module.Light]
|
light_module = light.modules[Module.Light]
|
||||||
|
|
||||||
with _patch_discovery(device=light), _patch_connect(device=light):
|
with _patch_discovery(device=light), _patch_connect(device=light):
|
||||||
|
@ -54,6 +54,7 @@ from . import (
|
|||||||
DEVICE_ID,
|
DEVICE_ID,
|
||||||
MAC_ADDRESS,
|
MAC_ADDRESS,
|
||||||
_mocked_device,
|
_mocked_device,
|
||||||
|
_mocked_feature,
|
||||||
_patch_connect,
|
_patch_connect,
|
||||||
_patch_discovery,
|
_patch_discovery,
|
||||||
_patch_single_discovery,
|
_patch_single_discovery,
|
||||||
@ -118,8 +119,32 @@ async def test_legacy_dimmer_unique_id(hass: HomeAssistant) -> None:
|
|||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("device", "transition"),
|
("device", "transition"),
|
||||||
[
|
[
|
||||||
(_mocked_device(modules=[Module.Light]), 2.0),
|
(
|
||||||
(_mocked_device(modules=[Module.Light, Module.LightEffect]), None),
|
_mocked_device(
|
||||||
|
modules=[Module.Light],
|
||||||
|
features=[
|
||||||
|
_mocked_feature("brightness", value=50),
|
||||||
|
_mocked_feature("hsv", value=(10, 30, 5)),
|
||||||
|
_mocked_feature(
|
||||||
|
"color_temp", value=4000, minimum_value=4000, maximum_value=9000
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
2.0,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
_mocked_device(
|
||||||
|
modules=[Module.Light, Module.LightEffect],
|
||||||
|
features=[
|
||||||
|
_mocked_feature("brightness", value=50),
|
||||||
|
_mocked_feature("hsv", value=(10, 30, 5)),
|
||||||
|
_mocked_feature(
|
||||||
|
"color_temp", value=4000, minimum_value=4000, maximum_value=9000
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_color_light(
|
async def test_color_light(
|
||||||
@ -131,7 +156,10 @@ async def test_color_light(
|
|||||||
)
|
)
|
||||||
already_migrated_config_entry.add_to_hass(hass)
|
already_migrated_config_entry.add_to_hass(hass)
|
||||||
light = device.modules[Module.Light]
|
light = device.modules[Module.Light]
|
||||||
|
|
||||||
|
# Setting color_temp to None emulates a device with active effects
|
||||||
light.color_temp = None
|
light.color_temp = None
|
||||||
|
|
||||||
with _patch_discovery(device=device), _patch_connect(device=device):
|
with _patch_discovery(device=device), _patch_connect(device=device):
|
||||||
await async_setup_component(hass, tplink.DOMAIN, {tplink.DOMAIN: {}})
|
await async_setup_component(hass, tplink.DOMAIN, {tplink.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
@ -220,9 +248,14 @@ async def test_color_light_no_temp(hass: HomeAssistant) -> None:
|
|||||||
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
|
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
|
||||||
)
|
)
|
||||||
already_migrated_config_entry.add_to_hass(hass)
|
already_migrated_config_entry.add_to_hass(hass)
|
||||||
device = _mocked_device(modules=[Module.Light], alias="my_light")
|
features = [
|
||||||
|
_mocked_feature("brightness", value=50),
|
||||||
|
_mocked_feature("hsv", value=(10, 30, 5)),
|
||||||
|
]
|
||||||
|
|
||||||
|
device = _mocked_device(modules=[Module.Light], alias="my_light", features=features)
|
||||||
light = device.modules[Module.Light]
|
light = device.modules[Module.Light]
|
||||||
light.is_variable_color_temp = False
|
|
||||||
type(light).color_temp = PropertyMock(side_effect=Exception)
|
type(light).color_temp = PropertyMock(side_effect=Exception)
|
||||||
with _patch_discovery(device=device), _patch_connect(device=device):
|
with _patch_discovery(device=device), _patch_connect(device=device):
|
||||||
await async_setup_component(hass, tplink.DOMAIN, {tplink.DOMAIN: {}})
|
await async_setup_component(hass, tplink.DOMAIN, {tplink.DOMAIN: {}})
|
||||||
@ -272,25 +305,47 @@ async def test_color_light_no_temp(hass: HomeAssistant) -> None:
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("bulb", "is_color"),
|
("device", "is_color"),
|
||||||
[
|
[
|
||||||
(_mocked_device(modules=[Module.Light], alias="my_light"), True),
|
(
|
||||||
(_mocked_device(modules=[Module.Light], alias="my_light"), False),
|
_mocked_device(
|
||||||
|
modules=[Module.Light],
|
||||||
|
alias="my_light",
|
||||||
|
features=[
|
||||||
|
_mocked_feature("brightness", value=50),
|
||||||
|
_mocked_feature("hsv", value=(10, 30, 5)),
|
||||||
|
_mocked_feature(
|
||||||
|
"color_temp", value=4000, minimum_value=4000, maximum_value=9000
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
True,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
_mocked_device(
|
||||||
|
modules=[Module.Light],
|
||||||
|
alias="my_light",
|
||||||
|
features=[
|
||||||
|
_mocked_feature("brightness", value=50),
|
||||||
|
_mocked_feature(
|
||||||
|
"color_temp", value=4000, minimum_value=4000, maximum_value=9000
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
False,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_color_temp_light(
|
async def test_color_temp_light(
|
||||||
hass: HomeAssistant, bulb: MagicMock, is_color: bool
|
hass: HomeAssistant, device: MagicMock, is_color: bool
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test a light."""
|
"""Test a light."""
|
||||||
already_migrated_config_entry = MockConfigEntry(
|
already_migrated_config_entry = MockConfigEntry(
|
||||||
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
|
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
|
||||||
)
|
)
|
||||||
already_migrated_config_entry.add_to_hass(hass)
|
already_migrated_config_entry.add_to_hass(hass)
|
||||||
device = _mocked_device(modules=[Module.Light], alias="my_light")
|
# device = _mocked_device(modules=[Module.Light], alias="my_light")
|
||||||
light = device.modules[Module.Light]
|
light = device.modules[Module.Light]
|
||||||
light.is_color = is_color
|
|
||||||
light.color_temp = 4000
|
|
||||||
light.is_variable_color_temp = True
|
|
||||||
|
|
||||||
with _patch_discovery(device=device), _patch_connect(device=device):
|
with _patch_discovery(device=device), _patch_connect(device=device):
|
||||||
await async_setup_component(hass, tplink.DOMAIN, {tplink.DOMAIN: {}})
|
await async_setup_component(hass, tplink.DOMAIN, {tplink.DOMAIN: {}})
|
||||||
@ -303,7 +358,7 @@ async def test_color_temp_light(
|
|||||||
attributes = state.attributes
|
attributes = state.attributes
|
||||||
assert attributes[ATTR_BRIGHTNESS] == 128
|
assert attributes[ATTR_BRIGHTNESS] == 128
|
||||||
assert attributes[ATTR_COLOR_MODE] == "color_temp"
|
assert attributes[ATTR_COLOR_MODE] == "color_temp"
|
||||||
if light.is_color:
|
if is_color:
|
||||||
assert attributes[ATTR_SUPPORTED_COLOR_MODES] == ["color_temp", "hs"]
|
assert attributes[ATTR_SUPPORTED_COLOR_MODES] == ["color_temp", "hs"]
|
||||||
else:
|
else:
|
||||||
assert attributes[ATTR_SUPPORTED_COLOR_MODES] == ["color_temp"]
|
assert attributes[ATTR_SUPPORTED_COLOR_MODES] == ["color_temp"]
|
||||||
@ -368,10 +423,11 @@ async def test_brightness_only_light(hass: HomeAssistant) -> None:
|
|||||||
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
|
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
|
||||||
)
|
)
|
||||||
already_migrated_config_entry.add_to_hass(hass)
|
already_migrated_config_entry.add_to_hass(hass)
|
||||||
device = _mocked_device(modules=[Module.Light], alias="my_light")
|
features = [
|
||||||
|
_mocked_feature("brightness", value=50),
|
||||||
|
]
|
||||||
|
device = _mocked_device(modules=[Module.Light], alias="my_light", features=features)
|
||||||
light = device.modules[Module.Light]
|
light = device.modules[Module.Light]
|
||||||
light.is_color = False
|
|
||||||
light.is_variable_color_temp = False
|
|
||||||
|
|
||||||
with _patch_discovery(device=device), _patch_connect(device=device):
|
with _patch_discovery(device=device), _patch_connect(device=device):
|
||||||
await async_setup_component(hass, tplink.DOMAIN, {tplink.DOMAIN: {}})
|
await async_setup_component(hass, tplink.DOMAIN, {tplink.DOMAIN: {}})
|
||||||
@ -414,11 +470,8 @@ async def test_on_off_light(hass: HomeAssistant) -> None:
|
|||||||
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
|
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
|
||||||
)
|
)
|
||||||
already_migrated_config_entry.add_to_hass(hass)
|
already_migrated_config_entry.add_to_hass(hass)
|
||||||
device = _mocked_device(modules=[Module.Light], alias="my_light")
|
device = _mocked_device(modules=[Module.Light], alias="my_light", features=[])
|
||||||
light = device.modules[Module.Light]
|
light = device.modules[Module.Light]
|
||||||
light.is_color = False
|
|
||||||
light.is_variable_color_temp = False
|
|
||||||
light.is_dimmable = False
|
|
||||||
|
|
||||||
with _patch_discovery(device=device), _patch_connect(device=device):
|
with _patch_discovery(device=device), _patch_connect(device=device):
|
||||||
await async_setup_component(hass, tplink.DOMAIN, {tplink.DOMAIN: {}})
|
await async_setup_component(hass, tplink.DOMAIN, {tplink.DOMAIN: {}})
|
||||||
@ -450,11 +503,9 @@ async def test_off_at_start_light(hass: HomeAssistant) -> None:
|
|||||||
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
|
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
|
||||||
)
|
)
|
||||||
already_migrated_config_entry.add_to_hass(hass)
|
already_migrated_config_entry.add_to_hass(hass)
|
||||||
device = _mocked_device(modules=[Module.Light], alias="my_light")
|
device = _mocked_device(modules=[Module.Light], alias="my_light", features=[])
|
||||||
light = device.modules[Module.Light]
|
light = device.modules[Module.Light]
|
||||||
light.is_color = False
|
|
||||||
light.is_variable_color_temp = False
|
|
||||||
light.is_dimmable = False
|
|
||||||
light.state = LightState(light_on=False)
|
light.state = LightState(light_on=False)
|
||||||
|
|
||||||
with _patch_discovery(device=device), _patch_connect(device=device):
|
with _patch_discovery(device=device), _patch_connect(device=device):
|
||||||
@ -513,8 +564,15 @@ async def test_smart_strip_effects(
|
|||||||
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
|
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
|
||||||
)
|
)
|
||||||
already_migrated_config_entry.add_to_hass(hass)
|
already_migrated_config_entry.add_to_hass(hass)
|
||||||
|
features = [
|
||||||
|
_mocked_feature("brightness", value=50),
|
||||||
|
_mocked_feature("hsv", value=(10, 30, 5)),
|
||||||
|
_mocked_feature(
|
||||||
|
"color_temp", value=4000, minimum_value=4000, maximum_value=9000
|
||||||
|
),
|
||||||
|
]
|
||||||
device = _mocked_device(
|
device = _mocked_device(
|
||||||
modules=[Module.Light, Module.LightEffect], alias="my_light"
|
modules=[Module.Light, Module.LightEffect], alias="my_light", features=features
|
||||||
)
|
)
|
||||||
light = device.modules[Module.Light]
|
light = device.modules[Module.Light]
|
||||||
light_effect = device.modules[Module.LightEffect]
|
light_effect = device.modules[Module.LightEffect]
|
||||||
@ -977,8 +1035,15 @@ async def test_scene_effect_light(
|
|||||||
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
|
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
|
||||||
)
|
)
|
||||||
already_migrated_config_entry.add_to_hass(hass)
|
already_migrated_config_entry.add_to_hass(hass)
|
||||||
|
features = [
|
||||||
|
_mocked_feature("brightness", value=50),
|
||||||
|
_mocked_feature("hsv", value=(10, 30, 5)),
|
||||||
|
_mocked_feature(
|
||||||
|
"color_temp", value=4000, minimum_value=4000, maximum_value=9000
|
||||||
|
),
|
||||||
|
]
|
||||||
device = _mocked_device(
|
device = _mocked_device(
|
||||||
modules=[Module.Light, Module.LightEffect], alias="my_light"
|
modules=[Module.Light, Module.LightEffect], alias="my_light", features=features
|
||||||
)
|
)
|
||||||
light_effect = device.modules[Module.LightEffect]
|
light_effect = device.modules[Module.LightEffect]
|
||||||
light_effect.effect = LightEffect.LIGHT_EFFECTS_OFF
|
light_effect.effect = LightEffect.LIGHT_EFFECTS_OFF
|
||||||
|
@ -129,7 +129,7 @@ async def test_color_light_no_emeter(hass: HomeAssistant) -> None:
|
|||||||
)
|
)
|
||||||
already_migrated_config_entry.add_to_hass(hass)
|
already_migrated_config_entry.add_to_hass(hass)
|
||||||
bulb = _mocked_device(alias="my_bulb", modules=[Module.Light])
|
bulb = _mocked_device(alias="my_bulb", modules=[Module.Light])
|
||||||
bulb.has_emeter = False
|
|
||||||
with _patch_discovery(device=bulb), _patch_connect(device=bulb):
|
with _patch_discovery(device=bulb), _patch_connect(device=bulb):
|
||||||
await async_setup_component(hass, tplink.DOMAIN, {tplink.DOMAIN: {}})
|
await async_setup_component(hass, tplink.DOMAIN, {tplink.DOMAIN: {}})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user