Skip to content

Commit

Permalink
Added console logger if a logger is not provided
Browse files Browse the repository at this point in the history
  • Loading branch information
NorthernMan54 committed Dec 3, 2024
1 parent 0d08e1d commit bcd63d1
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 72 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ All notable changes to `@homebridge/hap-client` will be documented in this file.
- Minor tweak to serviceName, and if the name is blank, use the name value from Accessory Information
- Fixed issue of error handler triggering error when attempting to connect to a homebridge instance that is down
- Added restart of monitor when client connections close
- Added console logging if a logger is not provided

## v2.0.4 (2024-11-07)

Expand Down
143 changes: 76 additions & 67 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,18 @@ export class HapClient extends EventEmitter {
private browser: Browser;
private discoveryInProgress = false;

private logger;
private logger: any;
private pin: string;
private debugEnabled: boolean;
private debugEnabled: boolean = false;
private config: {
debug?: boolean;
instanceBlacklist?: string[];
};

private instances: HapInstance[] = [];

private hiddenServices = [
Services.AccessoryInformation,
];

private hiddenCharacteristics = [
Characteristics.Name,
];
private hiddenServices = [Services.AccessoryInformation];
private hiddenCharacteristics = [Characteristics.Name];

private resetInstancePoolTimeout: NodeJS.Timeout | undefined = undefined;
private startDiscoveryTimeout: NodeJS.Timeout | undefined = undefined;
Expand All @@ -47,26 +42,46 @@ export class HapClient extends EventEmitter {
config: any;
}) {
super();

this.pin = opts.pin;
this.logger = opts.logger;
this.debugEnabled = opts.config.debug;
this.logger = opts.logger || console; // Fallback to console if no logger is provided
this.debugEnabled = !!opts.config.debug;
this.config = opts.config;
this.startDiscovery();
}

debug(msg) {
if (this.debugEnabled) {
const error = new Error();
const stackLines = error.stack.split('\n');
const callerInfo = stackLines[2]; // Line 2 contains the caller information
this.logger.log(msg + ' @ ' + callerInfo.trim());
/**
* Unified logging method.
*/
private logMessage(level: 'debug' | 'info' | 'warn' | 'error', msg: string, includeStack = false) {
if (!this.logger || typeof this.logger[level] !== 'function') {
return;
}

const message = includeStack
? `${msg} @ ${new Error().stack?.split('\n')[3]?.trim()}`
: msg;

if (level === 'debug' && !this.debugEnabled) return;
this.logger[level](message);
}

/**
* resetInstancePool - Reset the instance pool, useful for when a Homebridge instance is restarted
*/
debug(msg: string) {
this.logMessage('debug', msg, true);
}

info(msg: string) {
this.logMessage('info', msg);
}

warn(msg: string) {
this.logMessage('warn', msg);
}

error(msg: string) {
this.logMessage('error', msg);
}

// Example usage in methods
public resetInstancePool() {
if (this.discoveryInProgress) {
this.browser.stop();
Expand All @@ -76,8 +91,7 @@ export class HapClient extends EventEmitter {
}

this.instances = [];

this.resetInstancePoolTimeout = setTimeout(() => { // Give homebridge a few seconds to restart before we start discovery again
this.resetInstancePoolTimeout = setTimeout(() => {
this.refreshInstances();
}, 6000);
}
Expand Down Expand Up @@ -234,15 +248,13 @@ export class HapClient extends EventEmitter {
accessories.push(accessory);
}
} catch (e) {
if (this.logger) {
instance.connectionFailedCount++;
this.debug(`[HapClient] [${instance.ipAddress}:${instance.port} (${instance.username})] Failed to connect`);

if (instance.connectionFailedCount > 5) {
const instanceIndex = this.instances.findIndex(x => x.username === instance.username && x.ipAddress === instance.ipAddress);
this.instances.splice(instanceIndex, 1);
this.debug(`[HapClient] [${instance.ipAddress}:${instance.port} (${instance.username})] Removed From Instance Pool`);
}
instance.connectionFailedCount++;
this.debug(`[HapClient] [${instance.ipAddress}:${instance.port} (${instance.username})] Failed to connect`);

if (instance.connectionFailedCount > 5) {
const instanceIndex = this.instances.findIndex(x => x.username === instance.username && x.ipAddress === instance.ipAddress);
this.instances.splice(instanceIndex, 1);
this.debug(`[HapClient] [${instance.ipAddress}:${instance.port} (${instance.username})] Removed From Instance Pool`);
}
}
}
Expand Down Expand Up @@ -429,7 +441,9 @@ export class HapClient extends EventEmitter {
return service;
} catch (e) {
this.debug(`[HapClient] +${e}`);
this.logger.error(`[HapClient] Failed to refresh characteristics for ${service.serviceName}: ${e.message}`);

this.error(`[HapClient] Failed to refresh characteristics for ${service.serviceName}: ${e.message}`);

}
}

Expand All @@ -448,7 +462,9 @@ export class HapClient extends EventEmitter {
return characteristic;
} catch (e) {
this.debug(`[HapClient] +${e}`);
this.logger.error(`[HapClient] Failed to get characteristics for ${service.serviceName} with iid ${iid}: ${e.message}`);

this.error(`[HapClient] Failed to get characteristic for ${service.serviceName} with iid ${iid}: ${e.message}`);

}
}

Expand Down Expand Up @@ -480,21 +496,19 @@ export class HapClient extends EventEmitter {
);
return this.getCharacteristic(service, iid);
} catch (e) {
if (this.logger) {
this.logger.error(`[HapClient] [${service.instance.ipAddress}:${service.instance.port} (${service.instance.username})] ` +
`Failed to set value for ${service.serviceName}.`);
if (e.response && e.response?.status === 470 || e.response?.status === 401) {
this.logger.warn(`[HapClient] [${service.instance.ipAddress}:${service.instance.port} (${service.instance.username})] ` +
`Make sure Homebridge pin for this instance is set to ${this.pin}.`);
throw new Error(`Failed to control accessory. Make sure the Homebridge pin for ${service.instance.ipAddress}:${service.instance.port} ` +
`is set to ${this.pin}.`);
} else {
this.logger.error(e.message);
throw new Error(`Failed to control accessory: ${e.message}`);
}

this.error(`[HapClient] [${service.instance.ipAddress}:${service.instance.port} (${service.instance.username})] ` +
`Failed to set value for ${service.serviceName}.`);
if (e.response && e.response?.status === 470 || e.response?.status === 401) {
this.warn(`[HapClient] [${service.instance.ipAddress}:${service.instance.port} (${service.instance.username})] ` +
`Make sure Homebridge pin for this instance is set to ${this.pin}.`);
throw new Error(`Failed to control accessory. Make sure the Homebridge pin for ${service.instance.ipAddress}:${service.instance.port} ` +
`is set to ${this.pin}.`);
} else {
console.log(e);
this.error(e.message);
throw new Error(`Failed to control accessory: ${e.message}`);
}

}
}

Expand All @@ -514,31 +528,26 @@ export class HapClient extends EventEmitter {
if (resp.status === 200) {
return resp.data;
} else {
if (this.logger) {
this.logger.warn(`[HapClient] getResource [${service.instance.ipAddress}:${service.instance.port} (${service.instance.username})] ` +
`Failed to request resource from accessory ${service.serviceName}. Response status Code ${resp.status}`);
} else {
console.log(`[HapClient] getResource [${service.instance.ipAddress}:${service.instance.port} (${service.instance.username})] ` +
`Failed to request resource from accessory ${service.serviceName}. Response status Code ${resp.status}`)
}

this.warn(`[HapClient] getResource [${service.instance.ipAddress}:${service.instance.port} (${service.instance.username})] ` +
`Failed to request resource from accessory ${service.serviceName}. Response status Code ${resp.status}`);

}
return;
} catch (e) {
if (this.logger) {
this.logger.error(`[HapClient] [${service.instance.ipAddress}:${service.instance.port} (${service.instance.username})] ` +
`Failed to request resource from accessory ${service.serviceName}.`);
if (e.response && e.response?.status === 470 || e.response?.status === 401) {
this.logger.warn(`[HapClient] [${service.instance.ipAddress}:${service.instance.port} (${service.instance.username})] ` +
`Make sure Homebridge pin for this instance is set to ${this.pin}.`);
throw new Error(`Failed to request resource from accessory. Make sure the Homebridge pin for ${service.instance.ipAddress}:${service.instance.port} ` +
`is set to ${this.pin}.`);
} else {
this.logger.error(e.message);
throw new Error(`Failed to request resource: ${e.message}`);
}

this.error(`[HapClient] [${service.instance.ipAddress}:${service.instance.port} (${service.instance.username})] ` +
`Failed to request resource from accessory ${service.serviceName}.`);
if (e.response && e.response?.status === 470 || e.response?.status === 401) {
this.warn(`[HapClient] [${service.instance.ipAddress}:${service.instance.port} (${service.instance.username})] ` +
`Make sure Homebridge pin for this instance is set to ${this.pin}.`);
throw new Error(`Failed to request resource from accessory. Make sure the Homebridge pin for ${service.instance.ipAddress}:${service.instance.port} ` +
`is set to ${this.pin}.`);
} else {
console.log(e);
this.error(e.message);
throw new Error(`Failed to request resource: ${e.message}`);
}

}
}

Expand Down
18 changes: 13 additions & 5 deletions src/monitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ export class HapMonitor extends EventEmitter {
this.start();
}

log(message: string) {
this.logger?.log(`[HapMonitor] ${message}`);
}

error(message: string) {
this.logger?.log(`[HapMonitor] ERROR: ${message}`);
}

start() {
for (const instance of this.evInstances) {
this.connectInstance(instance);
Expand All @@ -45,10 +53,8 @@ export class HapMonitor extends EventEmitter {
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}.`);
}
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') {
Expand Down Expand Up @@ -93,7 +99,9 @@ export class HapMonitor extends EventEmitter {
});
} catch (e) {
this.debug(e);
this.logger.log(`Monitor Start Error [${instance.ipAddress}:${instance.port} (${instance.username})]: ${e.message}`);

this.error(`Monitor Start Error [${instance.ipAddress}:${instance.port} (${instance.username})]: ${e.message}`);

}
}

Expand Down

0 comments on commit bcd63d1

Please sign in to comment.