UNIFI Controller API to Automate Repetitive Tasks


Keeping many sites consistent is the key to quality and quick network support. Ubiquiti’s software defined controller presented unique challenges when implementing and keeping up with changes. With a few thousand UNIFI devices managed a task as small as adding a new admin to every site could take hours.

I wanted to share this as my biggest issue with this project was finding examples. This is not pretty compared to my current implementation; rather this is the foundation that you can also build upon to get comfortable with using this very useful tool.

This project relies upon the Art-Of-WiFi GitHub Unifi API client project . The readme on GitHub does a great job at showing how to get started with the project and how to run your first function; because of the existing documentation I’m not going to go into detail on any setup. Rather I’m going to tackle a issue, getting regular spectrum scans from the APs. The below tears down my scanallapsfast.php it can be easily adapted and is certainly quick and dirty.

First we are going to want to initialize the API class; most of this will need done for any Unifi API project you want to create.

<?php
/**
 * Scan All APs PHP API usage example
 *
 * contributed by: Art of WiFi and Cody Deluisio
 * description: example basic PHP script to scan all aps on a controller
 */
/**
 * using the composer autoloader
 */
require_once('/home/cody/vendor/autoload.php');
/**
 * include the config file (place your credentials etc. there if not already present)
 * see the config.template.php file for an example
 */
require_once('config.php');
/**
 * Define some variables
 */
$site_id = 'default';
$allsites = array();
$uaps = array();
$usw = array();
$ugw = array();
/**
 * initialize the UniFi API connection class and log in to the controller and do our thing
 */
$unifi_connection = new UniFi_API\Client($controlleruser, $controllerpassword, $controllerurl, $site_id, $controllerversion);
$set_debug_mode   = $unifi_connection->set_debug($debug);
$loginresults     = $unifi_connection->login();

Next we are going to want to create an array of every site; this will allow us to then feed the array of every site into another function to create an array of site and device. This is necessary as site and device are required to scan an AP. Every device needs the site it is associated with for this API.

/**
 * creates array of arrays with site info
 */
foreach($unifi_connection->list_sites() as $site){
        $desc = $site->desc;
        $name = $site->name;
        $_id = $site->_id;
        $allsites[]= $name;
        }
/**
 * creates array of arrays with site and device info
 */
foreach($allsites as $value){
        $setsite = $unifi_connection->set_site($value);
        foreach($unifi_connection->list_devices() as $device){
                $mac = $device->mac;
                $model = $device->model;
                $type = $device->type;
                $sitedevices[]= array($value,$mac,$model,$type);
        }
}

At this point we have the array $sitedevices and for every single device we will have an array containing the $value = site,$mac = device mac ,$model = device model ,$type = (UAP, USW, USG, etc). From here we are going to select only UAPs. First we want to shuffle the array, otherwise you are going to hit an entire site at once and will take down every AP for 5 minutes. I wrote this so that I didn’t have to wait 5 minutes for each AP. Waiting 5 minutes per AP would mean I have almost 2 months of this script running continuously to get this scan done. Rather, I’ll live with the chance of a 2 nearby APs going down at once; with my delay I’m pretty confident in this not being the case, a bit on that later.

/*
 * Shuffle the array so that a scan doesn't constainly hit the same site
 *
 * 
 */
shuffle($sitedevices);
//uncomment the below if you want to see output of what $sitedevices looks like. It is mind racking if you stare and see no output for minutes on end
//print_r ( $sitedevices);

Now we get to the good part, we are going to start spectrum scanning aps. Our array currently has USWs, USGs, and UAPs but we only need to do spectrum scans on UAPs. We use a if UAP function to only spectrum scan UAPs.

As per the sleep function; this is the delay between scanning APs. Remember, if you don’t have many sites or devices 10 seconds is going to be way too fast; it takes an AP being out of service for 5 minutes to do a spectrum scan. The delay has to take into account total runtime, sites, and devices per site. 10 seconds worked out great for me with my sites having great overlap and most sites having 20-60 APs, coupled with a few hundred sites. If your networks have less overlap and more density I would definitely recommend thinking before you run this. There is nothing wrong with making this 5 or 10 minutes for smaller deployments.

/**
 * Set site for proper device and spectrum scan. Adjust delay to something that works for you and your deployment. Remember a spectrum scan is 5 minutes of an AP being unusable 
 */
foreach($sitedevices as $device){
        $setsite = $unifi_connection->set_site($device[0]);
        $mac = $device[1];
        $type = $device[3];
            if($type == 'uap') {
                        $uaps[] = $mac;
                      $scan = $unifi_connection->spectrum_scan($mac);
                      sleep(10);
            }
}

Well I hope you enjoyed this. It is quick and dirty, but is a great demonstration of the power and flexibility of the Unifi API. A cron job to make this run monthly and you have a constant stream of spectrum data to help you determine if any new interference is present and if the channels need changed.

Other fun things that can be done with this script are mass updates, reboots, and setting changes. With tweaks and add-ons this can be used to simplify your life in many ways. Once you begin tinkering with this you’ll find that you want to change the arrays, export to json, or maybe even change how the scanning order is selected.

If you have any comments please post below or feel free to contact me. -Cody Deluisio

I made it easier and posted it all as one below.

<?php
/**
 * Scan All APs PHP API usage example
 *
 * contributed by: Art of WiFi and Cody Deluisio
 * description: example basic PHP script to scan all aps on a controller
 */
/**
 * using the composer autoloader
 */
require_once('/home/cody/vendor/autoload.php');
/**
 * include the config file (place your credentials etc. there if not already present)
 * see the config.template.php file for an example
 */
require_once('config.php');
/**
 * Define some variables
 */
$site_id = 'default';
$allsites = array();
$uaps = array();
$usw = array();
$ugw = array();
/**
 * initialize the UniFi API connection class and log in to the controller and do our thing
 */
$unifi_connection = new UniFi_API\Client($controlleruser, $controllerpassword, $controllerurl, $site_id, $controllerversion);
$set_debug_mode   = $unifi_connection->set_debug($debug);
$loginresults     = $unifi_connection->login();
/**
 * creates array of arrays with site info
 */
foreach($unifi_connection->list_sites() as $site){
        $desc = $site->desc;
        $name = $site->name;
        $_id = $site->_id;
        $allsites[]= $name;
        }
/**
 * creates array of arrays with site and device info
 */
foreach($allsites as $value){
        $setsite = $unifi_connection->set_site($value);
        foreach($unifi_connection->list_devices() as $device){
                $mac = $device->mac;
                $model = $device->model;
                $type = $device->type;
                $sitedevices[]= array($value,$mac,$model,$type);
        }
}
/*
 * Shuffle the array so that a scan doesn't constainly hit the same site
 *
 * 
 */
shuffle($sitedevices);
//print_r ( $sitedevices);
/**
 * Set site for proper device and spectrum scan. Adjust delay to something that works for you and your deployment. Remember a spectrum scan is 5 minutes of an AP being unusable 
 */
foreach($sitedevices as $device){
        $setsite = $unifi_connection->set_site($device[0]);
        $mac = $device[1];
        $type = $device[3];
            if($type == 'uap') {
                        $uaps[] = $mac;
                      $scan = $unifi_connection->spectrum_scan($mac);
                      sleep(10);
            }
}
,