Skip to content

Commit 0d6a5d9

Browse files
committed
Use color_temp range and update tests
1 parent 886757e commit 0d6a5d9

File tree

8 files changed

+149
-62
lines changed

8 files changed

+149
-62
lines changed

homeassistant/components/tplink/light.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -200,11 +200,10 @@ def __init__(
200200
# If _attr_name is None the entity name will be the device name
201201
self._attr_name = None if parent is None else device.alias
202202
modes: set[ColorMode] = {ColorMode.ONOFF}
203-
if light_module.has_feature("color_temp"):
203+
if color_temp_feat := light_module.get_feature("color_temp"):
204204
modes.add(ColorMode.COLOR_TEMP)
205-
temp_range = light_module.valid_temperature_range
206-
self._attr_min_color_temp_kelvin = temp_range.min
207-
self._attr_max_color_temp_kelvin = temp_range.max
205+
self._attr_min_color_temp_kelvin = color_temp_feat.minimum_value
206+
self._attr_max_color_temp_kelvin = color_temp_feat.maximum_value
208207
if light_module.has_feature("hsv"):
209208
modes.add(ColorMode.HS)
210209
if light_module.has_feature("brightness"):
@@ -270,15 +269,17 @@ async def _async_set_color_temp(
270269
self, color_temp: float, brightness: int | None, transition: int | None
271270
) -> None:
272271
light_module = self._light_module
273-
valid_temperature_range = light_module.valid_temperature_range
272+
color_temp_feat = light_module.get_feature("color_temp")
273+
assert color_temp_feat
274+
274275
requested_color_temp = round(color_temp)
275276
# Clamp color temp to valid range
276277
# since if the light in a group we will
277278
# get requests for color temps for the range
278279
# of the group and not the light
279280
clamped_color_temp = min(
280-
valid_temperature_range.max,
281-
max(valid_temperature_range.min, requested_color_temp),
281+
color_temp_feat.maximum_value,
282+
max(color_temp_feat.minimum_value, requested_color_temp),
282283
)
283284
await light_module.set_color_temp(
284285
clamped_color_temp,

tests/components/tplink/__init__.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -257,20 +257,27 @@ def _mocked_device(
257257
for module_name in modules
258258
}
259259

260+
device_features = {}
260261
if features:
261-
device.features = {
262+
device_features = {
262263
feature_id: _mocked_feature(feature_id, require_fixture=True)
263264
for feature_id in features
264265
if isinstance(feature_id, str)
265266
}
266267

267-
device.features.update(
268+
device_features.update(
268269
{
269270
feature.id: feature
270271
for feature in features
271272
if isinstance(feature, Feature)
272273
}
273274
)
275+
device.features = device_features
276+
277+
for mod in device.modules.values():
278+
mod.get_feature.side_effect = device_features.get
279+
mod.has_feature.side_effect = lambda id: id in device_features
280+
274281
device.children = []
275282
if children:
276283
for child in children:
@@ -289,6 +296,7 @@ def _mocked_device(
289296
device.protocol = _mock_protocol()
290297
device.config = device_config
291298
device.credentials_hash = credentials_hash
299+
292300
return device
293301

294302

@@ -303,8 +311,8 @@ def _mocked_feature(
303311
precision_hint=None,
304312
choices=None,
305313
unit=None,
306-
minimum_value=0,
307-
maximum_value=2**16, # Arbitrary max
314+
minimum_value=None,
315+
maximum_value=None,
308316
) -> Feature:
309317
"""Get a mocked feature.
310318
@@ -334,11 +342,14 @@ def _mocked_feature(
334342
feature.unit = unit or fixture.get("unit")
335343

336344
# number
337-
feature.minimum_value = minimum_value or fixture.get("minimum_value")
338-
feature.maximum_value = maximum_value or fixture.get("maximum_value")
345+
min_val = minimum_value or fixture.get("minimum_value")
346+
feature.minimum_value = 0 if min_val is None else min_val
347+
max_val = maximum_value or fixture.get("maximum_value")
348+
feature.maximum_value = 2**16 if max_val is None else max_val
339349

340350
# select
341351
feature.choices = choices or fixture.get("choices")
352+
342353
return feature
343354

344355

@@ -350,13 +361,7 @@ def _mocked_light_module(device) -> Light:
350361
light.state = LightState(
351362
light_on=True, brightness=light.brightness, color_temp=light.color_temp
352363
)
353-
light.is_color = True
354-
light.is_variable_color_temp = True
355-
light.is_dimmable = True
356-
light.is_brightness = True
357-
light.has_effects = False
358364
light.hsv = (10, 30, 5)
359-
light.valid_temperature_range = ColorTempRange(min=4000, max=9000)
360365
light.hw_info = {"sw_ver": "1.0.0", "hw_ver": "1.0.0"}
361366

362367
async def _set_state(state, *_, **__):
@@ -389,7 +394,6 @@ async def _set_color_temp(temp, *_, **__):
389394

390395
def _mocked_light_effect_module(device) -> LightEffect:
391396
effect = MagicMock(spec=LightEffect, name="Mocked light effect")
392-
effect.has_effects = True
393397
effect.has_custom_effects = True
394398
effect.effect = "Effect1"
395399
effect.effect_list = ["Off", "Effect1", "Effect2"]

tests/components/tplink/fixtures/features.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,9 @@
267267
"target_temperature": {
268268
"value": false,
269269
"type": "Number",
270-
"category": "Primary"
270+
"category": "Primary",
271+
"minimum_value": 5,
272+
"maximum_value": 30
271273
},
272274
"fan_speed_level": {
273275
"value": 2,

tests/components/tplink/snapshots/test_climate.ambr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
<HVACMode.HEAT: 'heat'>,
1010
<HVACMode.OFF: 'off'>,
1111
]),
12-
'max_temp': 65536,
13-
'min_temp': None,
12+
'max_temp': 30,
13+
'min_temp': 5,
1414
}),
1515
'config_entry_id': <ANY>,
1616
'device_class': None,
@@ -49,8 +49,8 @@
4949
<HVACMode.HEAT: 'heat'>,
5050
<HVACMode.OFF: 'off'>,
5151
]),
52-
'max_temp': 65536,
53-
'min_temp': None,
52+
'max_temp': 30,
53+
'min_temp': 5,
5454
'supported_features': <ClimateEntityFeature: 385>,
5555
'temperature': 22.2,
5656
}),

tests/components/tplink/snapshots/test_number.ambr

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
}),
4242
'area_id': None,
4343
'capabilities': dict({
44-
'max': 65536,
44+
'max': 60,
4545
'min': 0,
4646
'mode': <NumberMode.BOX: 'box'>,
4747
'step': 1.0,
@@ -77,7 +77,7 @@
7777
StateSnapshot({
7878
'attributes': ReadOnlyDict({
7979
'friendly_name': 'my_device Smooth off',
80-
'max': 65536,
80+
'max': 60,
8181
'min': 0,
8282
'mode': <NumberMode.BOX: 'box'>,
8383
'step': 1.0,
@@ -96,7 +96,7 @@
9696
}),
9797
'area_id': None,
9898
'capabilities': dict({
99-
'max': 65536,
99+
'max': 60,
100100
'min': 0,
101101
'mode': <NumberMode.BOX: 'box'>,
102102
'step': 1.0,
@@ -132,7 +132,7 @@
132132
StateSnapshot({
133133
'attributes': ReadOnlyDict({
134134
'friendly_name': 'my_device Smooth on',
135-
'max': 65536,
135+
'max': 60,
136136
'min': 0,
137137
'mode': <NumberMode.BOX: 'box'>,
138138
'step': 1.0,
@@ -151,7 +151,7 @@
151151
}),
152152
'area_id': None,
153153
'capabilities': dict({
154-
'max': 65536,
154+
'max': 10,
155155
'min': -10,
156156
'mode': <NumberMode.BOX: 'box'>,
157157
'step': 1.0,
@@ -187,7 +187,7 @@
187187
StateSnapshot({
188188
'attributes': ReadOnlyDict({
189189
'friendly_name': 'my_device Temperature offset',
190-
'max': 65536,
190+
'max': 10,
191191
'min': -10,
192192
'mode': <NumberMode.BOX: 'box'>,
193193
'step': 1.0,
@@ -206,7 +206,7 @@
206206
}),
207207
'area_id': None,
208208
'capabilities': dict({
209-
'max': 65536,
209+
'max': 60,
210210
'min': 0,
211211
'mode': <NumberMode.BOX: 'box'>,
212212
'step': 1.0,
@@ -242,7 +242,7 @@
242242
StateSnapshot({
243243
'attributes': ReadOnlyDict({
244244
'friendly_name': 'my_device Turn off in',
245-
'max': 65536,
245+
'max': 60,
246246
'min': 0,
247247
'mode': <NumberMode.BOX: 'box'>,
248248
'step': 1.0,

tests/components/tplink/test_init.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
MAC_ADDRESS,
5555
MODEL,
5656
_mocked_device,
57+
_mocked_feature,
5758
_patch_connect,
5859
_patch_discovery,
5960
_patch_single_discovery,
@@ -335,7 +336,14 @@ async def test_update_attrs_fails_in_init(
335336
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
336337
)
337338
config_entry.add_to_hass(hass)
338-
light = _mocked_device(modules=[Module.Light], alias="my_light")
339+
features = [
340+
_mocked_feature("brightness", value=50),
341+
_mocked_feature("hsv", value=(10, 30, 5)),
342+
_mocked_feature(
343+
"color_temp", value=4000, minimum_value=4000, maximum_value=9000
344+
),
345+
]
346+
light = _mocked_device(modules=[Module.Light], alias="my_light", features=features)
339347
light_module = light.modules[Module.Light]
340348
p = PropertyMock(side_effect=KasaException)
341349
type(light_module).color_temp = p
@@ -363,7 +371,14 @@ async def test_update_attrs_fails_on_update(
363371
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
364372
)
365373
config_entry.add_to_hass(hass)
366-
light = _mocked_device(modules=[Module.Light], alias="my_light")
374+
features = [
375+
_mocked_feature("brightness", value=50),
376+
_mocked_feature("hsv", value=(10, 30, 5)),
377+
_mocked_feature(
378+
"color_temp", value=4000, minimum_value=4000, maximum_value=9000
379+
),
380+
]
381+
light = _mocked_device(modules=[Module.Light], alias="my_light", features=features)
367382
light_module = light.modules[Module.Light]
368383

369384
with _patch_discovery(device=light), _patch_connect(device=light):

0 commit comments

Comments
 (0)