Network
banshee/network-collection/network/unifi/https/network-9/
devices
The devices of a UniFi site by the API of UniFi Network 9 on UniFi OS: state, firmware and update of each access point, switch and gateway.
by banshee1 installation2 versions
// The devices of a UniFi site, by the API of UniFi Network 9 and later on a UniFi OS console (Dream
// Machine, Cloud Key, Cloud Gateway, UniFi OS Server): the state of each access point, switch and gateway
// the site adopted, the firmware it runs, and whether an update is available. A device is named by its
// name, or by its MAC address when it has none. The console is read with an API key, which UniFi Network
// creates from version 9; it goes in the header X-API-KEY, never in a value returned.
need('protocol:http');
$key = need('protocol:http:token');
$base = variable('unifi:url', 'text', array(
'label' => 'Console address',
'help' => 'The address of the UniFi OS console, without a slash at the end, for instance https://unifi.example.',
));
$site = variable('unifi:site', 'text', array(
'label' => 'Site',
'help' => 'The short name of the site, the one its address shows (default for the first site).',
'default' => 'default',
));
per('device', 'Devices');
output('state', 'text', array('label' => 'State', 'per' => 'device'));
output('version', 'text', array('label' => 'Firmware', 'per' => 'device'));
output('update', 'text', array('label' => 'Firmware update', 'per' => 'device'));
output('devices', 'number', array('label' => 'Devices'));
watch.expect('not-connected', 'Device not connected', 'state', array(
'help' => 'Critical when a device stays in another state than connected: disconnected, heartbeat missed, adoption failed. An upgrade passes within three runs.',
'critical' => array('connected'),
'for' => '3 runs',
));
watch.state('update-available', 'Firmware update available', 'update', array('warning' => array('available'), 'enabled' => false));
watch.missing('missing', 'Missing device', 'state', array('enabled' => false));
// The device list of the site, under the Network application of the console.
$answer = http.get($base . '/proxy/network/api/s/' . url.encode($site) . '/stat/device', headers=array(
'X-API-KEY' => $key,
'Accept' => 'application/json',
));
if ($answer['status'] == 401 || $answer['status'] == 403) {
fail('misconfigured', 'API key refused by the console, code ' . $answer['status']);
}
if ($answer['status'] != 200) {
fail('unreachable', 'Device list unreadable, code ' . $answer['status']);
}
// {"meta": {"rc": "ok"}, "data": [{"name": "ap-hall", "mac": "...", "state": 1, "version": "6.6.77",
// "upgradable": false}, ...]}. The states are those the community libraries of the API agree on: UniFi
// does not publish them.
$states = array(
0 => 'disconnected', 1 => 'connected', 2 => 'pending', 4 => 'upgrading', 5 => 'provisioning',
6 => 'heartbeat-missed', 7 => 'adopting',
);
$list = json.read($answer['body']);
$count = 0;
foreach (list.get($list, 'data', array()) as $device) {
$name = list.get($device, 'name', '');
if ($name == '') {
$name = list.get($device, 'mac', 'device ' . $count);
}
$count = $count + 1;
$state = 'state ' . list.get($device, 'state', 'unknown');
if (list.has($states, list.get($device, 'state', ''))) {
$state = $states[$device['state']];
}
value('state', $state, $name);
if (list.get($device, 'version', '') != '') {
value('version', $device['version'], $name);
}
$update = 'none';
if (list.get($device, 'upgradable', false)) {
$update = 'available';
}
value('update', $update, $name);
}
value('devices', $count);