[ST Edge] Smartthings Alarm.com Integration

The other thing to try is just refresh the device by pulling down on the page to force a refresh

Iā€™ve been trying to run the proxy server on Android using termux. Iā€™m having a hard time getting the supervisord.conf file to work. I had to edit the path to an accessible location on Android. Canā€™t get it to open an http server.

Is it possible to do this on Android? Thinking of loading it on an old phone.

Not sure about Android, but I have published a docker container and added docs on how to invoke it to make it easier. If you install docker on your platform, the docker run command is the simplest way to make it work. I tried it on my raspberry pi to make sure it works, and it does.

1 Like

To get stproxy running I had to edit supervisord.conf, ensuring it pointed to the right python3. Turns out my Synology already had python 2.x. I had to change this line:

[program:stproxy]
command=/usr/local/bin/python3 server.py

Iā€™m having issues setting up the device/driver in Smartthings with the proxy running on my Synology NAS.

Iā€™ve gotten as far as setting up the alarm.com panel in smartthings but when refreshing on the device page I get ā€œthere was a problem connectingā€.
Iā€™ve tried leaving the ip/port blank but no luck. Iā€™ve also entered the local IP of my Synology (firewall off) with both 8081 and 9001. I see the Synology listening on port 8081, but not port 9001 - should it be? (using netstat -an | grep 9001).

The last few lines from /tmp/supervisord.log is:

2022-09-16 21:47:10,541 INFO RPC interface 'supervisor' initialized
2022-09-16 21:47:10,541 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2022-09-16 21:47:10,546 INFO daemonizing the supervisord process
2022-09-16 21:47:10,549 INFO supervisord started with pid 3604
2022-09-16 21:47:11,560 INFO spawned: 'stproxy' with pid 3605
2022-09-16 21:47:12,566 INFO success: stproxy entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

update: inet_http_server is intentionally commented out, is that right?

;[inet_http_server]
;port=127.0.0.1:9001

I also tried the Docker solution on my a Mac. Docker container started up but no ports were exposed. I saw this warning: WARNING: Published ports are discarded when using host network mode

Doing a docker ps shows nothing under the port column

docker ps
CONTAINER ID   IMAGE                      COMMAND                               PORTS                                           
5ec5998133b8   schwark/stproxy            "python server.py"                                                                   

I tried without the --net=host arg which exposed the ports but now I canā€™t find the device from smartthings. I can see the mac listening on port 8081 (when not using --net=host):

āžœ netstat -an|grep 8081
tcp46      0      0  *.8081                 *.*                    LISTEN

yes that is correct, 9001 is not used and not needed. 8081/tcp and 1900/udp are the two ones that are used. the 1900/udp is used to automatically discover the proxy on your network from SmartThings. if that UDP does not work, you will have to manually put in the host and port into SmartThings.

you should leave the host and port blank if your UDP is working, it will automatically find and use the proxy. if that does not work for some reason, try adding the IP address of your proxy. The port is default 8081 so you should not need to enter/change that.

Once the preferences are changed, you will need to pull down to refresh the Alarm.com Panel device. I am not automatically doing that on infoChanged.

The issue without --net=host is that the UDP broadcasts are not forwarded into the docker container, so the automatic proxy discovery is not working. It is ok for the Published ports discarded message to show up - it should still work. It shows that message because in that mode ALL ports are forwarded, not just specific ones, so you will not see anything in ports.

Also, I should mention that my Mac Docker did not end up forwarding UDP broadcasts even with --net=host. However, my rapberry pi docker does, and I would expect your Synology docker would as well.

In all cases, manually entering the IP into SmartThings should fix the problem as long as the proxy is running on port 8081 at that IP.

Am I correct that ā€œdiscoveryā€ and the UDP port is used during the ā€œadd device - scan nearbyā€ step? Iā€™m trying to understand where Iā€™m manually enter port 1900, also trying to determine what exactly is failing for me.

Here is where Iā€™ve been trying ports 8081 and 1900:

It sure looks like both 1900 and 8081 are open on my NAS:

**āžœ** nc -uzv 192.168.1.254 1900
Connection to 192.168.1.254 port 1900 [udp/ssdp] succeeded!

**āžœ** nc -zv 192.168.1.254 8081
Connection to 192.168.1.254 port 8081 [tcp/sunproxyadmin] succeeded!

No matter what I try this is what I get when refreshing:

UPDATE 1: I turned the supervisord log level to trace and see this at startup. Look ok?

http server is running as reverse proxy at 192.168.1.254:8081
ssdp server is running 192.168.1.254:8081

UPDATE 2: I see this in the logs when I re-add the panel device in smartthings and when refreshing the device

2022-09-17 12:51:20,554 DEBG 'stproxy' stderr output:
192.168.1.16 - - [17/Sep/2022 12:46:30] code 404, message error trying to proxy
192.168.1.16 - - [17/Sep/2022 12:46:30] "GET /1/login.aspx HTTP/1.1" 404 -
----------------------------------------
Exception happened during processing of request from ('192.168.1.16', 43646)
Traceback (most recent call last):
  File "/var/packages/py3k/target/usr/local/lib/python3.8/socketserver.py", line 650, in process_request_thread
    self.finish_request(request, client_address)
  File "/var/packages/py3k/target/usr/local/lib/python3.8/socketserver.py", line 360, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/var/packages/py3k/target/usr/local/lib/python3.8/socketserver.py", line 720, in __init__
    self.handle()
  File "/var/packages/py3k/target/usr/local/lib/python3.8/http/server.py", line 427, in handle
    self.handle_one_request()
  File "/var/packages/py3k/target/usr/local/lib/python3.8/http/server.py", line 415, in handle_one_request
    method()
  File "server.py", line 47, in do_GET
    req_header = (self.parse_headers() | self.get_base_headers(hostname))
TypeError: unsupported operand type(s) for |: 'dict' and 'dict'

I should have explained before that I am running on the NAS without Docker

I have it up and running on a raspberry pi using docker. Every time I change the alarm status it has to relog into Alarm.com and sometimes the system will change staus, and sometimes not. Each time the logon appears successful because Alarm.com sends me a notification of successful login, but the status of the system doesnā€™t necessarily change like i have requested in SmartThings, Is there any way to keep the pi continually logged into Alarm.com? My android phone has a ā€œkeep me logged inā€ option. If not, any suggestions on how to make SmartThings commands to Alarm.com more consistent?

Doing nothing since reinitiating the proxy on the pi and reinstalling the edge driver on the SmartThings hub about 1:30ā€¦ you can see by the Alarm.com log, the pi every so often has to re-login even though i have done nothing but let it sit there. If we had an option to ā€œkeep me logged inā€ would keep this from happening, and show sensor activity in near real-time.

it should update the status every 5minā€¦ So it can take up to 5min for the status to updateā€¦ The login happens whenever alarm.com servers time the session out. They seem to time out even if you do JSON requests - may need to load some webpages too to keep sessions alive longer. Have not played with how to keep the session alive longer.

It looks like a python version issueā€¦ Python 3.9 introduced the merge operator - I am assuming you are on something less than that?

Also, the 1900 port is never to be entered - it is the standard ssdp portā€¦ The manual entry would only be 8081 or any other port the proxy is running on.

I just checked in a change to remove the 3.9 dependency

This is the web login log from Alarm.com showing the multiple logins from the pi. I literally have had no activity with the Alarm.com panel in SmartThings. If the pi would just remain logged in like the android app, you would stop having the pi having to login to if you wanted to change the alarm status everytime you make a change to the alarm status in SmartThings.

Or is this something wrong with my pi setup because it should already remain logged in at all times?

No, nothing you are doing - the app logs in every time the server invalidates the sessionā€¦ I donā€™t control that, and I have not figured out a way to stay logged inā€¦

BTW, the android app uses their API and has a token that is long lived. I was unable to figure out the API because when I put a Charles proxy in between to reverse engineer the API, the app shuts down and does not work.

1 Like

Thanks for the answerā€¦ it is appreciated.

Went through the whole setup process and hit a wall. This is all I can get in the app.


I am running the proxy on a Raspberry Pi Zero W and the app on Android. I know essentially nothing about Linux, but I was able to slowly figure out how to follow the documentation and install the code with Docker. Everything seemed to install correctly. Still, no matter how many times I refresh, and even after rebooting the hub, all I get is what you see above. Any suggestions?

I ran into this on two different installs. Both times it was resolved with a reboot of the SmartThings Hub.

1 Like

@schwark yes I was on python 3.8.6. I just grabbed the latest update which fixed the error I was seeing. I can now see the alarm.com http calls but Iā€™m not sure theyā€™re successful (I still see the same error when refreshing the device). Here is the output in /tmp/stproxy.log. Also, it looks like the same log output no matter what username/password I put in settings.

23:17:03,942 root DEBUG ========start-get========
23:17:03,943 root DEBUG url: https://www.alarm.com/login.aspx
23:17:03,955 urllib3.connectionpool DEBUG Starting new HTTPS connection (1): www.alarm.com:443
23:17:06,283 urllib3.connectionpool DEBUG https://www.alarm.com:443 "GET /login.aspx HTTP/1.1" 200 32339
23:17:06,342 root DEBUG Cache-Control : no-cache
23:17:06,344 root DEBUG Pragma : no-cache
23:17:06,345 root DEBUG Content-Type : text/html; charset=utf-8
23:17:06,346 root DEBUG Expires : -1
23:17:06,347 root DEBUG Vary : Accept-Encoding
23:17:06,347 root DEBUG Content-Security-Policy : default-src 'self' *.google-analytics.com; font-src 'self' fonts.gstatic.com fonts.googleapis.com; media-src *; img-src * data:; style-src 'self' fonts.googleapis.com 'unsafe-inline' *.cloudfront.net; script-src 'self' *.google-analytics.com *.googletagmanager.com *.google.com *.gstatic.com *.greenhouse.io *.googleadservices.com *.hotjar.com *.facebook.net *.mathtag.com *.licdn.com *.tvsquared.com *.nextdoor.com 'unsafe-inline' 'unsafe-eval'; frame-ancestors 'self' *.alarm.com *.adt.com adt.com.es www.adt.cl www.adt.co.cr www.adt.co.uk www.adt.com.ar www.adt.com.br www.adt.com.mx www.adt.com.uy www.adt.my www.adtsecurity.com.au www.adtsecurity.co.nz www.secomsmart.com.sg www.sakralarm.se lightfootmechanical.com www.secomsmart.com.my smartsecurity.secom.plc.uk www.secom.co.th smartservices.adt.co.uk smartservices.adt.ie infinitysecurity.ca www.protek.com.py www.nos.pt www.chubbhomesecurity.com.au www.alert360.com www.securityinc.net i-wonder.co.jp; frame-src 'self' *.alarm.com *.youtube.com academy-alarm.com *.google.com *.greenhouse.io *.mathtag.com *.hotjar.com;, frame-ancestors 'none', frame-ancestors 'none'
23:17:06,348 root DEBUG X-Frame-Options : DENY, DENY
23:17:06,349 root DEBUG P3P : policyref="/w3c/p3p.xml",CP="OUR SAMa ADM UNI BUS ALL CUR DSP TAI COR IND STA"
23:17:06,350 root DEBUG Access-Control-Allow-Origin : *
23:17:06,350 root DEBUG X-Content-Type-Options : nosniff
23:17:06,351 root DEBUG Strict-Transport-Security : max-age=31536000; includeSubDomains
23:17:06,352 root DEBUG Date : Sun, 18 Sep 2022 04:17:05 GMT
23:17:06,358 root DEBUG ========end-get========
23:17:06,434 root DEBUG ========start-post========
23:17:06,435 root DEBUG url: https://www.alarm.com/web/Default.aspx
23:17:06,447 urllib3.connectionpool DEBUG Starting new HTTPS connection (1): www.alarm.com:443
23:17:08,575 urllib3.connectionpool DEBUG https://www.alarm.com:443 "POST /web/Default.aspx HTTP/1.1" 302 151
23:17:08,605 root DEBUG Cache-Control : private
23:17:08,606 root DEBUG Content-Type : text/html; charset=utf-8
23:17:08,606 root DEBUG Location : https://www.alarm.com?m=login_fail
23:17:08,607 root DEBUG Set-Cookie : IsFromNewSite=1; expires=Thu, 17-Nov-2022 05:17:08 GMT; path=/; secure, fromASP=; expires=Sat, 17-Sep-2022 04:17:08 GMT; path=/; secure, IsFromSeamlessLogin=; expires=Sat, 17-Sep-2022 04:17:08 GMT; path=/; secure, login=; expires=Sat, 17-Sep-2022 04:17:08 GMT; path=/; secure, ST=; expires=Sat, 17-Sep-2022 04:17:08 GMT; path=/; secure
23:17:08,608 root DEBUG P3P : policyref="/w3c/p3p.xml",CP="OUR SAMa ADM UNI BUS ALL CUR DSP TAI COR IND STA"
23:17:08,609 root DEBUG Access-Control-Allow-Origin : *
23:17:08,609 root DEBUG X-Content-Type-Options : nosniff
23:17:08,610 root DEBUG Strict-Transport-Security : max-age=31536000; includeSubDomains
23:17:08,611 root DEBUG X-UA-Compatible : IE=edge
23:17:08,612 root DEBUG Date : Sun, 18 Sep 2022 04:17:08 GMT
23:17:08,613 root DEBUG ========end-post========

Looks like a POST, then a 302 redirect to alarm.com?m=login_fail? Then Iā€™m not sure

if that POST call is the last one you see, then the login is unsuccessful. you should see a request for /web/system/ if the login is successful.