Skip to content

Commit

Permalink
Improve logging after YoLink API errors
Browse files Browse the repository at this point in the history
  • Loading branch information
dkerr64 committed Aug 22, 2024
1 parent 300f28e commit ce3aa53
Show file tree
Hide file tree
Showing 20 changed files with 73 additions and 39 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"displayName": "Homebridge YoLink",
"name": "homebridge-yolink",
"version": "1.6.0",
"version": "1.6.1",
"description": "Connect to YoLink.",
"license": "Apache-2.0",
"repository": {
Expand Down
5 changes: 3 additions & 2 deletions src/coSmokeDetector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This will issue warning messages to the HomeBridge log that can then
* be provided to author to assist in adding device support.
*
* Copyright (c) 2023 David Kerr
* Copyright (c) 2023-2024 David Kerr
*
*/

Expand Down Expand Up @@ -165,7 +165,8 @@ async function handleGetBlocking(this: YoLinkPlatformAccessory, sensor = 'smoke'
break;
}
} else {
platform.log.error(`Device offline or other error for ${device.deviceMsgName}`);
platform.log.error(`[${device.deviceMsgName}] Device offline or other error`);
device.errorState = true;
this.coService?.updateCharacteristic(platform.Characteristic.StatusActive, false);
this.coService?.updateCharacteristic(platform.Characteristic.StatusFault, true);
this.smokeService?.updateCharacteristic(platform.Characteristic.StatusActive, false);
Expand Down
5 changes: 3 additions & 2 deletions src/contactDevice.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/***********************************************************************
* YoLink door sensor device support.
*
* Copyright (c) 2022 David Kerr
* Copyright (c) 2022-2024 David Kerr
*
*/

Expand Down Expand Up @@ -85,7 +85,8 @@ async function handleGetBlocking(this: YoLinkPlatformAccessory): Promise<Charact
}
this.logDeviceState(device, `Contact: ${device.data.state.state}, Battery: ${device.data.state.battery}`);
} else {
platform.log.error(`Device offline or other error for ${device.deviceMsgName}`);
platform.log.error(`[${device.deviceMsgName}] Device offline or other error`);
device.errorState = true;
this.contactService
.updateCharacteristic(platform.Characteristic.StatusActive, false)
.updateCharacteristic(platform.Characteristic.StatusFault, true);
Expand Down
6 changes: 4 additions & 2 deletions src/garageDoor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,14 @@ async function handleGetBlocking(this: YoLinkPlatformAccessory, device: YoLinkDe
// return value for target state must be open or closed, not opening or closing.
// 0=open, 1=closed, 2=opening, 3=closing, 4=stopped(not used)
rc = (rc > 1) ? rc - 2 : rc;
this.logDeviceState(device, `Garage Door or Finger: ${(device.data.battery) ? 'Battery: ' + device.data.battery : ''}, rc: ${rc}`);
// eslint-disable-next-line max-len
this.logDeviceState(device, `Garage Door or Finger: ${(device.data.battery) ? 'Battery: ' + device.data.battery + ', ' : ''}rc: ${rc}`);
} else {
this.logDeviceState(device, `Sensor: ${device.data.state.state}, Battery: ${device.data.state.battery}, rc: ${rc}`);
}
} else {
platform.log.error(`Device offline or other error for ${device.deviceMsgName}`);
platform.log.error(`[${device.deviceMsgName}] Device offline or other error`);
device.errorState = true;
}
} catch (e) {
const msg = (e instanceof Error) ? e.stack : e;
Expand Down
5 changes: 3 additions & 2 deletions src/hubDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Homebridge does not have a hub-like device. But we register it and
* log data about it.
*
* Copyright (c) 2022 David Kerr
* Copyright (c) 2022-2024 David Kerr
*
*/

Expand Down Expand Up @@ -35,7 +35,8 @@ async function handleGet(this: YoLinkPlatformAccessory): Promise<CharacteristicV
if( await this.checkDeviceState(platform, device) ) {
this.logDeviceState(device, `WiFi: ${device.data.wifi.enable}, Ethernet: ${device.data.eth.enable}`);
} else {
platform.log.error(`Device offline or other error for ${device.deviceMsgName}`);
platform.log.error(`[${device.deviceMsgName}] Device offline or other error`);
device.errorState = true;
}
} catch(e) {
const msg = (e instanceof Error) ? e.stack : e;
Expand Down
3 changes: 2 additions & 1 deletion src/infraredRemoter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* Support for the YoLink Infrared Remoter device
*
* Copyright (c) 2023 David Kerr
* Copyright (c) 2023-2024 David Kerr
*
*/

Expand Down Expand Up @@ -109,6 +109,7 @@ async function handleGet(this: YoLinkPlatformAccessory, keyNumber = -1): Promise
this.logDeviceState(device, `Key Number: ${keyNumber}${batteryMsg}`);
} else {
platform.log.error(`[${device.deviceMsgName}] Device offline or other error`);
device.errorState = true;
}
} catch (e) {
const msg = (e instanceof Error) ? e.stack : e;
Expand Down
5 changes: 3 additions & 2 deletions src/leakDevice.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/***********************************************************************
* YoLink leak sensor device support
*
* Copyright (c) 2022-2023 David Kerr
* Copyright (c) 2022-2024 David Kerr
*
*/

Expand Down Expand Up @@ -108,7 +108,8 @@ async function handleGetBlocking(this: YoLinkPlatformAccessory, devSensor = 'mai
`DevTemp: ${device.data.state.devTemperature}\u00B0C ` +
`(${(device.data.state.devTemperature * 9 / 5 + 32).toFixed(1)}\u00B0F)`);
} else {
platform.log.error(`Device offline or other error for ${device.deviceMsgName}`);
platform.log.error(`[${device.deviceMsgName}] Device offline or other error`);
device.errorState = true;
this.leakService
.updateCharacteristic(platform.Characteristic.StatusActive, false)
.updateCharacteristic(platform.Characteristic.StatusFault, true);
Expand Down
5 changes: 3 additions & 2 deletions src/lightbulbDevice.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/***********************************************************************
* YoLink dimmer switch device support (as a HomeKit lightbulb)
*
* Copyright (c) 2022 David Kerr
* Copyright (c) 2022-2024 David Kerr
*
*/

Expand Down Expand Up @@ -114,7 +114,8 @@ async function handleGetBlocking(this: YoLinkPlatformAccessory, mode = 'on'): Pr
return (device.data.state === this.onState);
}
} else {
platform.log.error(`Device offline or other error for ${device.deviceMsgName}`);
platform.log.error(`[${device.deviceMsgName}] Device offline or other error`);
device.errorState = true;
}
} catch (e) {
const msg = (e instanceof Error) ? e.stack : e;
Expand Down
5 changes: 3 additions & 2 deletions src/lockDevice.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/***********************************************************************
* YoLink lock device support
*
* Copyright (c) 2022 David Kerr
* Copyright (c) 2022-2024 David Kerr
*
*/

Expand Down Expand Up @@ -118,7 +118,8 @@ async function handleGetBlocking(this: YoLinkPlatformAccessory, requested = 'cur
this.logDeviceState(device, `Lock: ${device.data.state}${batteryMsg}`);
rc = (device.data.state === this.lockedState) ? 1 : 0;
} else {
platform.log.error(`Device offline or other error for ${device.deviceMsgName}`);
platform.log.error(`[${device.deviceMsgName}] Device offline or other error`);
device.errorState = true;
}

} catch (e) {
Expand Down
1 change: 1 addition & 0 deletions src/motionDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ async function handleGetBlocking(this: YoLinkPlatformAccessory, devSensor = 'mai
`(${(device.data.state.devTemperature * 9 / 5 + 32).toFixed(1)}\u00B0F)`);
} else {
platform.log.error(`[${device.deviceMsgName}] Device offline or other error`);
device.errorState = true;
this.motionService
.updateCharacteristic(platform.Characteristic.StatusActive, false)
.updateCharacteristic(platform.Characteristic.StatusFault, true);
Expand Down
5 changes: 3 additions & 2 deletions src/outletDevice.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/***********************************************************************
* YoLink outlet and multi-outlet device support
*
* Copyright (c) 2022-2023 David Kerr
* Copyright (c) 2022-2024 David Kerr
*
*/

Expand Down Expand Up @@ -165,7 +165,8 @@ async function handleGetBlocking(this: YoLinkPlatformAccessory, outlet = -1): Pr
return (device.data.state[outlet] === this.onState);
}
} else {
platform.log.error(`Device offline or other error for ${device.deviceMsgName}`);
platform.log.error(`[${device.deviceMsgName}] Device offline or other error`);
device.errorState = true;
}
} catch (e) {
const msg = (e instanceof Error) ? e.stack : e;
Expand Down
6 changes: 4 additions & 2 deletions src/platform.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/***********************************************************************
* YoLink Homebridge Platform class
*
* Copyright (c) 2022-2023 David Kerr
* Copyright (c) 2022-2024 David Kerr
*
* Based on https://github.com/homebridge/homebridge-plugin-template
*
Expand Down Expand Up @@ -43,6 +43,7 @@ export type YoLinkDevice = {
modelName: string;
deviceMsgName: string;
semaphore: Semaphore;
errorState: boolean;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any;
};
Expand Down Expand Up @@ -101,7 +102,8 @@ export class YoLinkHomebridgePlatform implements DynamicPlatformPlugin {
this.config.refreshAfter ??= YOLINK_REFRESH_INTERVAL;
this.config.checkNewDeviceInterval ??= 0;

this.log.info(`YoLink plugin for HomeBridge version ${packageJSON.version} (c) 2022-2023 David A. Kerr${this.reportError}`);
this.log.info(`YoLink plugin for Homebridge.\n\nVersion ${packageJSON.version}\n` +
`Copyright (c) 2022-2024 David A. Kerr${this.reportError}`);
this.verboseLog(`Loaded configuration:\n${JSON.stringify(this.config, null, 2)}`);

this.yolinkAPI = new YoLinkAPI(this);
Expand Down
22 changes: 15 additions & 7 deletions src/platformAccessory.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/***********************************************************************
* YoLink Platform Accessory class
*
* Copyright (c) 2022-2023 David Kerr
* Copyright (c) 2022-2024 David Kerr
*
* Based on https://github.com/homebridge/homebridge-plugin-template
*
Expand Down Expand Up @@ -142,7 +142,7 @@ export class YoLinkPlatformAccessory {
device.updateTime = timestamp + device.config.refreshAfter;
// reportAtTime is the earlier of the time stamp on this message, or
// or the time reported in the message from YoLink. We use this to
// only log (in like mode), when we have an update.
// only log (in lite mode), when we have an update.
const msgTime = new Date(parseInt(device.budp.msgid));
const repTime = new Date(device.data?.reportAt ?? '9999-12-31');
device.reportAtTime = (msgTime < repTime) ? msgTime : repTime;
Expand All @@ -153,15 +153,18 @@ export class YoLinkPlatformAccessory {
}
}
} catch (e) {
// Error condition could be a throw() by ourselves within yolinkAPI.ts
const msg = ((e instanceof Error) ? e.stack : e) as string;
const yolinkMsg = msg.substring(7, msg.indexOf(')') + 1);
const errCode = msg.split('YoLink API error code: ').pop()?.substring(0, 6);
if ((errCode === '000201') ||(errCode === '010301')|| (errCode === '000201')) {
if ((errCode === '000201') || (errCode === '010301') || (errCode === '000201')) {
// "YoLink API error code are rather common, so don't declare a problem
platform.liteLog(yolinkMsg + ' - retrying');
} else {
platform.log.warn('Error in checkDeviceState' + platform.reportError + msg);
}
// Set device errorState so that when we eventually recover, we will log state.
device.errorState = true;
}
return (device.data);
}
Expand All @@ -171,10 +174,15 @@ export class YoLinkPlatformAccessory {
*
*/
logDeviceState(this: YoLinkPlatformAccessory, device: YoLinkDevice, msg: string) {
// reportAtTime is the earlier of the time stamp on this message, or
// or the time reported in the message from YoLink. We use this to
// only log (in lite mode), when we have an update.
if (device.lastReportAtTime < device.reportAtTime.getTime()) {
if (device.errorState) {
// we had previously logged an error condition, if we are now logging
// device state we must have recovered from the error. Log that we recovered.
this.platform.log.info(`[${device.deviceMsgName}] At ${device.reportAtTime.toLocaleString()}: Error recovery: ${msg}`);
device.errorState = false;
} else if (device.lastReportAtTime < device.reportAtTime.getTime()) {
// reportAtTime is the earlier of the time stamp on this message, or
// or the time reported in the message from YoLink. We use this to
// only log (in lite mode), when we have an update.
device.lastReportAtTime = device.reportAtTime.getTime();
this.platform.liteLog(`[${device.deviceMsgName}] At ${device.reportAtTime.toLocaleString()}: Device state updated: ${msg}`);
} else {
Expand Down
5 changes: 3 additions & 2 deletions src/powerDevice.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/***********************************************************************
* YoLink Power Failure Alarm sensor device support.
*
* Copyright (c) 2022 David Kerr
* Copyright (c) 2022-2024 David Kerr
*
*/

Expand Down Expand Up @@ -114,7 +114,8 @@ async function handleGetBlocking(this: YoLinkPlatformAccessory): Promise<Charact
this.logDeviceState(device, `Power OK: ${device.data.state.powerSupply}, ` +
`State: ${device.data.state.state}, Battery: ${device.data.state.battery}`);
} else {
platform.log.error(`Device offline or other error for ${device.deviceMsgName}`);
platform.log.error(`[${device.deviceMsgName}] Device offline or other error`);
device.errorState = true;
if (this.contactService) {
this.contactService
.updateCharacteristic(platform.Characteristic.StatusActive, false)
Expand Down
3 changes: 2 additions & 1 deletion src/statelessSwitch.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/***********************************************************************
* YoLink smart remote device support (as a HomeKit stateless switch)
*
* Copyright (c) 2022-2023 David Kerr
* Copyright (c) 2022-2024 David Kerr
*
*/

Expand Down Expand Up @@ -132,6 +132,7 @@ async function handleGetBlocking(this: YoLinkPlatformAccessory, devSensor = 'mai
`(${(device.data.state.devTemperature * 9 / 5 + 32).toFixed(1)}\u00B0F)`);
} else {
platform.log.error(`[${device.deviceMsgName}] Device offline or other error`);
device.errorState = true;
}
} catch (e) {
const msg = (e instanceof Error) ? e.stack : e;
Expand Down
5 changes: 3 additions & 2 deletions src/switchDevice.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/***********************************************************************
* YoLink siren/switch/garage door/finger device support (as a HomeKit switch)
*
* Copyright (c) 2022 David Kerr
* Copyright (c) 2022-2024 David Kerr
*
*/

Expand Down Expand Up @@ -113,7 +113,8 @@ async function handleGetBlocking(this: YoLinkPlatformAccessory): Promise<Charact
rc = true;
}
} else {
platform.log.error(`Device offline or other error for ${device.deviceMsgName}`);
platform.log.error(`[${device.deviceMsgName}] Device offline or other error`);
device.errorState = true;
}

} catch (e) {
Expand Down
5 changes: 3 additions & 2 deletions src/thermoHydroDevice.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/***********************************************************************
* YoLink temperature / humidity sensor device support
*
* Copyright (c) 2022-2023 David Kerr
* Copyright (c) 2022-2024 David Kerr
*
*/

Expand Down Expand Up @@ -132,7 +132,8 @@ async function handleGetBlocking(this: YoLinkPlatformAccessory, sensor = 'thermo
}
rc = (sensor === 'hydro') ? device.data.state.humidity : device.data.state.temperature;
} else {
platform.log.error(`Device offline or other error for ${device.deviceMsgName}`);
platform.log.error(`[${device.deviceMsgName}] Device offline or other error`);
device.errorState = true;
this.thermoService?.updateCharacteristic(platform.Characteristic.StatusActive, false);
this.thermoService?.updateCharacteristic(platform.Characteristic.StatusFault, true);
this.hydroService?.updateCharacteristic(platform.Characteristic.StatusActive, false);
Expand Down
5 changes: 3 additions & 2 deletions src/unknownDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This will issue warning messages to the HomeBridge log that can then
* be provided to author to assist in adding device support.
*
* Copyright (c) 2022 David Kerr
* Copyright (c) 2022-2024 David Kerr
*
*/

Expand Down Expand Up @@ -42,7 +42,8 @@ async function handleGet(this: YoLinkPlatformAccessory): Promise<CharacteristicV
+ platform.reportError + JSON.stringify(device.data, null, 2));

} else {
platform.log.error(`Device offline or other error for ${device.deviceMsgName}`);
platform.log.error(`[${device.deviceMsgName}] Device offline or other error`);
device.errorState = true;
}
} catch (e) {
const msg = (e instanceof Error) ? e.stack : e;
Expand Down
3 changes: 2 additions & 1 deletion src/valveDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,8 @@ async function handleGetBlocking(this: YoLinkPlatformAccessory, devSensor = 'val
break;
}
} else {
platform.log.error(`Device offline or other error for ${device.deviceMsgName}`);
platform.log.error(`[${device.deviceMsgName}] Device offline or other error`);
device.errorState = true;
this.valveService
.updateCharacteristic(platform.Characteristic.StatusFault, true);
}
Expand Down
Loading

0 comments on commit ce3aa53

Please sign in to comment.