The more you dabble with home automation, the more you realize how nice it would be to be able to keep track of when members of the household come and go. Things like automatically turning on a few lights when you come home late, or knowing that your kids got home from school alright.
Aiming for something practically usable rules out stuff like face recognition etc. One obvious choice is using wifi to track the presence of people's phones. There are a bunch attempts at generic solutions that don't rely on specific hardware, but unfortunately they do not work very well. Most of them rely on using ping or arping to see if the phone responds, but devices work very differently. For instance, when an iPhone's wifi goes into power save mode it stops responding to ping and arping.
Leaving generic for proprietary
Having almost ruled out this method of presence detection, I suddenly realized my Unifi access points keep track of all connected devices on a much lower level that is active even in power save. The next step was discovering that the Unifi Controller software has a REST API.
Mucking around with the Unifi Controller web ui while spying on the API calls quickly revealed that you only need two routes to check presence of wifi devices - login and sta (for statistics). There are a bunch of open source packages for the Unifi Controller API for all kinds of languages and frameworks, but I wanted to keep my solutions simple so I made something custom for the two routes.
What actually happens
The detection process is run with cron and basically does this:
- Request to log in to the Unifi controller - save the cookies returned.
- Request to get all connected devices.
- Filter out interesting devices and check how long since they were last seen.
- Update virtual switches in Domoticz based on which phones are present or not (see upcoming blog post on how to configure that)
API request to log in
To log in to the controller, make a POST request to this url:
The payload is in JSON as follows:
Returned in the header Cookies are the tokens needed for subsequent requests:
API request to get devices
To get devices, make a GET request to:
Returned is a JSON array with a lot of properties for each device.
I'm not going to go into details (you can spy on them in dev tools in your favorite browser when accessing the controller web ui). I'm just focusing on these two:
- mac - device mac
- last_seen - time stamp when device was last seen
Installing the Unifi controller on Ubuntu
I was previously running the Unifi controller on my MAC as I needed it. But that obviously won't work for continuous presence detection, so I put it on one of my Ubuntu servers.
There are ready-made packages to install the controller on Ubuntu. They work very well, with one exception: you can't set custom port numbers until you run the controller once successfully. The settings file (/usr/lib/unifi/data/system.properties) isn't created until the first start, and the controller won't start if its default ports are in use. So... clear ports 8080, 8088, 8443, 8843 before starting. Then change the ports and restart the controller.
Comments and reflections - next steps
The presence detection isn't SUPER snappy, it take a couple of minutes for the controller to realize a phone is gone, although it is usually quick to recognize that one has reconnected. I'm running my detection with cron which means checks no more than once a minute. You could probably up the interval with an internal scheduler in the code.
The controller actually keeps track of which access point a device is connected to, so if you have multiple you could probably concoct some kind of "where in the house"-detection as well. I expect that to be quite fuzzy though.
Can I run your code?
Absolutely! The package with installation instructions is on NPM https://www.npmjs.com/package/unifi-detect and the code is on GitHub https://github.com/osirisguitar/unifi-detect. Install, run, modify as you'd like.
What is Domoticz? Do I need it?
Domoticz is a home automation platform. You definitely do not need it to do presence detection with Unifi. However, you'll have to adapt the code yourself to whatever application you want to use it for. Source code is here: https://github.com/osirisguitar/unifi-detect