Skip to content

Commit

Permalink
API client class v1.1.58
Browse files Browse the repository at this point in the history
- changed several references from UniFi SDN controller to UniFi Network controller
- added optional payload parameter to the list_alarms() method/function, contributed by @MikeSiekkinen through PR #68
- added example showing how to disable/enable a UniFi switch port
- updated restart_device() function/method, thanks go to @leonardogyn for reporting this
- added example to modify outlet settings on a UniFi SmartPower PDU Pro, thanks go to @panthergm for providing access
  • Loading branch information
malle-pietje committed Oct 22, 2020
1 parent 69b43df commit d26cba1
Show file tree
Hide file tree
Showing 4 changed files with 210 additions and 38 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## UniFi Controller API client class

A PHP class that provides access to Ubiquiti's [**UniFi SDN Controller**](https://unifi-sdn.ui.com/) API, versions 4.X.X and 5.X.X of the UniFi SDN Controller software are supported (version 5.12.72 has been confirmed to work) as well as UbiOS-based controllers (version 5.12.59 has been confirmed to work). This class is used by our API browser tool which can be found [here](https://github.com/Art-of-WiFi/UniFi-API-browser).
A PHP class that provides access to Ubiquiti's [**UniFi Network Controller**](https://unifi-network.ui.com/) API, versions 4.X.X and 5.X.X of the UniFi Network Controller software are supported (version 5.12.72 has been confirmed to work) as well as UbiOS-based controllers (version 5.12.59 has been confirmed to work). This class is used by our API browser tool which can be found [here](https://github.com/Art-of-WiFi/UniFi-API-browser).

The package can be installed manually or using composer/[packagist](https://packagist.org/packages/art-of-wifi/unifi-api-client) for easy inclusion in your projects.

Expand Down Expand Up @@ -92,7 +92,7 @@ Please refer to the `examples/` directory for some more detailed examples which

#### IMPORTANT NOTES:

1. In the above example, `$site_id` is the short site "name" (usually 8 characters long) that is visible in the URL when managing the site in the UniFi SDN Controller. For example with this URL:
1. In the above example, `$site_id` is the short site "name" (usually 8 characters long) that is visible in the URL when managing the site in the UniFi Network Controller. For example with this URL:

`https://<controller IP address or FQDN>:8443/manage/site/jl3z2shm/dashboard`

Expand Down
78 changes: 78 additions & 0 deletions examples/disable_switch_port.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php
/**
* PHP API usage example
*
* contributed by: Art of WiFi
* description: example PHP script to disable/enable the port of a UniFi switch
* note: Requires controller version 5.5.X or higher. This example assumes an override alreay exists for the desired port.
* To create a new port override simply append one (similar in structure to $updated_override) as needed to the
* $existing_overrides array
*/

/**
* using the composer autoloader
*/
require_once('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');

/**
* the site to use to log in to the controller
*/
$site_id = '<enter your site id here>';

/**
* the MAC address of the UniFi switch to re-configure
*/
$device_mac = '<enter MAC address>';

/**
* index of port to modify/add
*/
$port_idx = 24;

/**
* port configuration id to apply when enabling/disabling the port
*
* NOTE:
* port configurations are available through list_portconf()
*/
$port_conf_id = '<enter _id value of desired port configuration>';

/**
* 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, false);
$set_debug_mode = $unifi_connection->set_debug($debug);
$loginresults = $unifi_connection->login();
$data = $unifi_connection->list_devices($device_mac);
$device_id = $data[0]->device_id;
$existing_overrides = $data[0]->port_overrides;

foreach ($existing_overrides as $key => $value) {
if (!empty($value->port_idx) && $value->port_idx === $port_idx) {
$updated_override = [
'portconf_id' => $port_conf_id,
'port_idx' => $port_idx,
'poe_mode' => $value->poe_mode,
'name' => 'Your-port-name',
];

$existing_overrides[$key] = $updated_override;
}
}

$payload = [
'port_overrides' => $existing_overrides
];

$update_device = $unifi_connection->set_device_settings_base($device_id, $payload);

/**
* provide feedback in json format
*/
echo json_encode($update_device, JSON_PRETTY_PRINT);
84 changes: 84 additions & 0 deletions examples/modify_smartpower_pdu_outlet.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php
/**
* PHP API usage example
*
* contributed by: Art of WiFi
* description: example basic PHP script to toggle power of an outlet on the UniFi SmartPower PDU Pro,
* last tested with UniFi controller version 6.1.19
*/
require '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');

/**
* the site to use
*/
$site_id = 'default';

/**
* MAC of UniFi SmartPower PDU Pro to work with
*/
$pdu_mac = '<MAC ADDRESS of PDU>';

/**
* index value of the outlet to modify
*/
$outlet_idx = 20;

/**
* new values for relay_state (enable/disable Power) and cycle_enabled (disable/enable Modem Power Cycle) for the above outlet,
* values must be boolean (true/false)
*
* NOTES:
* - here you can choose to also change the name of the outlet
* - outlet overrides are structured like this:
* {
* "index": 1,
* "name": "USB Outlet 1",
* "cycle_enabled": false,
* "relay_state": true
* }
*/
$new_relay_state = true;
$new_cycle_enabled = false;

/**
* 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();
if ($loginresults) {
$pdu_details = $unifi_connection->list_devices($pdu_mac);

if (!empty($pdu_details) && property_exists($pdu_details[0], 'model') && $pdu_details[0]->model === 'USPPDUP' && property_exists($pdu_details[0], 'outlet_overrides')) {
$device_id = $pdu_details[0]->_id;
$outlet_overrides = $pdu_details[0]->outlet_overrides;

foreach ($outlet_overrides as $key => $value) {
if ($value->index === $outlet_idx) {
$outlet_overrides[$key]->relay_state = $new_relay_state;
$outlet_overrides[$key]->cycle_enabled = $new_cycle_enabled;
}
}

$pdu_update = $unifi_connection->set_device_settings_base($device_id, ['outlet_overrides' => $outlet_overrides]);

/**
* provide feedback in json format
*/
echo 'results:' . PHP_EOL . PHP_EOL;
echo json_encode($pdu_update, JSON_PRETTY_PRINT);
echo PHP_EOL;
} else {
echo 'not a PDU device?';
echo PHP_EOL;
}
} else {
echo 'we encountered a login error!';
echo PHP_EOL;
}
82 changes: 46 additions & 36 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class Client
protected $is_loggedin = false;
protected $is_unifi_os = false;
protected $exec_retries = 0;
protected $class_version = '1.1.57';
protected $class_version = '1.1.58';
private $cookies = '';
private $request_type = 'GET';
private $request_types_allowed = ['GET', 'POST', 'PUT', 'DELETE'];
Expand Down Expand Up @@ -131,7 +131,10 @@ public function login()
* first we check whether we have a "regular" controller or one based on UniFi OS,
* prepare cURL and options
*/
$ch = $this->get_curl_resource();
if (!($ch = $this->get_curl_resource())) {
return false;
}

$curl_options = [
CURLOPT_HEADER => true,
CURLOPT_POST => true,
Expand All @@ -157,16 +160,17 @@ public function login()
$curl_options = [
CURLOPT_NOBODY => false,
CURLOPT_POSTFIELDS => json_encode(['username' => $this->user, 'password' => $this->password]),
CURLOPT_HTTPHEADER => ['content-type: application/json; charset=utf-8']
CURLOPT_HTTPHEADER => ['content-type: application/json; charset=utf-8'],
CURLOPT_REFERER => $this->baseurl . '/login',
CURLOPT_URL => $this->baseurl . '/api/login'
];

/**
* specific to UniFi OS-based controllers
*/
if ($http_code === 200) {
$this->is_unifi_os = true;
$curl_options[CURLOPT_REFERER] = $this->baseurl . '/login';
$curl_options[CURLOPT_URL] = $this->baseurl . '/api/auth/login';
} else {
$curl_options[CURLOPT_REFERER] = $this->baseurl . '/login';
$curl_options[CURLOPT_URL] = $this->baseurl . '/api/login';
$this->is_unifi_os = true;
$curl_options[CURLOPT_URL] = $this->baseurl . '/api/auth/login';
}

curl_setopt_array($ch, $curl_options);
Expand Down Expand Up @@ -212,7 +216,7 @@ public function login()
*/
if ($http_code >= 200 && $http_code < 400 && !empty($body)) {
preg_match_all('|Set-Cookie: (.*);|Ui', $headers, $results);
if (isset($results[1])) {
if (array_key_exists(1, $results)) {
$this->cookies = implode(';', $results[1]);

/**
Expand Down Expand Up @@ -244,7 +248,10 @@ public function logout()
/**
* prepare cURL and options
*/
$ch = $this->get_curl_resource();
if (!($ch = $this->get_curl_resource())) {
return false;
}

$curl_options = [
CURLOPT_HEADER => true,
CURLOPT_POST => true
Expand Down Expand Up @@ -309,19 +316,19 @@ public function authorize_guest($mac, $minutes, $up = null, $down = null, $MByte
/**
* if we have received values for up/down/MBytes/ap_mac we append them to the payload array to be submitted
*/
if (!empty($up)) {
if (!is_null($up)) {
$payload['up'] = intval($up);
}

if (!empty($down)) {
if (!is_null($down)) {
$payload['down'] = intval($down);
}

if (!empty($MBytes)) {
if (!is_null($MBytes)) {
$payload['bytes'] = intval($MBytes);
}

if (isset($ap_mac)) {
if (!is_null($ap_mac)) {
$payload['ap_mac'] = strtolower($ap_mac);
}

Expand Down Expand Up @@ -1661,7 +1668,7 @@ public function stat_payment($within = null)
public function create_hotspotop($name, $x_password, $note = null)
{
$payload = ['name' => $name, 'x_password' => $x_password];
if (isset($note)) {
if (!is_null($note)) {
$payload['note'] = trim($note);
}

Expand Down Expand Up @@ -1709,19 +1716,19 @@ public function create_voucher(
'quota' => intval($quota)
];

if (isset($note)) {
if (!is_null($note)) {
$payload['note'] = trim($note);
}

if (!empty($up)) {
if (!is_null($up)) {
$payload['up'] = intval($up);
}

if (!empty($down)) {
if (!is_null($down)) {
$payload['down'] = intval($down);
}

if (!empty($MBytes)) {
if (!is_null($MBytes)) {
$payload['bytes'] = intval($MBytes);
}

Expand Down Expand Up @@ -1791,7 +1798,7 @@ public function list_dpi_stats_filtered($type = 'by_cat', $cat_filter = null)

$payload = ['type' => $type];

if ($cat_filter !== null && $type == 'by_app' && is_array($cat_filter)) {
if (!is_null($cat_filter) && $type == 'by_app' && is_array($cat_filter)) {
$payload['cats'] = $cat_filter;
}

Expand Down Expand Up @@ -1879,18 +1886,18 @@ public function adopt_device($mac)
* Reboot a device
* ----------------------
* return true on success
* required parameter <mac> = device MAC address
* optional parameter <type> = string; two options: 'soft' or 'hard', defaults to soft
* soft can be used for all devices, requests a plain restart of that device
* hard is special for PoE switches and besides the restart also requests a
* power cycle on all PoE capable ports. Keep in mind that a 'hard' reboot
* does *NOT* trigger a factory-reset, as it somehow could suggest.
* required parameter <mac> = device MAC address
* optional parameter <reboot_type> = string; two options: 'soft' or 'hard', defaults to soft
* soft can be used for all devices, requests a plain restart of that device
* hard is special for PoE switches and besides the restart also requests a
* power cycle on all PoE capable ports. Keep in mind that a 'hard' reboot
* does *NOT* trigger a factory-reset.
*/
public function restart_device($mac, $type = 'soft')
public function restart_device($mac, $reboot_type = 'soft')
{
$payload = ['cmd' => 'restart', 'mac' => strtolower($mac)];
if (!empty($type) && in_array($type, ['soft', 'hard'])) {
$payload['type'] = strtolower($type);
if (!empty($reboot_type) && in_array($reboot_type, ['soft', 'hard'])) {
$payload['reboot_type'] = strtolower($reboot_type);
}

return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr', $payload);
Expand Down Expand Up @@ -2501,10 +2508,13 @@ public function list_events($historyhours = 720, $start = 0, $limit = 3000)
* List alarms
* -----------
* returns an array of known alarms
* optional parameter <payload> = array of flags to filter by
* Example: ["archived" => false, "key" => "EVT_GW_WANTransition"]
* return only unarchived for a specific key
*/
public function list_alarms()
public function list_alarms($payload = [])
{
return $this->fetch_results('/api/s/' . $this->site . '/list/alarm');
return $this->fetch_results('/api/s/' . $this->site . '/list/alarm', $payload);
}

/**
Expand Down Expand Up @@ -2755,7 +2765,7 @@ public function create_radius_account($name, $x_password, $tunnel_type, $tunnel_
'tunnel_medium_type' => (int) $tunnel_medium_type
];

if (isset($vlan)) {
if (!is_null($vlan)) {
$payload['vlan'] = (int) $vlan;
}

Expand Down Expand Up @@ -3037,7 +3047,7 @@ public function get_debug()
*/
public function get_last_results_raw($return_json = false)
{
if ($this->last_results_raw !== null) {
if (!is_null($this->last_results_raw)) {
if ($return_json) {
return json_encode($this->last_results_raw, JSON_PRETTY_PRINT);
}
Expand All @@ -3055,7 +3065,7 @@ public function get_last_results_raw($return_json = false)
*/
public function get_last_error_message()
{
if ($this->last_error_message !== null) {
if (!is_null($this->last_error_message)) {
return $this->last_error_message;
}

Expand Down Expand Up @@ -3414,7 +3424,7 @@ protected function exec_curl($path, $payload = null)
CURLOPT_URL => $url
];

if ($payload !== null) {
if (!is_null($payload)) {
$json_payload = json_encode($payload, JSON_UNESCAPED_SLASHES);
$curl_options[CURLOPT_POST] = true;
$curl_options[CURLOPT_POSTFIELDS] = $json_payload;
Expand Down

0 comments on commit d26cba1

Please sign in to comment.