node-unifi
Version:
NodeJS class for querying UniFi-Controller (www.ubnt.com)
1,526 lines (1,334 loc) • 110 kB
JavaScript
/* eslint-disable max-params, camelcase */
/**
*
* UniFi controller class (NodeJS)
*
* This nodejs class provides functionality to query a UniFi controller (www.ubnt.com) through
* its Web-API. The functionality implemented here had been gathered through different
* souces, namely:
*
* UniFi-API-client: https://github.com/Art-of-WiFi/UniFi-API-client/blob/master/src/Client.php
* UniFi-API sh: https://dl.ui.com/unifi/5.12.35/unifi_sh_api
* domwo: http://community.ubnt.com/t5/UniFi-Wireless/little-php-class-for-unifi-api/m-p/603051
* fbagnol: https://github.com/fbagnol/class.unifi.php
*
* The majority of the functions in here are actually based on the PHP UniFi-API-client class
* which defines compatibility to UniFi-Controller versions v4 and v5+
*
* Based/Compatible to UniFi-API-client class: v1.1.80
*
* Copyright (c) 2017-2023 Jens Maus <mail@jens-maus.de>
*
* The source code is distributed under the MIT license
*
*/
'use strict';
const EventEmitter = require('eventemitter2').EventEmitter2;
const WebSocket = require('ws');
const axios = require('axios');
const {CookieJar} = require('tough-cookie');
const {HttpCookieAgent, HttpsCookieAgent} = require('http-cookie-agent/http');
/// ///////////////////////////////////////////////////////////
// PUBLIC CLASS
class Controller extends EventEmitter {
/** CONSTRUCTOR */
constructor(options) {
super({
wildcard: true
});
// Parse opts
this.opts = options || {};
this.opts.host = (typeof (this.opts.host) === 'undefined' ? 'unifi' : this.opts.host);
this.opts.port = (typeof (this.opts.port) === 'undefined' ? 8443 : this.opts.port);
this.opts.username = (typeof (this.opts.username) === 'undefined' ? 'admin' : this.opts.username);
this.opts.password = (typeof (this.opts.password) === 'undefined' ? 'ubnt' : this.opts.password);
this.opts.token2FA = (typeof (this.opts.token2FA) === 'undefined' ? null : this.opts.token2FA);
this.opts.site = (typeof (this.opts.site) === 'undefined' ? 'default' : this.opts.site);
this.opts.sslverify = (typeof (this.opts.sslverify) === 'undefined' ? true : this.opts.sslverify);
this.opts.timeout = (typeof (this.opts.timeout) === 'undefined' ? 5000 : this.opts.timeout);
this.opts.rememberMe = (typeof (this.opts.rememberMe) === 'undefined' ? true : this.opts.rememberMe);
this._baseurl = new URL(`https://${options.host}:${options.port}`);
this._cookieJar = new CookieJar();
this._unifios = false;
this._isClosed = true;
this._autoReconnectInterval = 5 * 1000; // Ms
this._pingPongInterval = 3 * 1000; // Ms
this._isInit = false;
}
/** PUBLIC METHODS */
/**
* Login to the UniFi controller - login()
*
* returns true upon success
*/
async login(username = null, password = null, token2FA = null) {
// Allows to override username+password
if (username !== null) {
this.opts.username = username;
}
if (password !== null) {
this.opts.password = password;
}
if (token2FA !== null) {
this.opts.token2FA = token2FA;
}
// Make sure init() was called
const result = await this._init();
// If init() was already called
// resolve immediately
if (result === 2) {
return true;
}
let endpointUrl = `${this._baseurl.href}api/login`;
if (this._unifios) {
endpointUrl = `${this._baseurl.href}api/auth/login`;
}
// Prepare payload data
const data = {
username: this.opts.username,
password: this.opts.password,
rememberMe: this.opts.rememberMe
};
// Add 2FA token to payload
if (this.opts.token2FA) {
// On UniFiOS 2FA is in 'token' field, else in 'ubic_2fa_token'
data[this._unifios ? 'token' : 'ubic_2fa_token'] = this.opts.token2FA;
}
// Perform the login to the Unifi controller
const response = await this._instance.post(endpointUrl, data, {
timeout: this.opts.timeout
});
// Catch x-csrf-token if supplied in response
if (response.headers['x-csrf-token']) {
this._xcsrftoken = response.headers['x-csrf-token'];
this._instance.defaults.headers.common['x-csrf-token'] = this._xcsrftoken;
}
return true;
}
/**
* Logout from the UniFi controller - logout()
*
* returns true upon success
*/
async logout() {
if (this._unifios === true) {
return this._request('/api/auth/logout', null, 'POST');
}
return this._request('/logout');
}
/**
* Authorize a client device - authorize_guest()
*
* required parameter <mac> = client MAC address
* optional parameter <minutes> = minutes (from now) until authorization expires
* optional parameter <up> = upload speed limit in kbps
* optional parameter <down> = download speed limit in kbps
* optional parameter <megabytes>= data transfer limit in MB
* optional parameter <ap_mac> = AP MAC address to which client is connected, should result in faster authorization
*/
authorizeGuest(mac, minutes = null, up = null, down = null, megabytes = null, ap_mac = null) {
const payload = {cmd: 'authorize-guest', mac: mac.toLowerCase()};
if (minutes !== null) {
payload.minutes = minutes;
}
if (up !== null) {
payload.up = up;
}
if (down !== null) {
payload.down = down;
}
if (megabytes !== null) {
payload.bytes = megabytes;
}
if (ap_mac !== null) {
payload.ap_mac = ap_mac.toLowerCase();
}
return this._request('/api/s/<SITE>/cmd/stamgr', payload);
}
/**
* Unauthorize a client device - unauthorize_guest()
*
* required parameter <mac> = client MAC address
*/
unauthorizeGuest(mac) {
return this._request('/api/s/<SITE>/cmd/stamgr', {cmd: 'unauthorize-guest', mac: mac.toLowerCase()});
}
/**
* Reconnect a client device - reconnect_sta()
*
* required parameter <mac> = client MAC address
*/
reconnectClient(mac) {
return this._request('/api/s/<SITE>/cmd/stamgr', {cmd: 'kick-sta', mac: mac.toLowerCase()});
}
/**
* Block a client device - block_sta()
*
* required parameter <mac> = client MAC address
*/
blockClient(mac) {
return this._request('/api/s/<SITE>/cmd/stamgr', {cmd: 'block-sta', mac: mac.toLowerCase()});
}
/**
* Unblock a client device - unblock_sta()
*
* required parameter <mac> = client MAC address
*/
unblockClient(mac) {
return this._request('/api/s/<SITE>/cmd/stamgr', {cmd: 'unblock-sta', mac: mac.toLowerCase()});
}
/**
* Forget one or more client devices - forget_sta()
*
* return true on success
* required parameter <macs> = array of client MAC addresses
*
* NOTE:
* only supported with controller versions 5.9.X and higher, can be
* slow (up to 5 minutes) on larger controllers
*/
forgetClient(macs) {
return this._request('/api/s/<SITE>/cmd/stamgr', {cmd: 'forget-sta', macs});
}
/**
* Create a new user/client-device - create_user()
*
* return an array with a single object containing details of the new user/client-device on success, else return false
* required parameter <mac> = client MAC address
* required parameter <user_group_id> = _id value for the user group the new user/client-device should belong to which
* can be obtained from the output of list_usergroups()
* optional parameter <name> = name to be given to the new user/client-device
* optional parameter <note> = note to be applied to the new user/client-device
* optional parameter <is_guest> = boolean; defines whether the new user/client-device is a guest or not
* optional parameter <is_wired> = boolean; defines whether the new user/client-device is wi red or not
*/
createUser(mac, user_group_id, name = null, note = null, is_guest = null, is_wired = null) {
const new_user = {mac: mac.toLowerCase(),
user_group_id
};
if (name !== null) {
new_user.name = name;
}
if (note !== null) {
new_user.note = note;
}
if (is_guest !== null) {
new_user.is_guest = is_guest;
}
if (is_wired !== null) {
new_user.is_wired = is_wired;
}
return this._request('/api/s/<SITE>/group/user', {objects: [{data: new_user}]});
}
/**
* Add/modify/remove a client device note - set_sta_note()
*
* required parameter <user_id> = id of the client-device to be modified
* optional parameter <note> = note to be applied to the client-device
*
* NOTES:
* - when note is empty or not set, the existing note for the client-device is removed and "noted" attribute set to false
*/
setClientNote(user_id, note = '') {
return this._request('/api/s/<SITE>/upd/user/' + user_id.trim(), {note});
}
/**
* Add/modify/remove a client device name - set_sta_name()
*
* required parameter <user_id> = id of the client device to be modified
* optional parameter <name> = name to be applied to the client device
*
* NOTES:
* - when name is empty or not set, the existing name for the client device is removed
*/
setClientName(user_id, name = '') {
return this._request('/api/s/<SITE>/upd/user/' + user_id.trim(), {name});
}
/**
* Fetch 5 minutes site stats method - stat_5minutes_site()
*
* returns an array of 5-minute stats objects for the current site
* optional parameter <start> = Unix timestamp in milliseconds
* optional parameter <end> = Unix timestamp in milliseconds
*
* NOTES:
* - defaults to the past 12 hours
* - this function/method is only supported on controller versions 5.5.* and later
* - make sure that the retention policy for 5 minutes stats is set to the correct value in
* the controller settings
*/
get5minSiteStats(start = null, end = null) {
if (end === null) {
end = Date.now();
}
if (start === null) {
start = end - (12 * 3600 * 1000);
}
const payload = {attrs: ['bytes',
'wan-tx_bytes',
'wan-rx_bytes',
'wan2-tx_bytes',
'wan2-rx_bytes',
'wlan_bytes',
'num_sta',
'lan-num_sta',
'wlan-num_sta',
'time'],
start,
end};
return this._request('/api/s/<SITE>/stat/report/5minutes.site', payload);
}
/**
* Fetch Hourly site stats method - stat_hourly_site()
*
* optional parameter <start> = Unix timestamp in milliseconds
* optional parameter <end> = Unix timestamp in milliseconds
*
* NOTES:
* - defaults to the past 7*24 hours
* - "bytes" are no longer returned with controller version 4.9.1 and later
*/
getHourlySiteStats(start = null, end = null) {
if (end === null) {
end = Date.now();
}
if (start === null) {
start = end - (7 * 24 * 3600 * 1000);
}
const payload = {attrs: ['bytes',
'wan-tx_bytes',
'wan-rx_bytes',
'wan2-tx_bytes',
'wan2-rx_bytes',
'wlan_bytes',
'num_sta',
'lan-num_sta',
'wlan-num_sta',
'time'],
start,
end};
return this._request('/api/s/<SITE>/stat/report/hourly.site', payload);
}
/**
* Fetch Daily site stats method - stat_daily_site()
*
* optional parameter <start> = Unix timestamp in milliseconds
* optional parameter <end> = Unix timestamp in milliseconds
*
* NOTES:
* - defaults to the past 52*7*24 hours
* - "bytes" are no longer returned with controller version 4.9.1 and later
*/
getDailySiteStats(start = null, end = null) {
if (end === null) {
end = Date.now();
}
if (start === null) {
start = end - (52 * 7 * 24 * 3600 * 1000);
}
const payload = {attrs: ['bytes',
'wan-tx_bytes',
'wan-rx_bytes',
'wan2-tx_bytes',
'wan2-rx_bytes',
'wlan_bytes',
'num_sta',
'lan-num_sta',
'wlan-num_sta',
'time'],
start,
end};
return this._request('/api/s/<SITE>/stat/report/daily.site', payload);
}
/**
* Fetch monthly site stats - stat_monthly_site()
*
* @param int $start optional, Unix timestamp in milliseconds
* @param int $end optional, Unix timestamp in milliseconds
* @return array returns an array of monthly stats objects for the current site
*
* NOTES:
* - defaults to the past 52 weeks (52*7*24 hours)
* - "bytes" are no longer returned with controller version 4.9.1 and later
*/
getMonthlySiteStats(start = null, end = null) {
if (end === null) {
end = Date.now();
}
if (start === null) {
start = end - (52 * 7 * 24 * 3600 * 1000);
}
const payload = {attrs: ['bytes',
'wan-tx_bytes',
'wan-rx_bytes',
'wan2-tx_bytes',
'wan2-rx_bytes',
'wlan_bytes',
'num_sta',
'lan-num_sta',
'wlan-num_sta',
'time'],
start,
end};
return this._request('/api/s/<SITE>/stat/report/monthly.site', payload);
}
/**
* Fetch 5 minutes stats method for a single access point or all access points - stat_5minutes_aps()
*
* returns an array of 5-minute stats objects
* optional parameter <start> = Unix timestamp in milliseconds
* optional parameter <end> = Unix timestamp in milliseconds
* optional parameter <mac> = AP MAC address to return stats for
*
* NOTES:
* - defaults to the past 12 hours
* - this function/method is only supported on controller versions 5.5.* and later
* - make sure that the retention policy for 5 minutes stats is set to the correct value in
* the controller settings
*/
get5minApStats(start = null, end = null, mac = null) {
if (end === null) {
end = Date.now();
}
if (start === null) {
start = end - (12 * 3600 * 1000);
}
const payload = {attrs: ['bytes',
'num_sta',
'time'],
start,
end};
if (mac !== null) {
payload.mac = mac.toLowerCase();
}
return this._request('/api/s/<SITE>/stat/report/5minutes.ap', payload);
}
/**
* Fetch Hourly stats method for a single access point or all access points - stat_hourly_aps()
*
* optional parameter <start> = Unix timestamp in milliseconds
* optional parameter <end> = Unix timestamp in milliseconds
* optional parameter <mac> = AP MAC address to return stats for
*
* NOTES:
* - defaults to the past 7*24 hours
* - UniFi controller does not keep these stats longer than 5 hours with versions < 4.6.6
*/
getHourlyApStats(start = null, end = null, mac = null) {
if (end === null) {
end = Date.now();
}
if (start === null) {
start = end - (7 * 24 * 3600 * 1000);
}
const payload = {attrs: ['bytes',
'num_sta',
'time'],
start,
end};
if (mac !== null) {
payload.mac = mac.toLowerCase();
}
return this._request('/api/s/<SITE>/stat/report/hourly.ap', payload);
}
/**
* Fetch Daily stats method for a single access point or all access points - stat_daily_aps()
*
* optional parameter <start> = Unix timestamp in milliseconds
* optional parameter <end> = Unix timestamp in milliseconds
* optional parameter <mac> = AP MAC address to return stats for
*
* NOTES:
* - defaults to the past 7*24 hours
* - UniFi controller does not keep these stats longer than 5 hours with versions < 4.6.6
*/
getDailyApStats(start = null, end = null, mac = null) {
if (end === null) {
end = Date.now();
}
if (start === null) {
start = end - (7 * 24 * 3600 * 1000);
}
const payload = {attrs: ['bytes',
'num_sta',
'time'],
start,
end};
if (mac !== null) {
payload.mac = mac.toLowerCase();
}
return this._request('/api/s/<SITE>/stat/report/daily.ap', payload);
}
/**
* Fetch monthly stats for a single access point or all access points - stat_monthly_aps()
*
* NOTES:
* - defaults to the past 52 weeks (52*7*24 hours)
* - make sure that the retention policy for hourly stats is set to the correct value in
* the controller settings
*
* @param int $start optional, Unix timestamp in milliseconds
* @param int $end optional, Unix timestamp in milliseconds
* @param string $mac optional, AP MAC address to return stats for, when empty,
* stats for all APs are returned
* @return array returns an array of monthly stats objects
*/
getMonthlyApStats(start = null, end = null, mac = null) {
if (end === null) {
end = Date.now();
}
if (start === null) {
start = end - (52 * 7 * 24 * 3600 * 1000);
}
const payload = {attrs: ['bytes',
'num_sta',
'time'],
start,
end};
if (mac !== null) {
payload.mac = mac.toLowerCase();
}
return this._request('/api/s/<SITE>/stat/report/monthly.ap', payload);
}
/**
* Fetch 5 minutes stats method for a single user/client device - stat_5minutes_user()
*
* returns an array of 5-minute stats objects
* required parameter <mac> = MAC address of user/client device to return stats for
* optional parameter <start> = Unix timestamp in milliseconds
* optional parameter <end> = Unix timestamp in milliseconds
* optional parameter <attribs> = array containing attributes (strings) to be returned, valid values are:
* rx_bytes, tx_bytes, signal, rx_rate, tx_rate, rx_retries, tx_retries, rx_packets, tx_packets
* default is ['rx_bytes', 'tx_bytes']
*
* NOTES:
* - defaults to the past 12 hours
* - only supported with UniFi controller versions 5.8.X and higher
* - make sure that the retention policy for 5 minutes stats is set to the correct value in
* the controller settings
* - make sure that "Clients Historical Data" has been enabled in the UniFi controller settings in the Maintenance section
*/
get5minUserStats(mac, start = null, end = null, attribs = null) {
if (end === null) {
end = Date.now();
}
if (start === null) {
start = end - (12 * 3600 * 1000);
}
attribs = attribs === null ? ['time',
'rx_bytes',
'tx_bytes'] : ['time', ...attribs];
const payload = {attrs: attribs,
start,
end,
mac: mac.toLowerCase()};
return this._request('/api/s/<SITE>/stat/report/5minutes.user', payload);
}
/**
* Fetch Hourly stats method for a a single user/client device - stat_hourly_user()
*
* returns an array of hourly stats objects
* required parameter <mac> = MAC address of user/client device to return stats for
* optional parameter <start> = Unix timestamp in milliseconds
* optional parameter <end> = Unix timestamp in milliseconds
* optional parameter <attribs> = array containing attributes (strings) to be returned, valid values are:
* rx_bytes, tx_bytes, signal, rx_rate, tx_rate, rx_retries, tx_retries, rx_packets, tx_packets
* default is ['rx_bytes', 'tx_bytes']
*
* NOTES:
* - defaults to the past 7*24 hours
* - only supported with UniFi controller versions 5.8.X and higher
* - make sure that "Clients Historical Data" has been enabled in the UniFi controller settings in the Maintenance section
*/
getHourlyUserStats(mac, start = null, end = null, attribs = null) {
if (end === null) {
end = Date.now();
}
if (start === null) {
start = end - (7 * 24 * 3600 * 1000);
}
attribs = attribs === null ? ['time',
'rx_bytes',
'tx_bytes'] : ['time', ...attribs];
const payload = {attrs: attribs,
start,
end,
mac: mac.toLowerCase()};
return this._request('/api/s/<SITE>/stat/report/hourly.user', payload);
}
/**
* Fetch Daily stats method for a single user/client device - stat_daily_user()
*
* returns an array of daily stats objects
* required parameter <mac> = MAC address of user/client device to return stats for
* optional parameter <start> = Unix timestamp in milliseconds
* optional parameter <end> = Unix timestamp in milliseconds
* optional parameter <attribs> = array containing attributes (strings) to be returned, valid values are:
* rx_bytes, tx_bytes, signal, rx_rate, tx_rate, rx_retries, tx_retries, rx_packets, tx_packets
* default is ['rx_bytes', 'tx_bytes']
*
* NOTES:
* - defaults to the past 7*24 hours
* - only supported with UniFi controller versions 5.8.X and higher
* - make sure that the retention policy for daily stats is set to the correct value in
* the controller settings
* - make sure that "Clients Historical Data" has been enabled in the UniFi controller settings in the Maintenance section
*/
getDailyUserStats(mac, start = null, end = null, attribs = null) {
if (end === null) {
end = Date.now();
}
if (start === null) {
start = end - (7 * 24 * 3600 * 1000);
}
attribs = attribs === null ? ['time',
'rx_bytes',
'tx_bytes'] : ['time', ...attribs];
const payload = {attrs: attribs,
start,
end,
mac: mac.toLowerCase()};
return this._request('/api/s/<SITE>/stat/report/daily.user', payload);
}
/**
* Fetch monthly stats for a single user/client device - stat_monthly_user()
*
* NOTES:
* - defaults to the past 13 weeks (52*7*24 hours)
* - only supported with UniFi controller versions 5.8.X and higher
* - make sure that the retention policy for monthly stats is set to the correct value in
* the controller settings
* - make sure that "Clients Historical Data" has been enabled in the UniFi controller settings in the Maintenance section
*
* @param string $mac MAC address of user/client device to return stats for
* @param int $start optional, Unix timestamp in milliseconds
* @param int $end optional, Unix timestamp in milliseconds
* @param array $attribs array containing attributes (strings) to be returned, valid values are:
* rx_bytes, tx_bytes, signal, rx_rate, tx_rate, rx_retries, tx_retries, rx_packets, tx_packets
* default is ['rx_bytes', 'tx_bytes']
* @return array returns an array of monthly stats objects
*/
getMonthlyUserStats(mac, start = null, end = null, attribs = null) {
if (end === null) {
end = Date.now();
}
if (start === null) {
start = end - (13 * 7 * 24 * 3600 * 1000);
}
attribs = attribs === null ? ['time',
'rx_bytes',
'tx_bytes'] : ['time', ...attribs];
const payload = {attrs: attribs,
start,
end,
mac: mac.toLowerCase()};
return this._request('/api/s/<SITE>/stat/report/monthly.user', payload);
}
/**
* Fetch 5 minutes gateway stats method - stat_5minutes_gateway()
*
* returns an array of 5-minute stats objects for the gateway belonging to the current site
* optional parameter <start> = Unix timestamp in milliseconds
* optional parameter <end> = Unix timestamp in milliseconds
* optional parameter <attribs> = array containing attributes (strings) to be returned, valid val ues are:
* mem, cpu, loadavg_5, lan-rx_errors, lan-tx_errors, lan-rx_bytes ,
* lan-tx_bytes, lan-rx_packets, lan-tx_packets, lan-rx_dropped, l an-tx_dropped
* default is ['time', 'mem', 'cpu', 'loadavg_5']
*
* NOTES:
* - defaults to the past 12 hours
* - this function/method is only supported on controller versions 5.5.* and later
* - make sure that the retention policy for 5 minutes stats is set to the correct value in
* the controller settings
* - requires a USG
*/
get5minGatewayStats(start = null, end = null, attribs = null) {
if (end === null) {
end = Date.now();
}
if (start === null) {
start = end - (12 * 3600 * 1000);
}
attribs = attribs === null ? ['time',
'mem',
'cpu',
'loadavg_5'] : ['time', ...attribs];
const payload = {attrs: attribs,
start,
end};
return this._request('/api/s/<SITE>/stat/report/5minutes.gw', payload);
}
/**
* Fetch Hourly gateway stats method - stat_hourly_gateway()
*
* returns an array of hourly stats objects for the gateway belonging to the current site
* optional parameter <start> = Unix timestamp in milliseconds
* optional parameter <end> = Unix timestamp in milliseconds
* optional parameter <attribs> = array containing attributes (strings) to be returned, valid val ues are:
* mem, cpu, loadavg_5, lan-rx_errors, lan-tx_errors, lan-rx_bytes ,
* lan-tx_bytes, lan-rx_packets, lan-tx_packets, lan-rx_dropped, l an-tx_dropped
* default is ['time', 'mem', 'cpu', 'loadavg_5']
*
* NOTES:
* - defaults to the past 7*24 hours
* - requires a USG
*/
getHourlyGatewayStats(start = null, end = null, attribs = null) {
if (end === null) {
end = Date.now();
}
if (start === null) {
start = end - (7 * 24 * 3600 * 1000);
}
attribs = attribs === null ? ['time',
'mem',
'cpu',
'loadavg_5'] : ['time', ...attribs];
const payload = {attrs: attribs,
start,
end};
return this._request('/api/s/<SITE>/stat/report/hourly.gw', payload);
}
/**
* Fetch Daily gateway stats method - stat_daily_gateway()
*
* returns an array of daily stats objects for the gateway belonging to the current site
* optional parameter <start> = Unix timestamp in milliseconds
* optional parameter <end> = Unix timestamp in milliseconds
* optional parameter <attribs> = array containing attributes (strings) to be returned, valid val ues are:
* mem, cpu, loadavg_5, lan-rx_errors, lan-tx_errors, lan-rx_bytes ,
* lan-tx_bytes, lan-rx_packets, lan-tx_packets, lan-rx_dropped, l an-tx_dropped
* default is ['time', 'mem', 'cpu', 'loadavg_5']
*
* NOTES:
* - defaults to the past 52 weeks (52*7*24 hours)
* - requires a USG
*/
getDailyGatewayStats(start = null, end = null, attribs = null) {
if (end === null) {
end = Date.now();
}
if (start === null) {
start = end - (52 * 7 * 24 * 3600 * 1000);
}
attribs = attribs === null ? ['time',
'mem',
'cpu',
'loadavg_5'] : ['time', ...attribs];
const payload = {attrs: attribs,
start,
end};
return this._request('/api/s/<SITE>/stat/report/daily.gw', payload);
}
/**
* Fetch monthly gateway stats - stat_monthly_gateway()
*
* NOTES:
* - defaults to the past 52 weeks (52*7*24 hours)
* - requires a USG
*
* @param int $start optional, Unix timestamp in milliseconds
* @param int $end optional, Unix timestamp in milliseconds
* @param array $attribs array containing attributes (strings) to be returned, valid values are:
* mem, cpu, loadavg_5, lan-rx_errors, lan-tx_errors, lan-rx_bytes,
* lan-tx_bytes, lan-rx_packets, lan-tx_packets, lan-rx_dropped, lan-tx_dropped
* default is ['time', 'mem', 'cpu', 'loadavg_5']
* @return array returns an array of monthly stats objects for the gateway belonging to the current site
*/
getMonthlyGatewayStats(start = null, end = null, attribs = null) {
if (end === null) {
end = Date.now();
}
if (start === null) {
start = end - (52 * 7 * 24 * 3600 * 1000);
}
attribs = attribs === null ? ['time',
'mem',
'cpu',
'loadavg_5'] : ['time', ...attribs];
const payload = {attrs: attribs,
start,
end};
return this._request('/api/s/<SITE>/stat/report/monthly.gw', payload);
}
/**
* Fetch speed test results method - stat_speedtest_results()
*
* returns an array of speed test result objects
* optional parameter <start> = Unix timestamp in milliseconds
* optional parameter <end> = Unix timestamp in milliseconds
*
* NOTES:
* - defaults to the past 24 hours
* - requires a USG
*/
getSpeedTestResults(start = null, end = null) {
if (end === null) {
end = Date.now();
}
if (start === null) {
start = end - (24 * 3600 * 1000);
}
const payload = {
attrs: ['xput_download',
'xput_upload',
'latency',
'time'],
start,
end};
return this._request('/api/s/<SITE>/stat/report/archive.speedtest', payload);
}
/**
* Fetch IPS/IDS events methods - stat_ips_events
*
* returns an array of IPS/IDS event objects
* optional parameter <start> = Unix timestamp in milliseconds
* optional parameter <end> = Unix timestamp in milliseconds
* optional parameter <limit> = Maximum number of events to return, defaults to 10000
*
* NOTES:
* - defaults to the past 24 hours
* - requires a USG
* - supported in UniFi controller versions 5.9.X and higher
*/
getIPSEvents(start = null, end = null, limit = 10_000) {
if (end === null) {
end = Date.now();
}
if (start === null) {
start = end - (24 * 3600 * 1000);
}
const payload = {start,
end,
_limit: limit};
return this._request('/api/s/<SITE>/stat/ips/event', payload);
}
/**
* Fetch login sessions - stat_sessions()
*
* returns an array of login session objects for all devices or a single device
* optional parameter <start> = Unix timestamp in seconds
* optional parameter <end> = Unix timestamp in seconds
* optional parameter <mac> = client MAC address to return sessions for (can only be used when start and end are also provided)
* optional parameter <type> = client type to return sessions for, can be 'all', 'guest' or 'user'; default value is 'all'
*
* NOTES:
* - defaults to the past 7*24 hours
*/
getSessions(start = null, end = null, mac = null, type = 'all') {
if (end === null) {
end = Math.floor(Date.now() / 1000);
}
if (start === null) {
start = end - (7 * 24 * 3600);
}
const payload = {type,
start,
end};
if (mac !== null) {
payload.mac = mac.toLowerCase();
}
return this._request('/api/s/<SITE>/stat/session', payload);
}
/**
* Fetch latest 'n' login sessions for a single client device - stat_sta_sessions_latest()
*
* required parameter <mac> = client MAC address
* optional parameter <limit> = maximum number of sessions to get (defaults to 5)
*
*/
getLatestSessions(mac, limit = 5) {
const payload = {mac: mac.toLowerCase(),
_limit: limit,
_sort: '-assoc_time'};
return this._request('/api/s/<SITE>/stat/session', payload);
}
/**
* Fetch authorizations - stat_auths()
*
* optional parameter <start> = Unix timestamp in seconds
* optional parameter <end> = Unix timestamp in seconds
*
* NOTES:
* - defaults to the past 7*24 hours
*/
getAllAuthorizations(start = null, end = null) {
if (end === null) {
end = Math.floor(Date.now() / 1000);
}
if (start === null) {
start = end - (7 * 24 * 3600);
}
return this._request('/api/s/<SITE>/stat/authorization', {start, end});
}
/**
* Fetch client devices that connected to the site within given timeframe - stat_allusers()
*
* optional parameter <historyhours> = hours to go back (default is 8760 hours or 1 year)
*
* NOTES:
* - <historyhours> is only used to select clients that were online within that period,
* the returned stats per client are all-time totals, irrespective of the value of <historyhours>
*/
getAllUsers(within = 8760) {
const payload = {type: 'all',
conn: 'all',
within};
return this._request('/api/s/<SITE>/stat/alluser', payload);
}
/**
* List all blocked client devices ever connected to the site
*
* optional parameter <historyhours> = hours to go back (default is 8760 hours or 1 year)
*
* NOTES:
* - <historyhours> is only used to select clients that were online within that period,
* the returned stats per client are all-time totals, irrespective of the value of <historyhours>
*/
getBlockedUsers(within = 8760) {
const payload = {type: 'blocked',
conn: 'all',
within};
return this._request('/api/s/<SITE>/stat/alluser', payload);
}
/**
* Fetch guest devices - list_guests()
*
* optional parameter <within> = time frame in hours to go back to list guests with valid access (default = 24*365 hours)
*
* NOTES:
* - defaults to the past 7*24 hours
*
*/
getGuests(within = 8760) {
return this._request('/api/s/<SITE>/stat/guest', {within});
}
/**
* Fetch online client device(s) - list_clients()
*
* returns an array of online client device objects, or in case of a single device request, returns a single client device object
*
* optional parameter <client_mac> = the MAC address of a single online client device for which the call must be made
*/
getClientDevices(client_mac = '') {
return this._request('/api/s/<SITE>/stat/sta/' + client_mac.trim().toLowerCase());
}
/**
* Fetch details for a single client device - stat_client()
*
* optional parameter <client_mac> = the MAC address of a single online client device for which the call must be made
*/
getClientDevice(client_mac = '') {
return this._request('/api/s/<SITE>/stat/user/' + client_mac.trim().toLowerCase());
}
/**
* Assign client device to another group - set_usergroup()
*
* @param string $client_id _id value of the client device to be modified
* @param string $group_id _id value of the user group to assign client device to
* @return bool returns true upon success
*/
setUserGroup(client_id, group_id) {
return this._request('/api/s/<SITE>/upd/user/' + client_id.trim(), {usergroup_id: group_id});
}
/**
* Update client fixedip (using REST) - edit_client_fixedip()
*
* returns an array containing a single object with attributes of the updated client on success
* required parameter <client_id> = _id of the client
* required parameter <use_fixedip> = boolean defining whether if use_fixedip is true or false
* optional parameter <network_id> = _id value for the network where the ip belongs to
* optional parameter <fixed_ip> = value of client's fixed_ip field
*
*/
editClientFixedIP(client_id, use_fixedip, network_id = null, fixed_ip = null) {
const payload = {_id: client_id,
use_fixedip};
if (use_fixedip === true) {
if (network_id !== null) {
payload.network_id = network_id;
}
if (fixed_ip !== null) {
payload.fixed_ip = fixed_ip;
}
}
return this._request('/api/s/<SITE>/rest/user/' + client_id.trim(), payload, 'PUT');
}
/**
* Update client name (using REST) - edit_client_name()
*
* @param string $client_id _id value for the client
* @param bool $name of the client
* @return array|false returns an array containing a single object with attributes of the updated client on success
*/
editClientName(client_id, name) {
const payload = {_id: client_id,
name};
return this._request('/api/s/<SITE>/rest/user/' + client_id.trim(), payload, 'PUT');
}
/**
* Fetch user groups - list_usergroups()
*
*/
getUserGroups() {
return this._request('/api/s/<SITE>/list/usergroup');
}
/**
* Create user group (using REST) - create_usergroup()
*
* returns an array containing a single object with attributes of the new usergroup ("_id", "name", "qos_rate_max_down", "qos_rate_max_up", "site_id") on success
*
* required parameter <group_name> = name of the user group
* optional parameter <group_dn> = limit download bandwidth in Kbps (default = -1, which sets bandwidth to unlimited)
* optional parameter <group_up> = limit upload bandwidth in Kbps (default = -1, which sets bandwidth to unlimited)
*
*/
createUserGroup(group_name, group_dn = -1, group_up = -1) {
const payload = {name: group_name,
qos_rate_max_down: group_dn,
qos_rate_max_up: group_up};
return this._request('/api/s/<SITE>/rest/usergroup', payload);
}
/**
* Modify user group (using REST) - edit_usergroup()
*
* returns an array containing a single object with attributes of the updated usergroup on success
*
* required parameter <group_id> = _id of the user group
* required parameter <site_id> = _id of the site
* required parameter <group_name> = name of the user group
* optional parameter <group_dn> = limit download bandwidth in Kbps (default = -1, which sets bandwidth to unlimited)
* optional parameter <group_up> = limit upload bandwidth in Kbps (default = -1, which sets bandwidth to unlimited)
*
*/
editUserGroup(group_id, site_id, group_name, group_dn = -1, group_up = -1) {
const payload = {_id: group_id,
site_id,
name: group_name,
qos_rate_max_down: group_dn,
qos_rate_max_up: group_up};
return this._request('/api/s/<SITE>/rest/usergroup/' + group_id.trim(), payload, 'PUT');
}
/**
* Delete user group (using REST) - delete_usergroup()
*
* returns true on success
*
* required parameter <group_id> = _id value of the user group to delete
*
*/
deleteUserGroup(group_id) {
return this._request('/api/s/<SITE>/rest/usergroup/' + group_id.trim(), null, 'DELETE');
}
/**
* Fetch AP groups - list_apgroups()
*
* @return array containing the current AP groups on success
*/
getAPGroups() {
return this._request('/v2/api/site/<SITE>/apgroups');
}
/**
* Create AP group - create_apgroup()
*
* @param string $group_name name to assign to the AP group
* @param array $device_macs optional, array containing the MAC addresses (strings) of the APs to add to the new group
* @return object returns a single object with attributes of the new AP group on success
*
*/
createAPGroup(group_name, device_macs = []) {
const payload = {device_macs,
name: group_name
};
return this._request('/v2/api/site/<SITE>/apgroups', payload);
}
/**
* Modify AP group - edit_apgroup()
*
* @param string $group_id _id value of the AP group to modify
* @param string $group_name name to assign to the AP group
* @param array $device_macs array containing the members of the AP group which overwrites the existing
* group_members (passing an empty array clears the AP member list)
* @return object returns a single object with attributes of the updated AP group on success
*
*/
editAPGroup(group_id, group_name, device_macs) {
const payload = {_id: group_id,
attr_no_delete: false,
name: group_name,
device_macs};
return this._request('/v2/api/site/<SITE>/apgroups/' + group_id.trim(), payload, 'PUT');
}
/**
* Delete AP group - delete_apgroup()
*
* @param string $group_id _id value of the AP group to delete
* @return bool returns true on success
*
*/
deleteAPGroup(group_id) {
return this._request('/v2/api/site/<SITE>/apgroups/' + group_id.trim(), null, 'DELETE');
}
/**
* List firewall groups (using REST) - list_firewallgroups()
*
* returns an array containing the current firewall groups or the selected firewall group on success
* optional parameter <group_id> = _id value of the single firewall group to list
*/
getFirewallGroups(group_id = '') {
return this._request('/api/s/<SITE>/rest/firewallgroup/' + group_id.trim());
}
/**
* Create firewall group (using REST) - create_firewallgroup()
*
* returns an array containing a single object with attributes of the new firewall group on succe ss
* required parameter <group_name> = name to assign to the firewall group
* required parameter <group_type> = firewall group type; valid values are address-group, ipv6 -address-group, port-group
* optional parameter <group_members> = array containing the members of the new group (IPv4 addre sses, IPv6 addresses or port numbers)
* (default is an empty array)
*/
createFirewallGroup(group_name, group_type, group_members = []) {
const payload = {name: group_name,
group_type,
group_members};
return this._request('/api/s/<SITE>/rest/firewallgroup', payload);
}
/**
* Modify firewall group (using REST) - edit_firewallgroup
*
* returns an array containing a single object with attributes of the updated firewall group on s uccess
* required parameter <group_id> = _id value of the firewall group to modify
* required parameter <site_id> = site_id value of the firewall group to modify
* required parameter <group_name> = name of the firewall group
* required parameter <group_type> = firewall group type; valid values are address-group, ipv6 -address-group, port-group,
* group_type cannot be changed for an existing firewall gro up!
* optional parameter <group_members> = array containing the members of the group (IPv4 addresses , IPv6 addresses or port numbers)
* which overwrites the existing group_members (default is an empty array)
*
*
*/
editFirewallGroup(group_id, site_id, group_name, group_type, group_members = []) {
const payload = {_id: group_id,
name: group_name,
group_type,
group_members,
site_id};
return this._request('/api/s/<SITE>/rest/firewallgroup/' + group_id.trim(), payload, 'PUT');
}
/**
* Delete firewall group (using REST) - delete_firewallgroup()
*
* returns true on success
* required parameter <group_id> = _id value of the firewall group to delete
*/
deleteFirewallGroup(group_id) {
return this._request('/api/s/<SITE>/rest/firewallgroup/' + group_id.trim(), null, 'DELETE');
}
/**
* List firewall rules (using REST) - list_firewallrules()
*
* returns an array containing the current firewall rules on success
*/
getFirewallRules() {
return this._request('/api/s/<SITE>/rest/firewallrule');
}
/**
* List static routing settings (using REST) - list_routing()
*
* returns an array of static routes and their settings
* optional parameter <route_id> = string; _id value of the static route to get settings for
*/
getRouting(route_id = '') {
return this._request('/api/s/<SITE>/rest/routing/' + route_id.trim());
}
/**
* List health metrics - list_health()
*
*/
getHealth() {
return this._request('/api/s/<SITE>/stat/health');
}
/**
* List dashboard metrics - list_dashboard()
*
* returns an array of dashboard metric objects (available since controller version 4.9.1.alpha)
* optional parameter <five_minutes> = boolean; if true, return stats based on 5 minute intervals,
* returns hourly stats by default (supported on controller versions 5.5.* and higher)
*/
getDashboard(five_minutes = false) {
const path_suffix = five_minutes === true ? '?scale=5minutes' : '';
return this._request('/api/s/<SITE>/stat/dashboard' + path_suffix);
}
/**
* List client devices - list_users()
*
* returns an array of known client device objects
*/
getUsers() {
return this._request('/api/s/<SITE>/list/user');
}
/**
* List of site devices with a basic subset of fields (e.g., mac, state, adopted, disabled, type, model, name) - list_devices_basic()
*
* returns an array containing known UniFi device objects)
*/
getAccessDevicesBasic() {
return this._request('/api/s/<SITE>/stat/device-basic');
}
/**
* List access points and other devices under management of the controller (USW and/or USG devices) - list_devices()
*
* optional paramater <device_mac> = the MAC address of a single device for which the call must be made
*/
getAccessDevices(device_mac = '') {
return this._request('/api/s/<SITE>/stat/device/' + device_mac.trim().toLowerCase());
}
/**
* List (device) tags (using REST) - list_tags()
*
* returns an array of known device tag objects
*
* NOTES: this endpoint was introduced with controller versions 5.5.X
*/
listTags() {
return this._request('/api/s/<SITE>/rest/tag');
}
/**
* List rogue/neighboring access points - list_rogueaps()
*
* returns an array of rogue/neighboring access point objects
* optional parameter <within> = hours to go back to list discovered "rogue" access points (default = 24 hours)
*
*/
getRogueAccessPoints(within = 24) {
return this._request('/api/s/<SITE>/stat/rogueap', {within});
}
/**
* List known rogue access points - list_known_rogueaps()
*
* returns an array of known rogue access point objects
*/
getKnownRogueAccessPoints() {
return this._request('/api/s/<SITE>/rest/rogueknown');
}
/**
* Generate a backup - generate_backup()
*
* returns a URL from where the backup file can be downloaded once generated
*
* NOTES: this is an experimental function, please do not use unless you know
* exactly what you're doing
*/
generateBackup() {
return this._request('/api/s/<SITE>/cmd/backup', {cmd: 'backup'});
}
/**
* List auto backups - list_backups()
*
* return an array containing objects with backup details on success
*/
getBackups() {
return this._request('/api/s/<SITE>/cmd/backup', {cmd: 'list-backups'});
}
/**
* Generate a backup/export of the current site - generate_backup_site()
*
* NOTES: this is an experimental function, please do not use unless you know
* exactly what you're doing
*/
generateBackupSite() {
return this._request('/api/s/<SITE>/cmd/backup', {cmd: 'export-site'});
}
/**
* Delete a backup file
*
* return true on success
* required parameter <filename> = string; filename of backup to delete
*/
deleteBackup(filename) {
return this._request('/api/s/<SITE>/cmd/backup', {cmd: 'delete-backup', filename});
}
/**
* List sites
*
* calls callback function(err, result) with an array of the sites
* registered to the UniFi controller
*/
getSites() {
return this._request('/api/self/sites');
}
/**
* List sites stats
*
* calls callback function(err, result) with an array of sysinfo information
* for all sites registered to the UniFi controller
*
* NOTES: endpoint was introduced with controller version 5.2.9
*/
getSitesStats() {
return this._request('/api/stat/sites');
}
/**
* Create a site - create_site()
*
* required parameter <description> = the long name for the new site
*
* NOTES: immediately after being added, the new site is available in the output of the "list_sites" function
*/
createSite(description) {
const payload = {desc: description,
cmd: 'add-site'};
return this._request('/api/s/<SITE>/cmd/sitemgr', payload);
}
/**
* Delete a site - delete_site()
*
* return true on success
* required parameter <site_id> = 24 char string; _id value of the site to delete
*
*/
deleteSite(site_id) {
const payload = {site: site_id,
cmd: 'delete-site'};
return this._request('/api/s/<SITE>/cmd/sitemgr', payload);
}
/**
* Change the current site's name - set_site_name()
*
* return true on success
* required parameter <site_name> = string; the new long name for the current site
*
* NOTES: immediately after being changed, the site is available in the output of the list_sites() function
*/
setSiteName(site_name) {
const payload = {desc: site_name,
cmd: 'update-site'};
return this._request('/api/s/<SITE>/cmd/sitemgr', payload);
}
/**
* Set site country - set_site_country()
*
* required parameter <payload> = stdClass object or associative array containing the configuration to apply to the network, must be a (partial)
* object structured in the same manner as is returned by list_settings() for the "country" key.
* Valid country codes can be obtained using the list_country_codes() function/method.
* Do not include the _id property, it is assigned by the controller and returned upon success.
* return true on success
*/
setSiteCountry(country_id, payload) {
return this._request('/api/s/<SITE>/rest/setting/country/' + country_id.trim(), payload, 'PUT');
}
/**
* Set site locale - set_site_locale()
*
* required parameter <payload> = stdClass object or associative array containing the configuration to apply to the network, must be a (partial)
* object structured in the same manner as is returned by list_settings() for the "locale" key.
* Do not include the _id property, it is assigned by the controller and returned upon success.
* return true on success
*/
setSiteLocale(locale_id, payload) {
return this._request('/api/s/<SITE>/rest/setting/locale/' + locale_id.trim(), payload, 'PUT');
}
/**
* Set site snmp - set_site_snmp()
*
* required parameter <payload> = stdClass object or associative array containing the configuration to apply to the network,