Sensor state change delay

I'm in the process of installing a new 24-zone system I received today. I have about 40 pre-wired sensors and I tried to trace them using a tone tester but after only tracing two of them I decided I would just wire 6 sensors at a time up to one konnected board, open/close windows, and then label the wire.

When I started with the first 6 zones wired up I would open a window for a few seconds and SmartThings wouldn't update the state. I've seen some delays with other ST sensors that I have, so I thought it was just a ST app issue. So I pulled up the live log on the SmartThings site and started following it. What I found was intermittent messages being received. For example, I would open the window and no event was logged, but when closing the window is would transition to close. Repeating the action would show the open event, but no close. Intermittently I would see both the open and close event, but about half the time at least one of the events would be missing in the log. So I had to rule out ST as the problem. 

I disconnected the NodeMCU from the konnected board and then connected the MCU via USB. I updated the firmware to the latest version and then removed the device in ST and re-added it. After doing this I connected the D5 and G pins with a wire and see in the console the update to the state: 

Heap: 32888 HTTP Call: 204 state 0 pin 5 
Heap: 32888 HTTP Call: 204 state 1 pin 5 

The problem I am seeing is that it takes right around 3 seconds between when the circuit is closed and when the above message is written. The messages above seem to be after the call is complete. Setting up a SmartLights automation to trigger the buzzer on the state changing causes the sound to start playing slightly before the 204 call messages above are printed, but still at least 2 seconds after the sensor state changes.   

I've searched through the community and haven't seen any clear descriptions of the sensor delay. When I watched "Konnected Alarm Panel detail demonstration" video on youtube it appears to take less than 1 second to respond to changes. 

Was is the expected delay? Is there a way to decrease this delay? 

Thanks, 
-K

I did another test where I jumped the D5 and G pins on the MCU once per second for a total of 4 times.  Here is the log output with timestamps.

[04/08/18 - 01:16:19:505] Heap: 33024 HTTP Call: 204 state 0 pin 5

[04/08/18 - 01:16:21:919] Heap: 32896 HTTP Call: 204 state 1 pin 5

[04/08/18 - 01:16:24:883] Heap: 33016 HTTP Call: 204 state 0 pin 5

[04/08/18 - 01:16:27:293] Heap: 33104 HTTP Call: 204 state 1 pin 5

[04/08/18 - 01:16:29:591] Heap: 33184 HTTP Call: 204 state 0 pin 5

[04/08/18 - 01:16:31:924] Heap: 33280 HTTP Call: 204 state 1 pin 5


The calls were queued up in some way and then sent over 12 seconds or so even though I stopped changing the state after the first 3 seconds or so.


Here is the timing breakdown:

Interval (msec)
19.505
21.919 2414
24.883 2964
27.293 2410
29.591 2298
31.924 2333

The queuing behavior seems odd when it takes a few seconds to process each state transition.


During this test the SmartThings live log also missed some of the transitions, it only shows one event during this time


4f9894ac-fc01-4b7c-b3d3-812994ca94a1 1:16:27 AM: debug 3 is closed

Thanks for the detail here, Kevin!

Everything you're describing looks completely healthy. Yes, there is a 2-3 second delay in communication with SmartThings for each state change. Most of this time spent is in SSL/TLS negotiation, which is unfortunately a bit slow on the NodeMCU devices. Yes, it was a bit faster in the earliest version of the firmware when I recorded the detailed demonstration video. This was on an older firmware that didn't support TLS 1.2 ciphers, so it was faster but also less secure. 

You've observed that every state change is returning a 204 response (that means success), so SmartThings is receiving every state change. I've also seen occasional events dropped from the live log, and I think that's what's going on here. The 204 response though guarantees that ST received the state update.

You are correct that the state changes are queued up and replayed in sequence until all have been sent successfully. In the latest software (2.2.3) if any state changes fails (non-2XX response) then it will retry up to 10 times before automatically rebooting as a failsafe.

Right now there's no way to decrease the delay, as the ONLY way that Konnected can communicate to SmartThings is via HTTPS to the ST cloud. I'm hopeful that in the future ST will allow some local LAN communication capabilities either via unsecured HTTP or something lighter weight like MQTT, but it's not possible yet. You can try Home Assistant which runs locally and is MUCH faster over unsecured HTTP. We're working on Hubitat integration too, which I hope will also be faster over the LAN.

Hi Nate,


Thanks for the quick response.  Your explanation makes complete sense.  I've wired up all of the boards and I haven't seen any updates not being reflected in SmartThings now.  


The delay is only noticeable for a door chime with the system.  Walking in the door and being half way into the room until the chime activates is odd. :)  I've started looking into Home Assistant and what it would take to move to that since my ST installation is pretty new and I haven't done much with it besides a few SmartLights automations.  


One other option I was thinking about was using a reverse-proxy like you have documented in the Home Assistant section to deal with the TLS overhead.  I believe a similar solution for ST may work as well.  If the konnected software had a proxy URL configuration which points to the generic reverse-proxy endpoint then the proxy could be configured to connect to the public SmartThings endpoint and access the same URL path.


So something like this:

- In Konnected configuration - define a proxy endpoint URL: http://192.168.1.8:5000

- Konnected startup, send request:   http://192.168.1.8:5000/api/smartapps/installations/12345678-abcd-4321-fedc-f21230f92c28

- Proxy handles ST connections, request sent: https://graph-na04-useast2.api.smartthings.com:443/api/smartapps/installations/12345678-abcd-4321-fedc-f21230f92c28


So basically the proxy passes the entire URL path from the konnected (client) side to the ST (server) side of the proxy.


I'm ignoring any security implications on my internal network with this approach, and making some assumptions on how the ST API behaves.  I started looking at the code on github to see if I could play around with this approach as well.


I had another idea on using the tls module to keep a persistent connection to ST and reusing the same connection for each request, removing the connection set up overhead.  I did some digging into how to setup a quick dev environment to write an example of this but it got a little more complicated than I expected pretty quick.  Luckily I only had to use 3 of the 4 controllers I bought, so maybe I can play around with that at some point in the future.


Thanks,

-K


Just a quick follow-up.  The reverse-proxy solution worked.  I modified the Konnected Service Manager in the ST IDE and modified the URL being called:     

 def body = [
    token : state.accessToken,
    // old-- apiUrl : apiServerUrl + "/api/smartapps/installations/" + app.id,
    apiUrl: "http://192.168.1.8:9001" + "/api/smartapps/installations/" + app.id,
    blink: settings.blink,
    discovery: settings.enableDiscovery,
    sensors : sensors,
    actuators : actuators,
    dht_sensors : dht_sensors,
    ds18b20_sensors : ds18b20_sensors
  ]

I saved and published for my instance.
In the Konnected SmartApp I then went to each Konnected device, went to the zone configuration page and then clicked Save to push the new configuration.
After the device restarted the Device Status page shows the "API Endpoint" as the URL modified above.

I then configured a haproxy docker container to act as the reverse-proxy with the following configuration:  

Dockerfile
---
FROM haproxy:1.7

COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg

haproxy.cfg

global
maxconn 512
tune.ssl.default-dh-param 1024

resolvers dns
nameserver internal1 192.168.1.15:53
resolve_retries 3
timeout retry 3s
hold valid 150ms
hold other 150ms
hold refused 150ms
hold nx 150ms

defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms

frontend http
bind *:9001
default_backend smartthings

backend smartthings
server smartthings graph-na04-useast2.api.smartthings.com:443 resolvers dns maxconn 64 ssl verify none force-tlsv12

docker build/run:

docker build -t haproxy_st .
docker run -d -p 9001:9001 --name=haproxy_st haproxy_st

   

The response time has gone to approximately 1 second between sensor change and the chime playing.

I know this might be too advanced for some users but wanted to share with others who might be interested.  

Have fun!

Is it possible to get some more detailed instructions on how to do this? The 3 second delay on chimes is annoying and I'd love to shorten it. I tried looking in my Konnected Service Manager code for something that resembled the snippet you provided, but I don't see anything that matched anywhere close...

Nate, is this something you can potentially role into a software update?

Damn Kevin F that was a legit solution! 

Neat idea! Thank you for sharing this, Kevin F.

@Kevin Hornby


The code I changed is here:

https://github.com/konnected-io/konnected-security/blob/master/smartapps/konnected-io/konnected-service-manager.src/konnected-service-manager.groovy


Line 451 at commit 36e69fe


Here is a quick install overview:

- You need a machine capable of running Linux based docker containers.  I'm running Ubuntu 16.04.4 with docker version 1.13.1, built Nov 2017 (kinda old).

- You need to know the IP of the DNS server other clients on your network are using.

- Create a new directory on the linux machine.

- In the directory create the Dockerfile and haproxy.cfg files with the content I specified in the previous post.

- Modify haproxy.cfg, 

  - Replace 192.168.1.15 in the dns section with the IP of your DNS server.

  - Replace "graph-na04-useast2.api.smartthings.com:443" with the URL of your SmartThings instance.

  - Save changes.

- Run the docker build and docker run commands listed above

- Run "docker ps" and verify you see a container running similar to:

 

CONTAINER ID        IMAGE               COMMAND                  CREATED          STATUS          PORTS                     NAMES
e7a6c1280289        haproxy_st          "/docker-entrypoin..."   4 days ago       Up 4 days       0.0.0.0:9001->9001/tcp    haproxy_st

- You can modify the port that haproxy is using by changing the "-p" parameter on the docker run command.

- In the konnected-service-manager.groovy, change the apiUrl variable I specified before and replace the IP address with the IP of the machine running the docker container and the port haproxy is listening on.


Hope that helps.

-K

Kevin, 


Just dropping a thanks in here for the idea. I spent this morning spinning up haproxy on my pi3 and mirroring your config. Works like a champ! 


Thanks! 

@Kevin F


I appreciate your work! A few questions if you don't mind:


1. Can we use the following string as the instance URL? account.smartthings.com:443

My understanding is this should point to your individual ST shard.


2. Think a raspberry pi 3 can be used as the reverse proxy and handle the requests for a single home?


3. Is there any way to code this so that it can work with ST hubs across several ST instances? Lets just say, hypothetically, I have 2 hubs in a single location working off of two different ST servers.


Thank you in advance,

Scratch question 2, just realized Paul tried it on a pi3 and it works, lol.

Paul B,


You mind sharing steps on how to set up the reverse proxy server on a pi3?


Thank you in advance,

Is anyone interested in providing a (nearly) out-of-the-box solution for this, for a fee of course?

Kevin, just fell over this thread, having been experiencing problems with one of my boards going into a reboot loop, and googled the slow response/reaction times in ST.

 

Anyway, I managed to setup the same kind of thing using my Synology NAS the built-in Reverse Proxy Rules... works an absolute dream, I open the door, I get the chime!

 

Although, it did have me stumped for a while, until I realised I'd missed a step: 

<quote>In the Konnected SmartApp I then went to each Konnected device, went to the zone configuration page and then clicked Save to push the new configuration.
After the device restarted the Device Status page shows the "API Endpoint" as the URL modified above.
: <unquote>


Good work

Cheers

Grant

Is this delay an issue if using openHAB or other local hub?

Sorry, if the answer is obvious, I'm an hardware guy not a software guy.

This is an old thread but i am getting this issue with the pro board, we have zone 6 connected to an rfid keypad, when we swipe our card it closes the circuit on the zone which triggers 1 of 2 automations,  the alarm to disarm in home assistant if it is the armed_away state, and to arm if it is the disarmed state, problem is there is a 3 second delay, so users then swipe again thinking it hasn't worked and home assistant then runs the opposite automation arming again, worked fine when we were using a d1mini and mqtt. but i was trying to get all of the security on one hard wired board, it here a way to speed this up? the pro board is fully up to date btw