From ef8a09e99280caa2e4e25e7c6cedee053c27864a Mon Sep 17 00:00:00 2001 From: Northern Man <19808920+NorthernMan54@users.noreply.github.com> Date: Fri, 29 Nov 2024 13:38:12 -0500 Subject: [PATCH] Improved Resilliancy --- src/index.ts | 2 + src/monitor.ts | 105 +++++++++++++++++++++++++++---------------------- 2 files changed, 59 insertions(+), 48 deletions(-) diff --git a/src/index.ts b/src/index.ts index 78e223e..b5f3792 100644 --- a/src/index.ts +++ b/src/index.ts @@ -69,6 +69,7 @@ export class HapClient extends EventEmitter { this.browser.stop(); this.debug(`[HapClient] Discovery :: Terminated`); this.discoveryInProgress = false; + this.emit('discovery-ended'); } this.instances = []; @@ -108,6 +109,7 @@ export class HapClient extends EventEmitter { this.browser.stop(); this.debug(`[HapClient] Discovery :: Ended`); this.discoveryInProgress = false; + this.emit('discovery-ended'); }, 60000); // service found diff --git a/src/monitor.ts b/src/monitor.ts index e9398a0..eeb9b0a 100644 --- a/src/monitor.ts +++ b/src/monitor.ts @@ -30,64 +30,72 @@ export class HapMonitor extends EventEmitter { start() { for (const instance of this.evInstances) { - instance.socket = createConnection(instance, this.pin, { characteristics: instance.evCharacteristics }); + try { + instance.socket = createConnection(instance, this.pin, { characteristics: instance.evCharacteristics }); - this.debug(`[HapClient] [${instance.ipAddress}:${instance.port} (${instance.username})] Connected`); + this.debug(`[HapClient] [${instance.ipAddress}:${instance.port} (${instance.username})] Connected`); - instance.socket.on('data', (data) => { - const message = parseMessage(data); + instance.socket.on('data', (data) => { + const message = parseMessage(data); - if (message.statusCode === 401) { - if (this.logger) { - this.debug(`[HapClient] [${instance.ipAddress}:${instance.port} (${instance.username})] ` + - `${message.statusCode} ${message.statusMessage} - make sure Homebridge pin for this instance is set to ${this.pin}.`); + if (message.statusCode === 401) { + if (this.logger) { + this.debug(`[HapClient] [${instance.ipAddress}:${instance.port} (${instance.username})] ` + + `${message.statusCode} ${message.statusMessage} - make sure Homebridge pin for this instance is set to ${this.pin}.`); + } } - } - if (message.protocol === 'EVENT') { - try { - const body = JSON.parse(message.body); - if (body.characteristics && body.characteristics.length) { - this.debug(`[HapClient] [${instance.ipAddress}:${instance.port} (${instance.username})] ` + - `Got Event: ${JSON.stringify(body.characteristics)}`); - - const response = body.characteristics.map((c) => { - // find the matching service for each characteristics - const services = this.services.filter(x => x.aid === c.aid && x.instance.username === instance.username); - const service = services.find(x => x.serviceCharacteristics.find(y => y.iid === c.iid)); - - if (service) { - // find the correct characteristic and update it - const characteristic = service.serviceCharacteristics.find(x => x.iid === c.iid); - if (characteristic) { - characteristic.value = c.value; - service.values[characteristic.type] = c.value; - return service; + if (message.protocol === 'EVENT') { + try { + const body = JSON.parse(message.body); + if (body.characteristics && body.characteristics.length) { + this.debug(`[HapClient] [${instance.ipAddress}:${instance.port} (${instance.username})] ` + + `Got Event: ${JSON.stringify(body.characteristics)}`); + + const response = body.characteristics.map((c) => { + // find the matching service for each characteristics + const services = this.services.filter(x => x.aid === c.aid && x.instance.username === instance.username); + const service = services.find(x => x.serviceCharacteristics.find(y => y.iid === c.iid)); + + if (service) { + // find the correct characteristic and update it + const characteristic = service.serviceCharacteristics.find(x => x.iid === c.iid); + if (characteristic) { + characteristic.value = c.value; + service.values[characteristic.type] = c.value; + return service; + } } - } - }); + }); - // push update to listeners - this.emit('service-update', response.filter(x => x)); + // push update to listeners + this.emit('service-update', response.filter(x => x)); + } + } catch (e) { + // do nothing } - } catch (e) { - // do nothing } - } - }); - let closeTimeout: NodeJS.Timeout | null = null; - instance.socket.on('close', (data) => { - this.emit('monitor-close', data); - if (closeTimeout) { - clearTimeout(closeTimeout); // Clear the existing timeout - } - closeTimeout = setTimeout(() => { - this.finish(); - this.start(); - closeTimeout = null; // Reset the timeout - }, 10000); // 10-second debounce period - }); + }); + let closeTimeout = null; + instance.socket.on('close', (data) => { + this.emit('monitor-close', data); + if (!closeTimeout) { + closeTimeout = setTimeout(() => { + this.finish(); + this.start(); + closeTimeout = null; + }, 10000); + } + }); + instance.socket.on('error', (data) => { + this.emit('monitor-error', data); + this.debug(`ERROR: monitor-error ${data}`); + }); + } catch (e) { + this.debug(e); + this.logger.log(`Monitor Start Error [${instance.ipAddress}:${instance.port} (${instance.username})]: ${e.message}`); + } } } @@ -96,6 +104,7 @@ export class HapMonitor extends EventEmitter { if (instance.socket) { try { instance.socket.destroy(); + instance.socket.removeAllListeners(); this.debug(`[HapClient] [${instance.ipAddress}:${instance.port} (${instance.username})] Disconnected`); } catch (e) { // do nothing