[PROJECT] Driver for Unifi Network Controllers

This is a parent/child set of drivers in order to read data from your Unifi controller (originally based around my Unifi Dream Machine Pro but now expanded to other Unifi controllers) and provide information that may be useful to your Hubitat as well as some level of control over the devices. Like most of my drivers this will be a perpetual project and I am always open to feedback.

On to the good stuff, the drivers themselves.

If you want to do presence detection you must also have:

If you want to do hourly client checks you must also have:

If you want to use the Unifi Children feature (where each Unifi device becomes a separate child, enabling more features) then you need drivers for whichever devices you might have (you can load them all if you want):

Features:

  • Can create a child device for EACH Unifi Device the controller has, allowing additional features and data to be represented within each by enabling "Show Unifi Devices as Children?" feature on the parent device.
  • Can show all the active (non-archived) alarms present for the controller as well as Archive the alarms.
  • Can manually check for whether a MAC address exists in the controller's database and will produce an Event stating the result.
  • Can manually check for whether a MAC address is currently online and will produce an Event stating the result.
  • Can manually check the current status of the controller and will post events showing the "health" of the major areas (for example: wlan, www, wan, vpn, lan).
  • Can manually Refresh the overall status of the controller. Showing data such as how many clients have ever connected and how many are currently online as well as how many Unifi devices are connected to the controller.
  • Can be set to regularly perform a Refresh and get other general stat information for the controller.
  • Can be set to regularly poll whether particular MAC addresses are online. This can be used as a form of presence sensor as these will create child devices that will label as present (or not) if online (or not). Example: My smartphone is checked. If it is on the network then it must be home (and therefore I should be as well). Currently it is fixed that if you have <= 5 MACs being checked it will check all 5 each minute (spread across the minute to not cause excessive load). If you have <= 10 MAC addresses it will be performed every other minute. >10 MAC addresses is not currently allowed.
  • Can perform hourly client checks against up to 20 client devices to determine if they are online/offline as well as various connection-related data for them. Related to the Presence check but it will only check each device once per hour and uses a different child and driver. This is meant more for keeping a general check on important (but not critical) network connected devices.
  • At a fixed interval (1 hour) it will perform a login to the controller in order to keep the authentication cookie accurate.
  • Can perform a Hubitat-based Ping command against a specific IP. This requires Hubitat version 2.2.7 (or higher) and is not run via the Unifi controller.
  • Unifi devices listed as children can be removed as desired. If the Unifi Children "Show Unifi Devices as Children?" feature is still enabled they will be recreated automatically on the next daily check. If the feature is disabled all of the Unifi device children will be automatically removed (Presence children are not affected).
  • Can control Port PoE states, set Etherlighting on ports, and other switch-specific commands...
  • All are listed within Hubitat Package Manager (HPM).

Major Feature(s) Missing:

  • Changing network profiles or such are not planned to be incorporated. These require IDs that are contained in the API and are a long alphanumeric string (not the easy to use name) and thus cannot be readily presented to a user to select from in a reasonable way (like the web interface provides).

Setup:

  1. Add UnifiNetworkAPI.groovy driver to your Drivers Code section on your Hubitat (you can Import using the URLs above) then Save the driver.
  2. Add a Virtual device and set the Type to be UnifiNetworkAPI (user-added drivers are going to be at the bottom of the list), then Save Device.
  3. Enter your Unifi Controller's IP/Hostname, Username, and Password into their respective fields in Preferences, select your Unifi controller type, then Save Preferences.
    REQUIRED: If you use a Controller Type of "Other Unifi Controllers" go back to the Preferences after you save. There should now be a field showing Controller Port # that is required. This defaults to the typical 8443 but newer Controller versions may be using 443.
    REQUIRED: This driver is designed for use with a local admin account. It does not work with Ubiquiti cloud or 2FA accounts. Just create a separate local account on your controller.
    OPTIONAL: Add any child drivers in using the same method as step 1. Technically they are all optional if you do not use presence detection, client check, or the Unifi Children feature.
    OPTIONAL: If you use a site different than the default (most people see "Default") then enter the site in the Override Default Site field.

Extra:

  • I am always willing to add more device support or features. If you have a Ubiquiti Unifi device that does not already have a child driver above, please reach out! The minimum I need is the Model (not what Ubiquiti provides, but what is used by the API) which can be found in the child device's State Variables list. You should be able to use the generic "UnifiNetworkChild.groovy" driver for any unknown device just for the basics. Having the Model will let me identify the device in the API data and at least create a new child driver and send the data to it.
  • If a child device is lacking some major feature you want and you can do with the Network API on your local Unifi Controller, let me know. If you are willing to help provide some samples I can usually work out a way to add it.

Enjoy checking out the features!

13 Likes

This looks great. Any idea as to compatibility with the standard Dream Machine? I have the non pro version.

This is great! Checking it out now, will send more feeback once ive used a bit more.

As far as the stats for the UDMP, Could you include some of the below fields into the states on the parent? Would be great if we could automate rules for high CPU, low speed, etc. Im also wondering if I can take my WAN IP to automate my DDNS which seems to be broken in Unifi OS right now.

Summary
    "health":[
        {
           "subsystem":"wlan",
           "num_user":12,
           "num_guest":3,
        },
        {
           "subsystem":"wan",
           "wan_ip":"XX.XXX.XXX.X",
           "gw_mac":"XXX",
           "gw_name":"UDMP",
           "gw_system-stats":{
              "cpu":"13.9",
              "mem":"48.8",
              "uptime":"1239014"
           },
           "gw_version":"1.8.3-2.2939",
           "isp_name":"Comcast Cable",
           "isp_organization":"COMCAST-7922",
           "uptime_stats":{
              "WAN":{
                 "availability":100.0,
                 "latency_average":25,
              }
           }
        },
        {
           "subsystem":"www",
           "status":"ok",
           "latency":35,
           "xput_up":24.006,
           "xput_down":341.197,
           "speedtest_status":"Success",
           "speedtest_lastrun":1607366189,
           "speedtest_ping":22,
        },

Secondly, I know you have a limit of 10 Macs. Rather than add them delimited in preferences, or add limits, can you have them added by the parent field when you check presence by MAC. By default, have it poll every hour or something and on each device, you can change to check more often. Like i check ethernet devices every 10 minutes, but i check wifi every 1minute.

Third, If i keep the parent device open, it keeps getting a new additional attribute state showing up saying "Last Presence Check XXXX" Eventually this slows down the page. Can you just update this attribute on the child device?

I just had the idea yesterday to get my Unifi into grafana. Right now, i have pushover telling me when the three phone in my house change access points. My sister (who lives in the guest house) has asked for her dehumidifier to be shut off when she's in there, but on when she's elsewhere in our main house. So far, our phones seem pretty good at roaming to the closest AP, but I'm verifying every change of AP connections.

I do not have a UDM... but from the initial stuff I looked at it would not work with one at present due to a slightly different structure.

But I could look at incorporating it if people here are willing to try it out and let me know if it works.

Sure, it should be possible to add additional attributes in. I will put those on the list.

Not exactly sure what you mean about the MACs. You can search for particular ones using the command but it will not add to the queue of ones to check regularly. I am not sure if the 10 MAC limit I put in place is good or not overall (it is arbitrary at the moment). I just did it because I did not want to be overloading the UDMP (no idea what it would take to do that though). I also did not think most people could need to check more than 10 unique devices.

You have a second part to that though that I do understand a bit better, checking frequency based on device connection type. That would be tough to do... maybe. I think what I could do is see if the UDMP reports their connection type the first time it checks specific MACs. Then it could set a check schedule based on that... Have to put some more thought into it. I could also add a field on child devices that would set their own refresh rate for preferences as an alternative.

For the third... I am not sure why it is doing that to be honest. It happens on mine also. It is an attribute in the parent as well so it SHOULD just replace the existing one. Refreshing the page gets rid of the extras but I am not sure why it is happening anyways. Some events seem to do this and some do not and I am not sure why yet.

Okay awesome! Just wanted to make you aware. I mean you could add a command with a variable that is called AddMac or something instead of the preferences where its delimited. I deleted the string where it shows all the macs that its polling and the devices stayed. Just thought it might be easier to do one at a time through a command button.

Also it might be wise to separate out the system info from device count polling options. When i ran in debug, it brought back a lot of data for all my devices which was great, but i want System health every minute, but don't need the firehose of device data as often. Just a thought. Might be more impactful for bigger networks.

I will install in the current form and see what works. I'm running a beta firmware on my udm that supposedly is the same for the udm pro, so perhaps I will have success.

1 Like

Good ideas! Looks like I have a lot of work to do.
:smile:

I've installed and tested, and the main functions appear to be working. I get a token and login seems to be successful, and health stats report ok. However I never get a child device created for presence. I'm assuming that's because the driver only creates the child device after it has successfully polled the first time?? Does it matter what format you enter the mac address in? I've tried with and without colons, xx:xx, etc. with no change. I can see in the logs where it says a child device was created at some point, but if I click on the device link in the log entry, then I get a 404 not found. I have debug logging turned on, but I'm not sure of another way to get more info about the error if it is possible. I'm happy to provide whatever else might be helpful if you can tell me where/how.


image

1 Like

USG support??? Cloud key?

1 Like

@scottie.holden:

  • Good to know the UDM works like the UDMP.
  • The format of the "MAC Address(s) to Presence Check" field is along the lines of 12:34:56:78:90:ab;12:34:56:78:90:ac
  • You are correct, it only creates children when there is a successful response from the UDMP with the child's presence. I think the Request Timeout can also correspond to the UDMP not finding that child (so maybe the MAC was incorrect). But it COULD occur for other reasons (maybe not the most likely though) so I will have to change the log message. I probably have to build more logging into that section entirely from the looks of it to help identify possible issues.

@Bago:
This falls into the area that is not yet supported, the "older-style" API structure (since I only have a UDMP that is what I made this based around). I think it goes to a different port AND has some different path structures. There appears to be enough interest though so I will be trying to add the capability in.

2 Likes

+1 for adding USG support :slightly_smiling_face:.

1 Like

Did you use this (or similar) as a reference? I wonder how correct and up-to-date it is.

I'm going to be setting up my Unifi stuff this week, using a non-UDM/P controller, and I'm wondering how similar the APIs actually are. It looks pretty minimal in terms of path differences, but I haven't even begun to poke at it.

https://ubntwiki.com/products/software/unifi-controller/api

Updated Version(s):

  • UnifiAPI.groovy = 0.1.1

Change(s):

  • Attempt at supporting Unifi Controllers other than the UDM and UDMP. Select your Controller Type in Preferences and Save... I cannot test this but I tried to match it up with what I could find online. Default type is UDM.
  • Changes to Refresh. Now it only polls the current state information of the controller, which determines # of online devices, # of Unifi devices, "health" of the various interfaces as returned by the controller (note: VPN reports "unknown" if it is not configured), as well as the CPU usage, memory usage, and the uptime in days, hours, and minutes.
  • DailyCheck now handles a once-a-day check for any driver updates and the total number of clients the controller has ever seen.
  • Refresh Rate has been changed in Preferences to "Controller Stats Refresh Rate" to help make it more clear about what it will actually be getting since it has no impact on the Presence checking. That is still it's own separate 1 or 2 minute interval based on the number of MAC addresses it is checking.
  • Changed the logging for when a Request Timeout occurs to show the MAC it is trying but still not sure WHY it is occurring for @scottie.holden (I could not replicate it). Maybe it is some odd difference for UDM vs UDMP?

Known Issue(s):

  • My UDMP appears to "forget" some wifi devices at times. I am not sure why but in testing this evening my phone (and my wife's) were mostly "Not present" which is absolutely untrue. I thought I had broken the driver. But when I checked the UDMP itself it insisted that both of our smartphones were offline (despite both showing wifi and browsing the internet just fine). Not sure what the UDMP is doing... maybe this is a software bug that has happened in a more recent update since I originally starting using this capability (since it always seemed to work fine before). So PLEASE... before you start yelling at me that presence checking does not work, double check that the MAC address(es) in question are actually considered connected by the controller at that time.

Different Topic(s):

  • No changes to the way Presence Checks are performed at this time. While I have a better idea of what @ajones was talking about now I am still not decided on implementation so no changes were made in the "published" version.
1 Like

Thanks for the quick update! No change in presence detection for me. I'm still not getting a child driver on my UDM. I'm using a wired desktop PC as the target for testing. My UDM reports this device has been connected for 75 days with a "100% experience". It seems that maybe there is a slight difference in how the UDM handles the request, or needs it formatted. I wouldn't know how to discover the difference unfortunately.

I have a UDM and would be willing to test. This is an awesome project.

1 Like

+1

@scottie.holden:
Well, thanks for the quick notice. I do not see any issue at all with the way that MAC is formatted. I will try to do some digging and see if I can find anything that indicates a difference. It would be a real pain if UDMs do have some slight differences in the API from UDMPs but should be workable.

@richard.shutes:
If you could try it with your UDM... we can see if it gets the same result or not. Thanks for offering to help!

This looks potentially interesting: GitHub - oznu/unifi-events: A Node.js module to listen for events from a UniFi Controller.

It seems that there are webhooks for connect/disconnect events as well as AP handoffs.

@tomw:
Hubitat is designed around a request/receive model for HTTP (you make a request and then receive the response) with the exception being the 39501 port. So it is generally difficult, if not impossible, for it to deal with "unsolicited" information.

@scottie.holden:
Can you try connecting to your UDM with the Controller Type set to "Other Unifi Controllers"? A lot of the stuff I am seeing keeps saying that the "different" URLs and port are for the UDMP. The do not mention the UDM... so I wonder if that is more meant to be like the others?