Files
unifi/ts/classes.devicemanager.ts

189 lines
5.0 KiB
TypeScript
Raw Permalink Normal View History

import type { UnifiController } from './classes.unifi-controller.js';
import { UnifiDevice } from './classes.device.js';
import type { INetworkDevice, IUnifiApiResponse } from './interfaces/index.js';
import { logger } from './unifi.logger.js';
/**
* Manager for UniFi network devices
*/
export class DeviceManager {
private controller: UnifiController;
constructor(controller: UnifiController) {
this.controller = controller;
}
/**
* List all devices for a site
*/
public async listDevices(siteId: string = 'default'): Promise<UnifiDevice[]> {
logger.log('debug', `Fetching devices for site: ${siteId}`);
const response = await this.controller.request<IUnifiApiResponse<INetworkDevice>>(
'GET',
`/api/s/${siteId}/stat/device`
);
const devices: UnifiDevice[] = [];
for (const deviceData of response.data || []) {
devices.push(UnifiDevice.createFromApiObject(deviceData, this.controller, siteId));
}
logger.log('info', `Found ${devices.length} devices`);
return devices;
}
/**
* Get a device by MAC address
*/
public async getDeviceByMac(mac: string, siteId: string = 'default'): Promise<UnifiDevice | null> {
const normalizedMac = mac.toLowerCase().replace(/[:-]/g, ':');
const devices = await this.listDevices(siteId);
return devices.find((device) => device.mac.toLowerCase() === normalizedMac) || null;
}
/**
* Get a device by ID
*/
public async getDeviceById(deviceId: string, siteId: string = 'default'): Promise<UnifiDevice | null> {
const devices = await this.listDevices(siteId);
return devices.find((device) => device._id === deviceId) || null;
}
/**
* Get access points only
*/
public async getAccessPoints(siteId: string = 'default'): Promise<UnifiDevice[]> {
const devices = await this.listDevices(siteId);
return devices.filter((device) => device.isAccessPoint());
}
/**
* Get switches only
*/
public async getSwitches(siteId: string = 'default'): Promise<UnifiDevice[]> {
const devices = await this.listDevices(siteId);
return devices.filter((device) => device.isSwitch());
}
/**
* Get gateways only
*/
public async getGateways(siteId: string = 'default'): Promise<UnifiDevice[]> {
const devices = await this.listDevices(siteId);
return devices.filter((device) => device.isGateway());
}
/**
* Get devices with available upgrades
*/
public async getUpgradableDevices(siteId: string = 'default'): Promise<UnifiDevice[]> {
const devices = await this.listDevices(siteId);
return devices.filter((device) => device.hasUpgrade());
}
/**
* Get offline devices
*/
public async getOfflineDevices(siteId: string = 'default'): Promise<UnifiDevice[]> {
const devices = await this.listDevices(siteId);
return devices.filter((device) => !device.isOnline());
}
/**
* Restart a device by MAC
*/
public async restartDevice(mac: string, siteId: string = 'default'): Promise<void> {
logger.log('info', `Restarting device: ${mac}`);
await this.controller.request(
'POST',
`/api/s/${siteId}/cmd/devmgr`,
{
cmd: 'restart',
mac: mac.toLowerCase(),
}
);
}
/**
* Upgrade a device's firmware
*/
public async upgradeDevice(mac: string, siteId: string = 'default'): Promise<void> {
logger.log('info', `Upgrading device: ${mac}`);
await this.controller.request(
'POST',
`/api/s/${siteId}/cmd/devmgr`,
{
cmd: 'upgrade',
mac: mac.toLowerCase(),
}
);
}
/**
* Adopt a device
*/
public async adoptDevice(mac: string, siteId: string = 'default'): Promise<void> {
logger.log('info', `Adopting device: ${mac}`);
await this.controller.request(
'POST',
`/api/s/${siteId}/cmd/devmgr`,
{
cmd: 'adopt',
mac: mac.toLowerCase(),
}
);
}
/**
* Forget a device (remove from controller)
*/
public async forgetDevice(mac: string, siteId: string = 'default'): Promise<void> {
logger.log('info', `Forgetting device: ${mac}`);
await this.controller.request(
'POST',
`/api/s/${siteId}/cmd/devmgr`,
{
cmd: 'delete-device',
mac: mac.toLowerCase(),
}
);
}
/**
* Locate device (flash LEDs)
*/
public async locateDevice(mac: string, enabled: boolean, siteId: string = 'default'): Promise<void> {
logger.log('info', `${enabled ? 'Locating' : 'Stop locating'} device: ${mac}`);
await this.controller.request(
'POST',
`/api/s/${siteId}/cmd/devmgr`,
{
cmd: enabled ? 'set-locate' : 'unset-locate',
mac: mac.toLowerCase(),
}
);
}
/**
* Force provision a device (push config)
*/
public async provisionDevice(mac: string, siteId: string = 'default'): Promise<void> {
logger.log('info', `Provisioning device: ${mac}`);
await this.controller.request(
'POST',
`/api/s/${siteId}/cmd/devmgr`,
{
cmd: 'force-provision',
mac: mac.toLowerCase(),
}
);
}
}