UNPKG

homebridge-meraki-control

Version:
152 lines (129 loc) 5.98 kB
import EventEmitter from 'events'; import ImpulseGenerator from './impulsegenerator.js'; import { ApiUrls } from './constants.js'; import { withLock } from './utils.js'; class MerakiDb extends EventEmitter { constructor(config) { super(); const networkId = config.networkId; this.clientsPolicy = config.deviceData; this.logDebug = config.logDebug; this.firstRun = true; this.dashboardClientsUrl = ApiUrls.DbClients.replace('networkId', networkId); this.client = config.client; //lock flags this.locks = false; this.impulseGenerator = new ImpulseGenerator() .on('connect', () => withLock(this, async () => { await this.connect(); })) .on('state', (state) => { this.emit(state ? 'success' : 'warn', `Impulse generator ${state ? 'started' : 'stopped'}`); }); }; async updateExistedClientsPolicy(configuredAndExistedClients) { if (this.logDebug) this.emit('debug', `Requesting existed client policy data.`); try { const exposedClients = []; for (const client of configuredAndExistedClients) { const clientId = client.id; const clientPolicyData = await this.client.get(`${this.dashboardClientsUrl}/${clientId}/policy`); if (this.logDebug) this.emit('debug', `Existed client policy data: ${JSON.stringify(clientPolicyData.data, null, 2)}`); const clientPolicyMac = clientPolicyData.data.mac; const clientPolicyPolicy = clientPolicyData.data.devicePolicy ?? 'undefined'; const clientPolicyState = clientPolicyPolicy !== 'Blocked'; //push exposed clients to array const obj = { 'id': clientId, 'name': client.name, 'policyType': client.type, 'mac': clientPolicyMac, 'policy': clientPolicyPolicy, 'policyState': clientPolicyState }; exposedClients.push(obj); }; //configured clients policy const clientsCount = exposedClients.length; if (this.logDebug) this.emit('debug', `Found: ${clientsCount} exposed clients.`); if (clientsCount === 0) { this.emit('warn', `Found: ${clientsCount} exposed clients.`); return false; }; //emit device info and state if (this.firstRun) { this.emit('deviceInfo', clientsCount); this.firstRun = false; } this.emit('deviceState', exposedClients, clientsCount); return true; } catch (error) { throw new Error(`Existed client policy data error: ${error}`); }; }; async updateConfiguredAndExistingClients(dbClients) { if (this.logDebug) this.emit('debug', `Check configured and active clients.`); try { //create exposed clientsPolicy const configuredAndExistedClients = []; for (const clientPolicy of this.clientsPolicy) { const mac = clientPolicy.mac; //check if configured client exist in dashboard const index = dbClients.findIndex(item => item.mac === mac); const id = index !== -1 ? dbClients[index].id : -1; //push existed clients if (index !== -1) { const obj = { 'name': clientPolicy.name, 'mac': clientPolicy.mac, 'type': clientPolicy.type, 'id': id } configuredAndExistedClients.push(obj); }; }; const configuredAndExistedClientsCount = configuredAndExistedClients.length; if (this.logDebug) this.emit('debug', `Found: ${configuredAndExistedClientsCount} configured and active clients.`); if (configuredAndExistedClientsCount === 0) { this.emit('warn', `Found: ${configuredAndExistedClientsCount} configured and active clients.`); return false; }; const state = await this.updateExistedClientsPolicy(configuredAndExistedClients); return state; } catch (error) { throw new Error(`Requesting configured clients error: ${error}`); }; }; async connect() { if (this.logDebug) this.emit('debug', `Requesting clients data.`); try { const dbClientsData = await this.client.get(`${this.dashboardClientsUrl}?perPage=255&timespan=2592000`); if (this.logDebug) this.emit('debug', `Clients data: ${JSON.stringify(dbClientsData.data, null, 2)}`); const dbClients = []; for (const dbClient of dbClientsData.data) { const id = dbClient.id; const mac = dbClient.mac.split(':').join(''); const description = dbClient.description; const obj = { 'id': id, 'mac': mac, 'description': description } dbClients.push(obj); } //exposed existings and configured clients const dbClientsCount = dbClients.length; if (this.logDebug) this.emit('debug', `Found: ${dbClientsCount} clients.`); if (dbClientsCount === 0) return false; const state = await this.updateConfiguredAndExistingClients(dbClients); return state; } catch (error) { throw new Error(`Requesting clients data error: ${error}`); }; }; async send(url, payload) { await this.client.put(url, payload); return true; }; }; export default MerakiDb;