Skip to content

Commit 1b0ccf1

Browse files
bdracoballoob
authored andcommitted
Fix tplink HS220 dimmers (round 2) (#33928)
* HS220 dimmers are handled as lights with a limited feature set * Dimmers look up has has_emeter every call so this is cached as well now to resovle the performance issue.
1 parent f38ff3b commit 1b0ccf1

File tree

2 files changed

+34
-28
lines changed

2 files changed

+34
-28
lines changed

homeassistant/components/tplink/light.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040

4141
LIGHT_STATE_DFT_ON = "dft_on_state"
4242
LIGHT_STATE_ON_OFF = "on_off"
43+
LIGHT_STATE_RELAY_STATE = "relay_state"
4344
LIGHT_STATE_BRIGHTNESS = "brightness"
4445
LIGHT_STATE_COLOR_TEMP = "color_temp"
4546
LIGHT_STATE_HUE = "hue"
@@ -128,6 +129,7 @@ class LightFeatures(NamedTuple):
128129
supported_features: int
129130
min_mireds: float
130131
max_mireds: float
132+
has_emeter: bool
131133

132134

133135
class TPLinkSmartBulb(Light):
@@ -285,8 +287,9 @@ def _get_light_features(self):
285287
model = sysinfo[LIGHT_SYSINFO_MODEL]
286288
min_mireds = None
287289
max_mireds = None
290+
has_emeter = self.smartbulb.has_emeter
288291

289-
if sysinfo.get(LIGHT_SYSINFO_IS_DIMMABLE):
292+
if sysinfo.get(LIGHT_SYSINFO_IS_DIMMABLE) or LIGHT_STATE_BRIGHTNESS in sysinfo:
290293
supported_features += SUPPORT_BRIGHTNESS
291294
if sysinfo.get(LIGHT_SYSINFO_IS_VARIABLE_COLOR_TEMP):
292295
supported_features += SUPPORT_COLOR_TEMP
@@ -306,6 +309,7 @@ def _get_light_features(self):
306309
supported_features=supported_features,
307310
min_mireds=min_mireds,
308311
max_mireds=max_mireds,
312+
has_emeter=has_emeter,
309313
)
310314

311315
def _get_light_state_retry(self) -> LightState:
@@ -360,7 +364,7 @@ def _get_light_state(self) -> LightState:
360364
return self._light_state_from_params(self._get_device_state())
361365

362366
def _update_emeter(self):
363-
if not self.smartbulb.has_emeter:
367+
if not self._light_features.has_emeter:
364368
return
365369

366370
now = dt_util.utcnow()
@@ -446,10 +450,11 @@ def _get_device_state(self):
446450
if isinstance(self.smartbulb, SmartBulb):
447451
return self.smartbulb.get_light_state()
448452

453+
sysinfo = self.smartbulb.sys_info
449454
# Its not really a bulb, its a dimmable SmartPlug (aka Wall Switch)
450455
return {
451-
LIGHT_STATE_ON_OFF: self.smartbulb.state,
452-
LIGHT_STATE_BRIGHTNESS: self.smartbulb.brightness,
456+
LIGHT_STATE_ON_OFF: sysinfo[LIGHT_STATE_RELAY_STATE],
457+
LIGHT_STATE_BRIGHTNESS: sysinfo.get(LIGHT_STATE_BRIGHTNESS, 0),
453458
LIGHT_STATE_COLOR_TEMP: 0,
454459
LIGHT_STATE_HUE: 0,
455460
LIGHT_STATE_SATURATION: 0,
@@ -468,9 +473,12 @@ def _set_device_state(self, state):
468473
if state[LIGHT_STATE_BRIGHTNESS]:
469474
self.smartbulb.brightness = state[LIGHT_STATE_BRIGHTNESS]
470475
else:
471-
self.smartbulb.state = 0
476+
self.smartbulb.state = self.smartbulb.SWITCH_STATE_OFF
472477
elif LIGHT_STATE_ON_OFF in state:
473-
self.smartbulb.state = state[LIGHT_STATE_ON_OFF]
478+
if state[LIGHT_STATE_ON_OFF]:
479+
self.smartbulb.state = self.smartbulb.SWITCH_STATE_ON
480+
else:
481+
self.smartbulb.state = self.smartbulb.SWITCH_STATE_OFF
474482

475483
return self._get_device_state()
476484

tests/components/tplink/test_light.py

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ class SmartSwitchMockData(NamedTuple):
4949
"""Mock smart switch data."""
5050

5151
sys_info: dict
52-
light_state: dict
5352
state_mock: Mock
5453
brightness_mock: Mock
5554
get_sysinfo_mock: Mock
@@ -188,28 +187,28 @@ def dimmer_switch_mock_data_fixture() -> None:
188187
"model": "HS220",
189188
"alias": "dimmer1",
190189
"feature": ":",
191-
}
192-
193-
light_state = {
194-
"on_off": 1,
190+
"relay_state": 1,
195191
"brightness": 13,
196192
}
197193

198194
def state(*args, **kwargs):
199-
nonlocal light_state
195+
nonlocal sys_info
200196
if len(args) == 0:
201-
return light_state["on_off"]
202-
light_state["on_off"] = args[0]
197+
return sys_info["relay_state"]
198+
if args[0] == "ON":
199+
sys_info["relay_state"] = 1
200+
else:
201+
sys_info["relay_state"] = 0
203202

204203
def brightness(*args, **kwargs):
205-
nonlocal light_state
204+
nonlocal sys_info
206205
if len(args) == 0:
207-
return light_state["brightness"]
208-
if light_state["brightness"] == 0:
209-
light_state["on_off"] = 0
206+
return sys_info["brightness"]
207+
if sys_info["brightness"] == 0:
208+
sys_info["relay_state"] = 0
210209
else:
211-
light_state["on_off"] = 1
212-
light_state["brightness"] = args[0]
210+
sys_info["relay_state"] = 1
211+
sys_info["brightness"] = args[0]
213212

214213
get_sysinfo_patch = patch(
215214
"homeassistant.components.tplink.common.SmartDevice.get_sysinfo",
@@ -228,7 +227,6 @@ def brightness(*args, **kwargs):
228227
with brightness_patch as brightness_mock, state_patch as state_mock, get_sysinfo_patch as get_sysinfo_mock:
229228
yield SmartSwitchMockData(
230229
sys_info=sys_info,
231-
light_state=light_state,
232230
brightness_mock=brightness_mock,
233231
state_mock=state_mock,
234232
get_sysinfo_mock=get_sysinfo_mock,
@@ -247,7 +245,7 @@ async def test_smartswitch(
247245
hass: HomeAssistant, dimmer_switch_mock_data: SmartSwitchMockData
248246
) -> None:
249247
"""Test function."""
250-
light_state = dimmer_switch_mock_data.light_state
248+
sys_info = dimmer_switch_mock_data.sys_info
251249

252250
await async_setup_component(hass, HA_DOMAIN, {})
253251
await hass.async_block_till_done()
@@ -276,7 +274,7 @@ async def test_smartswitch(
276274
await update_entity(hass, "light.dimmer1")
277275

278276
assert hass.states.get("light.dimmer1").state == "off"
279-
assert light_state["on_off"] == 0
277+
assert sys_info["relay_state"] == 0
280278

281279
await hass.services.async_call(
282280
LIGHT_DOMAIN,
@@ -290,7 +288,7 @@ async def test_smartswitch(
290288
state = hass.states.get("light.dimmer1")
291289
assert state.state == "on"
292290
assert state.attributes["brightness"] == 48.45
293-
assert light_state["on_off"] == 1
291+
assert sys_info["relay_state"] == 1
294292

295293
await hass.services.async_call(
296294
LIGHT_DOMAIN,
@@ -304,10 +302,10 @@ async def test_smartswitch(
304302
state = hass.states.get("light.dimmer1")
305303
assert state.state == "on"
306304
assert state.attributes["brightness"] == 53.55
307-
assert light_state["brightness"] == 21
305+
assert sys_info["brightness"] == 21
308306

309-
light_state["on_off"] = 0
310-
light_state["brightness"] = 66
307+
sys_info["relay_state"] = 0
308+
sys_info["brightness"] = 66
311309

312310
await hass.services.async_call(
313311
LIGHT_DOMAIN,
@@ -330,7 +328,7 @@ async def test_smartswitch(
330328
state = hass.states.get("light.dimmer1")
331329
assert state.state == "on"
332330
assert state.attributes["brightness"] == 168.3
333-
assert light_state["brightness"] == 66
331+
assert sys_info["brightness"] == 66
334332

335333

336334
async def test_light(hass: HomeAssistant, light_mock_data: LightMockData) -> None:

0 commit comments

Comments
 (0)