Skip to content

Instantly share code, notes, and snippets.

@i8beef
Last active March 20, 2023 03:28
Show Gist options
  • Save i8beef/ab6386f1bb8f25c154e51df9a465eb05 to your computer and use it in GitHub Desktop.
Save i8beef/ab6386f1bb8f25c154e51df9a465eb05 to your computer and use it in GitHub Desktop.

Ubiquiti UniFi Presence Detection

Uses a UniFi node to monitor a UniFi management instance for named devices and their "Last Seen" values to determine device presence on the network.

Usage

  1. Install the node-red-contrib-unifi package.
  2. Past into a new or existing flow.
  3. Modify the UniFi node settings.
  4. Change the list of devices in the "Determine device presence" node. It maps the final MQTT topic that will be used to announce presence to the device name setup in UniFi for a client. Could be easily changed to be based on MAC address, etc., but if you name the devices in UniFi you can then later change those names without changing this flow.
[{"id":"a79a3412.95bbc8","type":"comment","z":"198805b3.d752aa","name":"Presence","info":"","x":100,"y":1420,"wires":[]},{"id":"356d290f.2adc76","type":"inject","z":"198805b3.d752aa","name":"Every 5 seconds","topic":"","payload":"","payloadType":"date","repeat":"5","crontab":"","once":false,"x":130,"y":1460,"wires":[["2fe17f39.cb2e2"]]},{"id":"2fe17f39.cb2e2","type":"Unifi","z":"198805b3.d752aa","name":"","ip":"","port":8443,"site":"default","command":"20","x":310,"y":1460,"wires":[["9c4ebd18.14827"]]},{"id":"9c4ebd18.14827","type":"function","z":"198805b3.d752aa","name":"Determine device presence","func":"const lastSeenSeconds = 20;\nlet presenceCutoff = (Math.abs(new Date()) - (lastSeenSeconds * 1000)) / 1000; \nconst people = {\n \"presence/person1\": \"Identifier1\",\n \"presence/person2\": \"Identifier2\"\n};\n\nreturn Object.keys(people).map(function(topic) {\n let devices = msg.payload.filter(device => device.name === people[topic] && device.last_seen > presenceCutoff);\n return {\n topic: topic,\n retain: true,\n payload: devices.length > 0\n };\n});","outputs":"2","noerr":0,"x":520,"y":1460,"wires":[["1d706e57.f39ea2"],["84981.f0fe567f"]],"outputLabels":["michael presence","meredith presence"]},{"id":"1d706e57.f39ea2","type":"rbe","z":"198805b3.d752aa","name":"","func":"rbe","gap":"","start":"","inout":"out","x":750,"y":1440,"wires":[["e52f02f3.7cd59"]]},{"id":"84981.f0fe567f","type":"rbe","z":"198805b3.d752aa","name":"","func":"rbe","gap":"","start":"","inout":"out","x":750,"y":1480,"wires":[["e52f02f3.7cd59"]]}]
@mondface
Copy link

i have changed it to
const lastSeenSeconds = 60;
now i have no more problems with jumping between on and off.

@i8beef
Copy link
Author

i8beef commented Dec 29, 2020

LastSeen is essentially there to be a debounce of disconnects, so a "short" blip will not trigger notifications. It needs to be balanced against "how quickly do I want to know about a disconnect?". Reconnect notifications would still be immediate, but it wouldn't consider a "missing" device as "disconnected" until that buffer has elapsed.

@sparky-Ol
Copy link

Hi,
i can connect to my UDM (green indicator and OK) via unifi node but the array i receive is empty : payload: array[0].
In the unifi node i changed my sitename, entered my credentials and selected Command: ClientDevices.
What might went wrong?

@quadhammer
Copy link

I'm not at my computer to check, but from memory the array thing had to be expanded, and perhaps you need to use a complete message object debug note, rather than just the message.payload one. Apologies if this is obvious, and you have already tried it.

@i8beef
Copy link
Author

i8beef commented Jan 23, 2021

Sorry, no idea off hand. If the message payload coming out of that is empty it sounds like theres something not right in your node setup, or something. might want to ask on the UniFi node's Github or something and see if they know.

@quadhammer
Copy link

The node-red-contrib-unifi package has stopped working for me too, so it's probably the culprit here.

@groenerik
Copy link

Thank you very much for this code!

To get it working here with Unifi Application: Network 7.2.97 and node-red v3.0.2 I needed to make two changes.

To remove a code verification error I changed the second line to :
let presenceCutoff = (Date.now() - (lastSeenSeconds * 1000)) / 1000;
new Date() appears to return an object in stead of a number.

Then during executing I got an error message and no results.
"TypeError: msg.payload[0].filter is not a function"

I could resolve it bij removing the [0] index from msg.payload[0].filter.
let devices = msg.payload.filter(device => device.name === people[topic]);

Apparently the structure of the Unifi output has changed over time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment