[PROJECT] Driver for Unifi Network Controllers

Just difference in approaches. I have used another community driver that you enter MAC address into top command and it creates a child device from there. I tried the Presence Check command and got confirmation the device was present and assumed it would also create a device. I neglected to notice the top MAC address preference in my hast to finally setup this functionality. So PEBCAK issue :joy:

Sounds like it. I generally think of the commands as momentary actions. Not for setting up a lasting sequence. That is what I use the preferences for. But a big plus of community drivers is that you can get a bunch of different people and a bunch of different styles. Some fit better for some usage than others. Sometimes someone stumbles across something that turns out to work really well.

2 Likes

Can I use these drivers without a Unifi controller? For example, if all that I wanted to do was to have the ability to power cycle ports on a Unifi PoE switch could the driver interface with the PoE switch directly?

No. The drivers have been designed to communicate with the API structure that the controller provides.

Personally, I do not know how one would even attempt to control the devices directly as I do not know if they even have a method exposed for doing that. Never even thought of doing it since I bought my controller to act as a router first and then built off of that slowly to my current absurdity.

1 Like

I was hoping that the switch could be controlled through SNMP. I'm just looking to automate some PoE ports and the Unifi switch is the only PoE switch I could find that could be controlled through Hubitat.

I did some looking on the Ubiquiti forum and it appears people have asked there and the answer is "no". They CAN have SNMP enabled but it is read-only without write support.

General google searches did not find anything otherwise (usually links to the Ubiquiti forum postings actually) EXCEPT for a couple versions of a PDF that mentions the capability "validated" by this other company, except it is just in a document section and I cannot find any articles or information leading up to it. The devices it actually lists models for are generally fairly old and many have been discontinued (some will still be supported for a few years at least).

The other version I found is almost identical to the one I linked, with the only difference being it lacks the Ruckus switch.

Without any real information or details otherwise, I would tend to rely on the Ubiquiti forum.

Hi @snell,
First thanks for all your great work! This i was just what I needed to control my POE switch.

But I had a few issues getting my 24p 250w POE switch to work, all other devices added correctly.

At first I couldn't add it at all but then I read the logs that parent device was trying to add it using generic driver and I found your comment inside API driver about adding using the generic driver so tried that and it worked, I then manually changed to the USW24PoE driver + changed DNI.

This seemed to work at first but then I got errors in child log as soon as I tried to do anything. Like this:

dev:831 2023-07-21 04:38:59.808 errorUS-24-250W - No MAC for USW24PoE ff:92:c2:49:2f:ac, cannot refresh.

So I started doing some more debugging and found the following two issues that I would like to report back

  1. First I found what I just think is a copy paste error on line 1306 since my 24p POE switch is reported as US24P250 and that is also what you have written in your device list. Changing this would add my Switch correctly without needing to add using generic driver first.
From:
                                    case "USL24P250": // Unifi 24 Port 250W PoE Switch (USW24PoE)
To:
                                    case "US24P250": // Unifi 24 Port 250W PoE Switch (USW24PoE)
  1. When trying to figure out the MAC error I checked my USW24PoE State Variables and could see that MAC address was missing compared to the other devices. For some reason it's not saved when child device is created. I ended up just making a quick fix driver that just sets state Variable MAC when clicking Configure button
def configure() {
    state.MAC = "ff:92:c2:49:2f:ac"
}    

After this everything seems to work fine without any errors. So now I look forward to be able to control my POE ports from Hubitat :smiley: !

Also in parent logs I got this error a few times in the beginning but not after I got everything working so not sure if its related.

dev:818 2023-07-21 02:44:54.903 [error] java.lang.NullPointerException: Cannot get property 'label' on null object on line 1858 (method ReceiveData)

Thanks, the information regarding Custom command was just what I needed, just noticed that I had to uses String for both port nr and value to get it to work

1 Like

Huh... Looks like I have a couple corrections to do. Although there are numerous models that include an l in it. So I will just add one in that does not, since it will be for the same child driver.

The failure on line 1858 was because the device did not exist properly so when it went to try to check if it had a label yet (the very first thing) it was failing. I changed a bit for that.

I should have an update posted soon as I also noticed another thing happening...

1 Like

I have been working some changes to the main driver behind the scenes, so this will be a good opportunity to include those changes for everyone. This is why the version is bumping up a couple instead of the normal increment.

Updated Version(s):

  • UnifiNetworkAPI.groovy = 0.4.40
    EDIT:
  • UnifiNetworkChild-UDMPSE.groovy = 0.1.3
  • UnifiNetworkChild-USF5P.groovy = 0.1.8
  • UnifiNetworkChild-USW16LPoE.groovy = 0.1.7
  • UnifiNetworkChild-USW16PoE.groovy = 0.1.6
  • UnifiNetworkChild-USW24PoE.groovy = 0.1.6
  • UnifiNetworkChild-USW8LPoE.groovy = 0.1.7
  • UnifiNetworkChild-USW8PoE.groovy = 0.1.6
  • UnifiNetworkChild-USW8PoE60.groovy = 0.1.3
  • UnifiNetworkChild-USW48PoE.groovy = 0.1.7

Change(s):

  • Added US24P250 recognition so that devices going forward with this internal model should be recognized properly as 24 port PoE capable switches.
  • Added additional check at beginning of device data processing when it checks for their label, to handle if device does not exist yet (this should generally not occur unless there were other errors though).
  • Added power monitoring if that data is returned for a device. This is sent to the devices as an event. EDIT: Updated child devices are now posted as well.
  • Added a bunch of additional data handling for new data that is being returned. Few of them are actually getting sent to the child devices though as most were of little apparent use.
  • It is now possible for the main driver to "force" events to child devices, so they will be flagged as changed data even if the data is not actually changed. This is more something to keep my code consistent across drivers than functional value in this driver.
1 Like

Amazing project. One issue I'm running up against, USW24PoE driver.

When I set PoE to off for a port, it sets all of the ports on that switch to the default VLAN. I have tested a few times to verify that this is happening both with the UI and Maker API.

I'm guessing that the VLAN is now a required field and in it's absence the controller is defaulting to the "Management" VLAN when it doesn't receive a VLAN in the post to the API.

I'll take a look at the code in the AM to see if I can contribute a fix, but I may not have the time.

That sounds like exactly how they do things. I will take a look at my 48 port now... They must have made an update that included that, and in many cases they consider "no data" to be a "set to default" command, which has made port stuff a joy to work with.

EDIT:
Upon review with my 48 port... Ubiquiti has substantially changed what data gets provided with a port override and have furthered the annoying method of considering any absent field as being "defaulted". Which may work for some people, but does not work for others if they have custom settings.

As an example, all of THIS is now included in a simple PoE port off request:

{"port_idx":8,"setting_preference":"auto","name":"Port 8","port_security_enabled":false,"port_security_mac_address":[],"native_networkconf_id":"639b633d4caxxxxxxxxxxxxxx","show_traffic_restriction_as_allowlist":false,"forward":"native","poe_mode":"off","port_poe":false,"lldpmed_enabled":true,"voice_networkconf_id":"","stormctrl_bcast_enabled":false,"stormctrl_bcast_rate":100,"stormctrl_mcast_enabled":false,"stormctrl_mcast_rate":100,"stormctrl_ucast_enabled":false,"stormctrl_ucast_rate":100,"egress_rate_limit_kbps_enabled":false,"autoneg":true,"isolation":false,"stp_port_mode":true,"op_mode":"switch"}

One of those fields "native_networkconf_id" is what is causing the trouble for @arlogilbert, and would for anyone else using a network configuration OTHER than their default. I have had part of the ID from mine above... but as you can see that also is not labeled something easy like "default". Instead it is the unique ID for each network (the "true name" of the default in my case).

It looks like it MAY be possible to get enough information to build it based on the device refresh, but it also appears that a lot of the information is not sent in the refresh UNTIL the controller has had a change. For example, that native_networkconf_id field is not included in ANY of my port fields (or the returned port_overrides) except for the one port I just did (#8). So apparently that is a recent addition that now gets added when a change is made.

This will require some substantial rework of the overrides (and data handling from refresh) to attempt to accommodate. I will get to work.

I wish Ubiquiti went with the more sane "if the field is not in the override, DO NOT OVERRIDE IT" model.

Updated Version(s):

  • UnifiNetworkAPI.groovy = 0.4.41

Change(s):

  • Rework of how port overrides are handled, affecting PoE port changes. Rather than just the previously "known" elements it now attempts to handle ALL override data that is provided by a refresh. There are some checks performed because of how the data is received (sending it back with no quotes around integers or booleans for example) so there is the potential for new data elements to cause trouble, but it should handle most cases.
  • Similar rework was made to outlet overrides, affecting outlet on/off methods.
  • Rework to how data is handled when there is a response to the port changes. It sends back a port table but that one does not have nearly the data included in the refresh (it drops the PoE power information for example) which was causing issues. So now it ignores everything EXCEPT the Port Overrides data returned. In addition, if a port change is sent but does not result in an actual change occurring (ex: you send port 8 to be POE Off, but POE is already off on it) then the response is basically blank INCLUDING the Port Overrides (thanks Ubiquiti...) so now it should just pop an info log about that and not change the overrides.
  • Additional data was handled since I noticed a couple new entries in my debug log since the last time I checked.
2 Likes

@snell latest update doesn't change all ports (bug fixed!), but also doesn't power cycle the port or change status of the port.

I have an issue, setting a POE override the first time works but when I try to do it again then I get this error
using: (UnifiNetworkAPI = 0.4.41 and UnifiNetworkChild-USW24PoE = 0.1.6)

dev:818 2023-07-24 23:53:24.799 errorjava.lang.NullPointerException: Cannot invoke method isNumber() on null object on line 1019 (method SetPortState)

First thought the error was related to my changes in UnifiNetworkChild-USW24PoE driver (added a command to clear "Port Overrides" State Variable) but using clean drivers I get the same problem.

@arlogilbert: No changes were made to the port power cycle... so I need to look at that. A quick test on mine showed an exception that was not being processed properly. So I need to look into that.
EDIT: A bit further checking with mine and it appears to get an error "Bad Request". I reviewed my controller directly and the Power Cycle option for my PoE ports is gone. It looks like they have removed this capability from the API.
EDIT2: I have been checking through release notes to see if this was intentional... but since I have not found anything I have now submitted a ticket asking if these feature is removed...

As for the change status... do you mean when you power off the PoE for a port, the respective Port Status state variable does not update? That is true. The response from the API does NOT provide the correct state of the port (even before I reduced what it DID update to prevent other erroneous information). The PoE Status will eventually get updated when a refresh happens (because this DOES provide the data). I am a bit torn between only relying on the "real" data provided by the API and setting it myself ASSUMING it worked properly depending on the response. I do not trigger a refresh after a command because they can take a while (depending on your controller and the hardware involved).

@Ortovox: It has to do with the information contained in the Port Overrides state variable. Can you shoot me a message with what yours has so I can make sure it is formatted properly? You should be able to perform a "Refresh" command on the child device's page to have it specifically get refreshed data (including the Port Overrides) only. It can sometimes take a bit for the API to produce the result and return it.

2 Likes

@sneed - FWIW, I'm on Early Release cycle and still see a powercycle option on PoE ports, I only see a powercycle option if the port has something plugged in.

POST request is made to: https://unifi.local/proxy/network/api/s/default/cmd/devmgr

Here is the object posted:

{
"mac": "f1:80:8b:8f:b3:61",
"port_idx": 4,
"cmd": "power-cycle"
}

But to be clear, my report above is that if I set the auto/off on a single port via the hubitat driver, it previously had the bug of setting the default for all ports. That is not happening anymore, instead, it just does nothing, there is no change on the port in the Unifi console and the PoE device connected that I want to turn off (not powercycle) never turns off.

AH. That is very different... and odd. I am on the Official Release channel and Power Cycle no longer appears for any of my devices (whether something is plugged into it or not) and Ubiquiti has come back asking for screenshots.

But my SetPortState is working properly... Can you send me a couple things in a separate message:

  1. The Port Overrides from the switch BEFORE running the command.
  2. The parameter Trace when you run the command.
  3. Any response received as a result of the command.
  4. The Port Overrides from the switch AFTER the command (unless it is the same, just tell me then).

Sorry to have you checking a bunch of stuff, but trying to hunt such things down when I cannot recreate them myself is always fun. I have to get to work but I will check this afternoon when I get home and try to see if I can find anything to fix this evening.

FYI, new Release Candidates for consoles and network application have been put out over the past couple of days.
https://community.ui.com/releases