Closed jokakilla closed 1 year ago
Hi guys, I use the unifi plugin for some month without any issues for presence detection. Thanks by the way 🙂.
But as the number of devices on my unifi system is constantly rising it would make sense to request only information about the presence relevant device instead of fetching and parsing a huge blob of data.
It would be nice if you could check and integrate my proposal.
Hi jokakilla, would you mind to share your current flow to check presence status? I have the same need to get this information out of my UDM. Thanks a lot. Andreas
Hi @pluto202, I can't give you the flow right now as I've changed my local implementation with the changes from this pull request. But basically I have an inject node the is triggering every minute the Unifi node with command "ClientDevices" The result is processed by a function node:
var myPhoneMac= "d4:d7:cf:xx:xx:xx";
var myWifesPhoneMac = "b8:3b:cc:xx:xx:xx";
for (var device of msg.payload) {
if(device.mac == myPhoneMac || device.mac == myWifesPhoneMac) {
msg.payload = true;
return msg;
}
}
msg.payload = false;
return msg;
The unifi node returns an array of devices. When a device leaves the wifi it disappears from the array. With the proposed change I can request the info for every single device and don't have to iterate over an array of 50 devices.
I've tested this by letting my inject node set the payload to {"client_mac": "d4:d7:cf:xx:xx:xx"}
When the device is connected an array of size 1 is returned with all the information. If not the payload is only the payload injected to the node.
This way I can simply check for presence of the device by:
msg.payload.length == 1
PS: Still dreaming of Unifi implementing an event based interface like MQTT for such stuff so I could subscribe to the presence topic of a certain device and instantly get notified about state changes. ;) One more hint: On Android I had to turn off the privacy feature for my Wifi that generates random mac addresses.
Hello. Thanks for that. Sure, I will implement this, I need to make some more changes to the documentation and so on but I will do this right now
@jokakilla just out of curiosity: 1) do the phones disappear from wifi in standby mode? (iphone/android different behavior?)
2) instead of waiting for MQTT maybe the log could be parsed for notice of appearance/dissappearence of spedific devices?
This is now implemented in version 0.2.12 the command changed to { command: "clientDevices", mac: "device MAC address" }
PS: Still dreaming of Unifi implementing an event based interface like MQTT
I am working on solution that will listen for events, but I need to make it solid before I could release it.
@ozett on different Android devices (Xiaomi, Realme) with android 9 to 12 it has been working reliable for me in every situation. When leaving the house it sometimes takes a bit. Unfortunately I don't have any apple devices around. I guess many variables can have an impact on reliability:
In first place I expected that the device stays in the array and the disconnect_timestamp field to be updated. My idea was to check if the last_seen timestamp is after the disconnect_timestamp. But it turned out the device completely disappears from the data.
@Isaksson out of curiosity: How are you planing to implement the event solution? I always thought the Unifi API only allows polling.
@jokakilla and @ozett seems to be working with Apple devices as well with the code above. Still on Version 0.2.11
i dont really like the idea of 1 minute polling information from the controller .
but you encouraged me to take the other road and see if i can catch the same events from the syslog with node-red
@Isaksson out of curiosity: How are you planing to implement the event solution? I always thought the Unifi API only allows polling.
It will be through websocket and listen to events.
The only issue with polling 1 time / minute is that in worst case you will miss the event by 59 seconds, there will be no impact on the controller by polling the system.
The is always a delay from Unifi when a client is disconnected, connected is almost always instant. That is how the system works and same result in the GUI.
But it seems like you all need the new feature, so maybe I should speed up the development of that new feature.
love to see doing it with MQTT, (like most other things already on my node-red)
but in a qucik test it works also pretty as push with syslog.
filtering on hostapd and dis/association
does the job.
(random MAC must OFF, as it looks like unify controller allows to name the device even with random-mac, but i dont how how to filter on the name)
syslog |
---|
node-red module syslog2 |
[{"id":"9981a256474fb492","type":"syslog-input2","z":"eb151a75.f4dc58","name":"syslog","socktype":"udp","address":"192.168.14.204","port":20514,"topic":"","x":220,"y":290,"wires":[["b6953ed501f637cd"]]},{"id":"b6953ed501f637cd","type":"switch","z":"eb151a75.f4dc58","name":"","property":"payload.msg","propertyType":"msg","rules":[{"t":"nnull"}],"checkall":"true","repair":false,"outputs":1,"x":370,"y":290,"wires":[["12924ecc4052d788","7c23129a64d8831b","d43816d196f86954"]]},{"id":"7c23129a64d8831b","type":"switch","z":"eb151a75.f4dc58","name":"hostapd","property":"payload.msg","propertyType":"msg","rules":[{"t":"cont","v":"hostapd","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":540,"y":360,"wires":[["d3d2ad246a71a69e","1ab3ee5fd3152fc2"]]},{"id":"1ab3ee5fd3152fc2","type":"switch","z":"eb151a75.f4dc58","name":"associated","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"associated","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":720,"y":420,"wires":[["7097022755886567"]]},{"id":"7097022755886567","type":"debug","z":"eb151a75.f4dc58","name":"associated","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload.msg","statusType":"jsonata","x":920,"y":420,"wires":[]}]
Well, that's one of the strength with Node-red is that you could fetch data from many different protocol's but handle them the same in your flow. You could fetch a JSON string from MQTT or from Websocket or even HTTP scrape, but in your flows you could just handle them the same, that's very nice. MQTT from Unifi seems unlikely but who knows.
I have also strong doubt that Unifi will implement MQTT. But connecting via websocket from an unifi node to the Unifi controller sounds very promising to me. Hope I got the idea right. The unifi node would trigger as soon as certain events from the websocket connection happen?!
@ozett does the syslog solution cause a lot of network traffic between the unifi controller and node-red?
I have also strong doubt that Unifi will implement MQTT. But connecting via websocket from an unifi node to the Unifi controller sounds very promising to me. Hope I got the idea right. The unifi node would trigger as soon as certain events from the websocket connection happen?!
Yes, that's correct. It's like a subscription so you subscribe on events and as soon that events happens then the node will output the result.
@ozett does the syslog solution cause a lot of network traffic between the unifi controller and node-red?
dont know how to measure that, but i would say "no". i aggregate lots of appliances into one syslog and its UDP and all data is compressed at the end. no problem. no network load ever recognized, only over the time i have some data collections on the disks.
in case of node red, i would say: if you filter and dont store: no data collection, no real measurable network load. as far as i googled it, nobody seems to be afraid of network overloading.. save to try, i would say
you could try to make presense-detection with athome/away
with a trigger node. like HAS is doing it.
work like this : if no more lifesign from the reset line, than the trigger times out after 15 minutes of devices wifi is "disassociated".
screenshot |
---|
Thanks once again for quickly integrating the change :) Maybe I'll try the syslog solution or wait for the websocket event based stuff.
But meanwhile simply getting only the relevant devices has reduced cpu load on the RaspberryPi3 that is running the Unifi controller
The internal getClientDevices method already allows to get information only for a certain device by setting the optional client_mac parameter. Adding the message payload client_mac parameter to the method call allows to get device info just for a single device.
If the msg.payload does not contain client_mac the internal undefined check should handle that by setting an empty string.