Note
This repository is slightly out of date. The code here still works, but is not secure (as made clear by the clever students who saw the endpoints I published here and immediately made fake calls to them to desynchronize the status of the door). There's a better, safer solution that you can learn about here, on this blog post. Thanks!
Here's the new people counter setup! Subject to change.
We have two Aqara door/window sensors. These communicate over a protocol called Zigbee. The rpi can't interact with this protocol by default, so we have a special Zigbee sensor plugged into the pi to allow it to see these signals. No need for a propriatary hub!
The pi is running Home Assistant, which allows it to read the Zigbee signals using ZHA. Then, whenever the status of either sensor changes, it runs one of four REST commands. Becauase of how Home Assistant is currently set up, these have to be defined in its configuration.yaml
, which I've included in this repo. They're named intuitively: door1_opened
, door1_closed
, door2_opened
, and door2_closed
.
So, UWNet and eduroam both employ access point isolation such that both devices on the broader internet & local ones alike are unable to see any others on the network. (This makes sense, as anyone on the network would be able to see everyone's devices!) Because of this,web servers aren't able to directly query Home Assistant to see the status of its devices.
To work around this, I threw together a really simple Express server in the backend folder that caches any live events it receives from the pi. So, when the pi announces that door 1 has been opened, the backend will hang onto that and rebroadcast it when someone checks the status. It'll return an object in this format:
{
"status": {
"door1": "open",
"door2": "closed"
}
}
For reference, door1
is the one at the front of the UPL (that faces into the lobby), and door2
is the one at the back (that faces the balcony).
...this probably isn't the best way of doing things, as there's the extra redundancy of having a server that just repeats what the pi says. If the UPL ever gets the ability to have its LAN devices publicly accessible, this server can be removed.
(Or, we could put both the pi and the server on a Tailnet. The rpi is already on one!)
In here. Queries the endpoint and, if both doors are open, sets the name of the channel to upl-doors-open
. If either door is closed, it sets the name to upl-doors-closed
. It updates every minute.
There's a weird issue where sometimes it'll skip updating the channel name for a bit. Not sure if it's a caching issue...?
Legacy code can be found in the v1 folder.