core: Kasa Light turn on doesn't immediately take effect

The problem

I’ve had an automation that does similar to the one in this thread which turns on a light, checks its condition afterward, and if its off stops a timer. I’ve simulated this in the below yaml and without the ‘delay’ the light turns on and then immediately off. It should be turning on, then seeing it is on and not turning it off. I must add delays to the automation for it to work effectively. This doesn’t happen with non-kasa lights and never happened prior to the new upgrade. It seems the light turn on is moving on to the next step BEFORE its actually being reflected in HA. This has caused race conditions in the automation.

What is version of Home Assistant Core has the issue?

core-2021.10.2

What was the last working version of Home Assistant Core?

core-2021.9.7

What type of installation are you running?

Home Assistant OS

Integration causing the issue

kasa-python

Link to integration documentation on our website

No response

Example YAML snippet

This causes the light to immediately turn back off

alias: Test Timer without sleep
sequence:
  - service: light.turn_on
    target:
      entity_id: light.master_bedroom_lights_2
    data:
      brightness_pct: 5
  - choose:
      - conditions:
          - condition: state
            entity_id: light.master_bedroom_lights_2
            state: 'off'
        sequence:
          - service: light.turn_off
            target:
              entity_id: light.master_bedroom_lights_2
    default: []
mode: single



This works correctly.

alias: Test Timer with sleep
sequence:
  - service: light.turn_on
    target:
      entity_id: light.master_bedroom_lights_2
    data:
      brightness_pct: 5
  - delay:
      hours: 0
      minutes: 0
      seconds: 1
      milliseconds: 0
  - choose:
      - conditions:
          - condition: state
            entity_id: light.master_bedroom_lights_2
            state: 'off'
        sequence:
          - service: light.turn_off
            target:
              entity_id: light.master_bedroom_lights_2
    default: []
mode: single

Anything in the logs that might be useful for us?

no

Additional information

No response

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 17 (13 by maintainers)

Most upvoted comments

not stale, haven’t had time to circle back to this yet.

This is in my queue. It might be a while before I get to it though.

There currently is no way to ask the coordinator to block until the refresh is complete.

It could be built into the integration manually with something like this

diff --git a/homeassistant/components/tplink/entity.py b/homeassistant/components/tplink/entity.py
index b331f70c5b..d2b7b5a6c4 100644
--- a/homeassistant/components/tplink/entity.py
+++ b/homeassistant/components/tplink/entity.py
@@ -1,6 +1,7 @@
 """Common code for tplink."""
 from __future__ import annotations
 
+import asyncio
 from typing import Any, Callable, TypeVar, cast
 
 from kasa import SmartDevice
@@ -22,7 +23,10 @@ def async_refresh_after(func: WrapFuncType) -> WrapFuncType:
         self: CoordinatedTPLinkEntity, *args: Any, **kwargs: Any
     ) -> None:
         await func(self, *args, **kwargs)
+        refresh_future = asyncio.Future()
+        self._refresh_futures.append(refresh_future)
         await self.coordinator.async_request_refresh_without_children()
+        refresh_result = await asyncio.wait_for(refresh_future, timeout=2)
 
     return cast(WrapFuncType, _async_wrap)
 
@@ -38,6 +42,7 @@ class CoordinatedTPLinkEntity(CoordinatorEntity):
         """Initialize the switch."""
         super().__init__(coordinator)
         self.device: SmartDevice = device
+        self._refresh_futures = []
         self._attr_unique_id = self.device.device_id
 
     @property

… and then set the futures when the refresh calls back, and clear out the list

This adds a bit of complexity to the integration. I am not the code owner of the integration and just helping out for a bit so it isn’t something I feel comfortable adding.