TP-Link automation trigger delay

I have an HS200 switch that operates the lights at my front door and an HS100 plug that operates the lights for a nearby outdoor patio. There is no interior switch to control the patio lights, so I “linked” the HS100 to the HS200 as follows:

#
# Tie Patio lights to Front Outside Switch
#  ON:  When Front Outside Lights are turned ON
#  OFF: When Front Outside Lights are turned OFF
  - alias: Turn ON Patio light when Front Outside light is turned ON
    trigger:
      platform: state
      entity_id: switch.front_outside
      to: 'on'
    action:
      service: switch.turn_on
      entity_id: switch.patio
# OFF
  - alias: Turn OFF Patio light when Front Outside light is turned OFF
    trigger:
      platform: state
      entity_id: switch.front_outside
      to: 'off'
    action:
      service: switch.turn_off
      entity_id: switch.patio

When I toggle “front_outside” in the UI, the “patio” lights change instantly.
When I toggle the actual HS200 switch there is a 10 to 25 second delay before the HS100 (patio) changes state.

What causes the state change reporting delay?

@rcblackwell has encountered a similar issue.

@MarkHofmann11 your input appreciated on this topic.

As @YetAnotherDave reports, I’m seeing the same behavior; a 20 to 30 second delay between switching on the first switch and the second switch being activated by HA.

At first, Dave and I thought it may be due to limited resources on a NAS (Me) or RPi (Dave). To test this theory I installed HA on a Debian server that was built on a Dell XPS 9100. No lack of horse power with that puppy! Results were the same.

I had to add the self.update_state() at the end of the def turn_on and def turn_off in the switch.py for the tplink component to fix the delay issues on updating the status.

You might want to experiment and add it to def is_on as well, if you still have issues.

Here is the area in switch.py that I’m referring to:

    @property
    def is_on(self):
        """Return true if switch is on."""
        return self._state

    def turn_on(self, **kwargs):
        """Turn the switch on."""
        self.smartplug.turn_on()
        self.update_state()

    def turn_off(self, **kwargs):
        """Turn the switch off."""
        self.smartplug.turn_off()
        self.update_state()

I added self.update_state() before the return in def is_on(self) and rebooted… no apparent effect after reboot. 13 - 25 second delay still remains. Since that didn’t work I also tried inserting the self.update_state() after the return (didn’t really make sense to me) in def is_on(self) and rebooted… that didn’t help either

    @property
    def is_on(self):
        """Return true if switch is on."""
        self.update_state()
        return self._state

    def turn_on(self, **kwargs):
        """Turn the switch on."""
        self.smartplug.turn_on()
        self.update_state()

    def turn_off(self, **kwargs):
        """Turn the switch off."""
        self.smartplug.turn_off()
        self.update_state()

I’m running Home Assistant Core 0.115.3 are you on a newer version?
Operating system HassOS 4.13

Thanks again for your suggestions.

I have a new theory. I don’t believe this state change detection lag is “fixable”.

Polling vs Interrupts

When a switch is toggled in the UI, the HA server is immediately informed, the automation is invoked, the action completed “instantaneously”. Two lights switch on/off as one. “synchronized ballet”

When a physical switch is toggled (HS200, HS100, HS105) the attached circuit instantly responds. However, when does the HA or Kasa server learn that the switch state has changed?

For Kasa, the physical switch sends a message to the server, the server than sends a message back to the app. It takes 2 to 5 seconds to see the state change reflected in the Kasa app.

For HA, there is no communication path from the physical switch back to the HA server. Instead, the HA server must continuously POLL the physical switch to ask: “Are you on?”.
I’m guessing that HA polls the Kasa devices once every 30 seconds.

I now interpret the 13 - 25 second delay as the moment the physical switch is toggled relative to the start of the 30 second polling cycle (really a 1 to 29 second delay based on timing). Reducing the width of the polling window (15, 10, 5, 2, 1??? seconds) would make communication with the Kasa devices excessively chatty, I’ll live with the state change lag without further regret.

Is this close to being correct?

As @YetAnotherDave reports, I’m seeing the same behavior after installing the zip that @MarkHofmann11 provided. Original integration was removed prior to adding files from the zip.

I’m seeing the same behaviour when monitoring TP-Link switches in the Kasa application.

If that we’re the case, and I’m not saying it isn’t, wouldn’t other integrations (switches, plugs, bulbs, etc) be demonstrating the same behaviour?

Is it possible that HA uses listeners rather than polling?

Makes sense - however I’d like to get to the root of the issue before adding more devices to HA.

Exactly right. I see the same behavior with switches (HS200) and plugs (HS100, HS105, KP400). I don’t have experience with any other TP-link devices.
[edit: Bulbs don’t have an external/physical on/off switch so it’s not possible to determine the time from “physical” toggle of a swtich to “virtual” reporting/movement of the “switch” in the user interface.]

I’m resigned to “it works as designed” (not a bug)

[Edit]
Kasa Smart Action (using the Kasa App) provides a dependable 2 second delay from the time I press the HS200 button to the time the HS100 changes state vs 1 to 29 second lag when using HA to trigger device 2 based on input from device 1).

Kasa Smart Action

I’m going to vote in here that this is indeed a bug. I am implementing TPLINK/Kasa devices assuming Home Assistant will be able to respond to HS200 switch changes at least as quickly as my SmartThings Hub. ST reliably responds to physical switch state changes in the order of 1-2 seconds (virtually identical to Kasa app) instead of the 20-30 second response time I see for the same switch states being registered by HA.

So either this is a bug or I invested in many HS200 switches on a naive assumption that HA should be able to perform a very basic function as well as ST. My two bits …

1 Like

I’m also not having luck reducing the 30 second (worst case) latency between TPLINK HS200 switch press and the state change being registered within HA.

I moved …homeassistant/components/tplink out of the way, created new tplink folder and restored contents TPlink.zip, rebooted … and same latency results. Tried adding the self.update_state() before the return of is_on() routine and still no luck ;(. Note that for me at least a state change initiated from within HA is immediately registered on the HS200…which has always been the case.

I’ve been able to confirm HA only updates TPLINK switch status exactly every 30 seconds. So right now looking for a method to decrease that interval to something more reasonable. I’m seeing workaround suggestions to use automation to trigger homeassistant.update_entity every 5 seconds ( https://github.com/home-assistant/core/issues/21768#issuecomment-470959458) but that really seems a bit cludgy.

Halp!

@YetAnotherDave, It seems you’re correct on this matter.

I’ve been digging into the delay issue and today came across an interesting article in the Home Assistant documentation. The documentation indicates HA poll’s devices every thirty seconds. This could explain why the entity, in this case an HS200, doesn’t immediately update in HA when it’s turned on or off. The article reads

"### SCAN INTERVAL

Platforms that require polling will be polled in an interval specified by the main component. For example a light will check every 30 seconds for a changed state. It is possible to overwrite this scan interval for any platform that is being polled by specifying a scan_interval configuration key. In the example below we set up the your_lights platform but tell Home Assistant to poll the devices every 10 seconds instead of the default 30 seconds."

# Example configuration.yaml entry to poll your lights every 10 seconds.
light:
  - platform: your_lights
    scan_interval: 10

The related page is located at Entity integration platform options.

I should add that the article indicates the ability to change polling duration has been phased out :smirk:.

Regards

1 Like

If there was a way to get an “interrupt” when Device-1 (e.g. an HS200) changes state then it would be possible to trigger Device-2 (e.g. as HS100) within 2 seconds. @rcblackwell has confirmed the polling cycle (aka Scan Interval) to be 30 seconds. The 1 to 29 second delay that you see is based on how much of the 30 second polling cycle has already expired before you press the button on the HS200.

Reducing the scan interval to 1 second makes for an overly chatty protocol. This becomes a user priority issue. Which is more important to you: a fast response at Device-2 based on the button press at Device-1? or minimizing network traffic?

For me it was “both”. Therefore, I abandoned HA to “link” two of my Kasa devices and went back to the Kasa app to minimize “trigger” time.

I’d like to have a pure HA implementation, but as with many things in life, this is not my first compromise. :wink:

I didn’t realize the Kasa App had that functionality. I think I’ll follow your lead and do the same. At least until HA is capable of operating in the same fashion.

Thanks for the tip!

1 Like

yes… see earlier post re: Edit Action (found in Smart Action in Kasa App)

FWIW I ended up integrating Node Red into HA and then added node-red-contrib-tplink which is a super dope node allowing full access and configurability on TPLINK devices including the HS200 … and allows for polling down to 500 ms if you want. I’ve settled on 2 seconds and things are sweet.

If you’re only running Home Assistant Core it’s not hard to integrate node red to it but a bit of a pain finding any docs on it as almost everyone does it through hassio …

So on my raspian linux it was as follows:

# sudo apt install nodejs
# sudo npm install -g --unsafe-perm node-red
# install node-red-contrib-home-assistant-websocket
# npm install node-red-contrib-tplink

You then create access token in HA and paste that into the tplink node’s HA server config screen in Node Red and that was about it. Just remember to keep hitting the red Deploy button at the top of the screen after every round of changes. From that point you can follow other tutorials on how to config Node Red with HA.

Thanks for everyone saving me chasing further on getting HA to change the device poll rate from 30 seconds.

3 Likes

@3gyptian Wow! I had not considered Node Red. I’m running the the full (easy) HA for RPiv4 (4.19.127-v7l Linux) as supplied by the HA build, it does not include “apt”.

I’ll follow your hints to learn more about Node Red for future reference. TP-Link Contrib.

For me the “best” solution would be to somehow intercept the “state change” message that the HS200 sends to the Kasa server, but that is far beyond ny skill level. (i.e. no polling)

I’ve successfully installed Node-Red and added the node-red-contrib-tplink super dope node.

After adding the contrib package I was able to add TP-Link nodes for the desire items to Node-Red. What I cannot figure out is how to connect them to HA. I’ve searched for but have been unsuccessful in finding suitable tutorial for what I’m trying to achieve. Would you mind;

  • Pointing me to a couple of tutorial samples and;
  • Sharing a screen shot of your Node-Red integration for TP-Link

Regards
Robert

While investigating Node-Red functionality I found there’s a number of “ready made” examples that may be imported for review. From the menu select “Import” then click the “Examples” tab. Select the flow you wish to review and import it. There’s lots of great examples - specific to TP-Link and HA.

Regards

@3gyptian, Any chance you can post code for one the TPLink switches that you’ve changed polling time for? I’m trying to set up a similar scenario but thus far have been unsuccessful. I’m not sure which node(s) to link with. Do I use the “Kasa” node as the first point or HA’s State change? What order do these nodes go in? My current code is;

[{"id":"da977d62.39175","type":"api-call-service","z":"9c88f7c4.b7ad18","name":"On","server":"fcf9b76b.256a88","version":1,"debugenabled":true,"service_domain":"switch","service":"turn_on","entityId":"switch.desk_lamp","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1030,"y":380,"wires":[[]]},{"id":"8bcf42ef.90e48","type":"api-current-state","z":"9c88f7c4.b7ad18","name":"In on?","server":"fcf9b76b.256a88","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is_not","override_topic":false,"entity_id":"switch.desk_lamp","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":830,"y":380,"wires":[["da977d62.39175"],["ce8eede6.0f0b1"]]},{"id":"d3be067e.3e4f48","type":"switch","z":"9c88f7c4.b7ad18","name":"On-Off","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"},{"t":"eq","v":"off","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":670,"y":420,"wires":[["8bcf42ef.90e48"],["371e2920.33f5d6"]]},{"id":"371e2920.33f5d6","type":"api-current-state","z":"9c88f7c4.b7ad18","name":"Is off?","server":"fcf9b76b.256a88","version":1,"outputs":2,"halt_if":"off","halt_if_type":"str","halt_if_compare":"is_not","override_topic":false,"entity_id":"switch.desk_lamp","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":830,"y":460,"wires":[["dd8b3de1.d647c"],["ce8eede6.0f0b1"]]},{"id":"65f89bce.4dcba4","type":"kasa","z":"9c88f7c4.b7ad18","name":"Breakfast - HS220(US)","device":"192.168.2.200","interval":"7500","eventInterval":"2000","payload":"getInfo","payloadType":"info","debug":true,"x":190,"y":320,"wires":[["1b0af2b0.c280bd","d3be067e.3e4f48"]]},{"id":"dd8b3de1.d647c","type":"api-call-service","z":"9c88f7c4.b7ad18","name":"Off","server":"fcf9b76b.256a88","version":1,"debugenabled":true,"service_domain":"switch","service":"turn_off","entityId":"switch.desk_lamp","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1030,"y":460,"wires":[[]]},{"id":"fcf9b76b.256a88","type":"server","name":"Home Assistant","legacy":false,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]

With appreciation

@rcblackwell … hey sorry on the delay responding here. Ya so I’m not sure where to find the code or config files works for HA/node red (I’m new to this too), I did it all through the node red gui only. You only need the HA login token and the switch entity ID from HA that you want to change state …in my case a Tuya power switch that toggles power to my garage ceiling lights upon button presses of the TPLINK wall switch.

My node flow is as follows:

Working left to right … the inject node is used just to send a single message of “startPowerEvents” at startup to the TP-LINK node to tell it to enable the transmission of start and start power events (HS200 button presses in my case). The default behaviour of this node is that it won’t send anything out of the TPLINK node even when you press the power button … which took me a little while to figure out!

Event messages you can send to configure and content you can receive to/from the TPLINK node are well described in the node red under ‘Kasa’ documentation/help screen in node red … here’s the blurb on ‘StartPowerEvents’

image

Then moving over to the TPLINK HS200 node … it’s pretty straightforward and I think I only changed the polling rate down to 1000 milliseconds. You click on the search icon and it will scan your network for the TPLINK devices fairly quickly. Pretty dope!

The next node is Home Assistant ‘Call Service’ node configured with: (top to bottom)

  • connect to HA server (with token as I described earlier)
  • have it connect to the HA ‘switch’ domain
  • have it perform toggle function each time triggered
  • define the HA entity ID which we can extract from entity list in HA … or just start typing the beginning of it in the node field and it will start auto-filling the matches. I have a few switches all with an ugly entity ID so I just copy paste it from HA.

fyi here’s what my HA server config looks like in Call Service node -

Then the last (optional) debug node which is set to go to ‘Debug Window’ which shows on the right node red window pane when you select the little beetle. Handy as heck and you can insert debugs anywhere in the flow. Helped a lot figuring out how the TPLINK node worked and how to get it going with that inject node.

It’s all been working solid as a rock for me. And for network overhead … not far from my garage light switch is my IP webcam blasting surveillance video 24x7. A dozen bytes every second of HS200 polling traffic I’m pretty sure won’t make a difference!

6 Likes