diff --git a/CHANGELOG.md b/CHANGELOG.md index 78e5c784..f8eddf12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ All notable changes to this project will be documented in this file. This project uses [Semantic Versioning](https://semver.org/) +## [Version 2.1.1](https://github.com/OpenWonderLabs/homebridge-switchbot/releases/tag/v2.1.1) (2022-10-14) + +## What's Changed + +- Fixed issue were `CustomOff` would send incorrect commands. Also Resolves [#409](https://github.com/OpenWonderLabs/homebridge-switchbot/issues/409). +- Fixed issue were IR Commands were not sent from IR Devices, Thanks [@jonzhan](https://github.com/jonzhan). [#520](https://github.com/OpenWonderLabs/homebridge-switchbot/issues/520) +- Fixed issue with Curtain not refreshing moving status. [#517](https://github.com/OpenWonderLabs/homebridge-switchbot/issues/517) +- Housekeeping and updated dependencies. + +**Full Changelog**: https://github.com/OpenWonderLabs/homebridge-switchbot/compare/v2.1.0...v2.1.1 + ## [Version 2.1.0](https://github.com/OpenWonderLabs/homebridge-switchbot/releases/tag/v2.1.0) (2022-10-13) ## What's Changed diff --git a/package-lock.json b/package-lock.json index 52364349..81c8a8b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@switchbot/homebridge-switchbot", - "version": "2.1.0", + "version": "2.1.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@switchbot/homebridge-switchbot", - "version": "2.1.0", + "version": "2.1.1", "funding": [ { "type": "Paypal", diff --git a/package.json b/package.json index d03e3454..577cc7dc 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "displayName": "Homebridge SwitchBot", "name": "@switchbot/homebridge-switchbot", - "version": "2.1.0", + "version": "2.1.1", "description": "The [Homebridge](https://homebridge.io) SwitchBot plugin allows you to access your [SwitchBot](https://www.switch-bot.com) device(s) from HomeKit.", "author": "SwitchBot (https://github.com/SwitchBot)", "license": "ISC", diff --git a/src/device/curtain.ts b/src/device/curtain.ts index b4fce760..32bb48fb 100644 --- a/src/device/curtain.ts +++ b/src/device/curtain.ts @@ -180,7 +180,7 @@ export class Curtain { // update slide progress interval(this.updateRate * 1000) - .pipe(skipWhile(() => this.curtainUpdateInProgress)) + //.pipe(skipWhile(() => this.curtainUpdateInProgress)) .subscribe(async () => { if (this.PositionState === this.platform.Characteristic.PositionState.STOPPED) { return; @@ -652,7 +652,7 @@ export class Curtain { } } catch (e: any) { this.apiError(e); - this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushBrightnessChanges with ${this.device.connectionType}` + this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}` + ` Connection, Error Message: ${superStringify(e.message)}`, ); } diff --git a/src/irdevice/airconditioner.ts b/src/irdevice/airconditioner.ts index 2d7aac19..3c9a5cfe 100644 --- a/src/irdevice/airconditioner.ts +++ b/src/irdevice/airconditioner.ts @@ -45,10 +45,10 @@ export class AirConditioner { constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: irdevice & irDevicesConfig) { // default placeholders - this.logs(device); - this.config(device); - this.pushOnChanges(device); - this.context(device); + this.logs({ device }); + this.config({ device }); + this.pushOnChanges({ device }); + this.context({ device }); // set accessory information accessory @@ -56,9 +56,9 @@ export class AirConditioner { .setCharacteristic(this.platform.Characteristic.Manufacturer, 'SwitchBot') .setCharacteristic(this.platform.Characteristic.Model, device.remoteType) .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!) - .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision(accessory, device)) + .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision({ accessory, device })) .getCharacteristic(this.platform.Characteristic.FirmwareRevision) - .updateValue(this.FirmwareRevision(accessory, device)); + .updateValue(this.FirmwareRevision({ accessory, device })); // get the Television service if it exists, otherwise create a new Television service // you can create multiple services for each accessory @@ -238,7 +238,7 @@ export class AirConditioner { await this.pushChanges(body); } - async pushChanges(body): Promise { + async pushChanges(body: any): Promise { if (this.device.connectionType === 'OpenAPI') { try { // Make Push On request to the API @@ -285,7 +285,7 @@ export class AirConditioner { this.accessory.context.CoolingThresholdTemperature = this.CoolingThresholdTemperature; this.updateHomeKitCharacteristics(); } catch (e: any) { - this.apiError(e); + this.apiError({ e }); this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,` + ` Error Message: ${superStringify(e.message)}`, ); @@ -334,8 +334,6 @@ export class AirConditioner { async ActiveSet(value: CharacteristicValue): Promise { this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Set Active: ${value}`); - this.Active = value; - this.accessory.context.Active = this.Active; if (value === this.platform.Characteristic.Active.INACTIVE) { this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushAirConditionerOffChanges, Active: ${this.Active}`); this.pushAirConditionerOffChanges(); @@ -347,6 +345,12 @@ export class AirConditioner { this.pushAirConditionerStatusChanges(); } } + /** + * pushAirConditionerOnChanges and pushAirConditionerOffChanges above assume they are measuring the state of the accessory BEFORE + * they are updated, so we are only updating the accessory state after calling the above. + */ + this.Active = value; + this.accessory.context.Active = this.Active; } async TargetHeaterCoolerStateGet(): Promise { @@ -557,7 +561,7 @@ export class AirConditioner { } } - async commandType() { + async commandType(): Promise { let commandType: string; if (this.device.customize) { commandType = 'customize'; @@ -567,7 +571,7 @@ export class AirConditioner { return commandType; } - async commandOn() { + async commandOn(): Promise { let command: string; if (this.device.customize && this.device.customOn) { command = this.device.customOn; @@ -577,10 +581,10 @@ export class AirConditioner { return command; } - async commandOff() { + async commandOff(): Promise { let command: string; - if (this.device.customize && this.device.customOn) { - command = this.device.customOn; + if (this.device.customize && this.device.customOff) { + command = this.device.customOff; } else { command = 'turnOff'; } @@ -618,7 +622,7 @@ export class AirConditioner { } } - async apiError(e: any): Promise { + async apiError({ e }: { e: any; }): Promise { this.coolerService.updateCharacteristic(this.platform.Characteristic.Active, e); this.coolerService.updateCharacteristic(this.platform.Characteristic.RotationSpeed, e); this.coolerService.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, e); @@ -628,7 +632,7 @@ export class AirConditioner { this.coolerService.updateCharacteristic(this.platform.Characteristic.CoolingThresholdTemperature, e); } - FirmwareRevision(accessory: PlatformAccessory, device: irdevice & irDevicesConfig): string { + FirmwareRevision({ accessory, device }: { accessory: PlatformAccessory; device: irdevice & irDevicesConfig; }): string { let FirmwareRevision: string; this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName}` + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`); @@ -644,7 +648,7 @@ export class AirConditioner { return FirmwareRevision; } - async context(device: irdevice & irDevicesConfig) { + async context({ device }: { device: irdevice & irDevicesConfig; }): Promise { if (this.Active === undefined) { this.Active = this.platform.Characteristic.Active.INACTIVE; } else { @@ -664,7 +668,7 @@ export class AirConditioner { } } - async config(device: irdevice & irDevicesConfig): Promise { + async config({ device }: { device: irdevice & irDevicesConfig; }): Promise { let config = {}; if (device.irair) { config = device.irair; @@ -683,7 +687,7 @@ export class AirConditioner { } } - async logs(device: irdevice & irDevicesConfig): Promise { + async logs({ device }: { device: irdevice & irDevicesConfig; }): Promise { if (this.platform.debugMode) { this.deviceLogging = this.accessory.context.logging = 'debugMode'; this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`); @@ -700,7 +704,7 @@ export class AirConditioner { } - async pushOnChanges(device: irdevice & irDevicesConfig): Promise { + async pushOnChanges({ device }: { device: irdevice & irDevicesConfig; }): Promise { if (device.irair?.pushOn) { this.pushOn = true; } else { diff --git a/src/irdevice/airpurifier.ts b/src/irdevice/airpurifier.ts index 55b54d92..646e9203 100644 --- a/src/irdevice/airpurifier.ts +++ b/src/irdevice/airpurifier.ts @@ -80,13 +80,17 @@ export class AirPurifier { async ActiveSet(value: CharacteristicValue): Promise { this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Set Active: ${value}`); - this.Active = value; - this.accessory.context.Active = this.Active; if (value === this.platform.Characteristic.Active.INACTIVE) { this.pushAirPurifierOffChanges(); } else { this.pushAirPurifierOnChanges(); } + /** + * pushAirPurifierOnChanges and pushAirPurifierOffChanges above assume they are measuring the state of the accessory BEFORE + * they are updated, so we are only updating the accessory state after calling the above. + */ + this.Active = value; + this.accessory.context.Active = this.Active; } async TargetAirPurifierStateSet(value: CharacteristicValue): Promise { @@ -267,7 +271,7 @@ export class AirPurifier { } } - async commandType() { + async commandType(): Promise { let commandType: string; if (this.device.customize) { commandType = 'customize'; @@ -277,7 +281,7 @@ export class AirPurifier { return commandType; } - async commandOn() { + async commandOn(): Promise { let command: string; if (this.device.customize && this.device.customOn) { command = this.device.customOn; @@ -287,10 +291,10 @@ export class AirPurifier { return command; } - async commandOff() { + async commandOff(): Promise { let command: string; - if (this.device.customize && this.device.customOn) { - command = this.device.customOn; + if (this.device.customize && this.device.customOff) { + command = this.device.customOff; } else { command = 'turnOff'; } diff --git a/src/irdevice/camera.ts b/src/irdevice/camera.ts index 14c23abe..d3af2724 100644 --- a/src/irdevice/camera.ts +++ b/src/irdevice/camera.ts @@ -56,13 +56,17 @@ export class Camera { async OnSet(value: CharacteristicValue): Promise { this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} On: ${value}`); - this.On = value; - this.accessory.context.On = this.On; - if (this.On) { + if (value) { this.pushOnChanges(); } else { this.pushOffChanges(); } + /** + * pushOnChanges and pushOffChanges above assume they are measuring the state of the accessory BEFORE + * they are updated, so we are only updating the accessory state after calling the above. + */ + this.On = value; + this.accessory.context.On = this.On; } /** @@ -164,7 +168,7 @@ export class Camera { } } - async commandType() { + async commandType(): Promise { let commandType: string; if (this.device.customize) { commandType = 'customize'; @@ -174,7 +178,7 @@ export class Camera { return commandType; } - async commandOn() { + async commandOn(): Promise { let command: string; if (this.device.customize && this.device.customOn) { command = this.device.customOn; @@ -184,10 +188,10 @@ export class Camera { return command; } - async commandOff() { + async commandOff(): Promise { let command: string; - if (this.device.customize && this.device.customOn) { - command = this.device.customOn; + if (this.device.customize && this.device.customOff) { + command = this.device.customOff; } else { command = 'turnOff'; } diff --git a/src/irdevice/fan.ts b/src/irdevice/fan.ts index a50e0631..742de26d 100644 --- a/src/irdevice/fan.ts +++ b/src/irdevice/fan.ts @@ -147,13 +147,17 @@ export class Fan { async ActiveSet(value: CharacteristicValue): Promise { this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Active: ${value}`); - this.Active = value; - this.accessory.context.Active = this.Active; if (value === this.platform.Characteristic.Active.INACTIVE) { this.pushFanOffChanges(); } else { this.pushFanOnChanges(); } + /** + * pushFanOnChanges and pushFanOffChanges above assume they are measuring the state of the accessory BEFORE + * they are updated, so we are only updating the accessory state after calling the above. + */ + this.Active = value; + this.accessory.context.Active = this.Active; } /** @@ -293,7 +297,7 @@ export class Fan { } } - async commandType() { + async commandType(): Promise { let commandType: string; if (this.device.customize) { commandType = 'customize'; @@ -303,7 +307,7 @@ export class Fan { return commandType; } - async commandOn() { + async commandOn(): Promise { let command: string; if (this.device.customize && this.device.customOn) { command = this.device.customOn; @@ -313,10 +317,10 @@ export class Fan { return command; } - async commandOff() { + async commandOff(): Promise { let command: string; - if (this.device.customize && this.device.customOn) { - command = this.device.customOn; + if (this.device.customize && this.device.customOff) { + command = this.device.customOff; } else { command = 'turnOff'; } diff --git a/src/irdevice/light.ts b/src/irdevice/light.ts index bbc831fc..669166c6 100644 --- a/src/irdevice/light.ts +++ b/src/irdevice/light.ts @@ -56,13 +56,17 @@ export class Light { async OnSet(value: CharacteristicValue): Promise { this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} On: ${value}`); - this.On = value; - this.accessory.context.On = this.On; - if (this.On) { + if (value) { await this.pushLightOnChanges(); } else { await this.pushLightOffChanges(); } + /** + * pushLightOnChanges and pushLightOffChanges above assume they are measuring the state of the accessory BEFORE + * they are updated, so we are only updating the accessory state after calling the above. + */ + this.On = value; + this.accessory.context.On = this.On; } /** @@ -183,7 +187,7 @@ export class Light { } } - async commandType() { + async commandType(): Promise { let commandType: string; if (this.device.customize) { commandType = 'customize'; @@ -193,7 +197,7 @@ export class Light { return commandType; } - async commandOn() { + async commandOn(): Promise { let command: string; if (this.device.customize && this.device.customOn) { command = this.device.customOn; @@ -203,10 +207,10 @@ export class Light { return command; } - async commandOff() { + async commandOff(): Promise { let command: string; - if (this.device.customize && this.device.customOn) { - command = this.device.customOn; + if (this.device.customize && this.device.customOff) { + command = this.device.customOff; } else { command = 'turnOff'; } diff --git a/src/irdevice/other.ts b/src/irdevice/other.ts index 7da42e2c..3f18ced3 100644 --- a/src/irdevice/other.ts +++ b/src/irdevice/other.ts @@ -64,13 +64,17 @@ export class Others { async ActiveSet(value: CharacteristicValue): Promise { this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} On: ${value}`); - this.Active = value; - this.accessory.context.Active = this.Active; if (value) { await this.pushOnChanges(); } else { await this.pushOffChanges(); } + /** + * pushOnChanges and pushOffChanges above assume they are measuring the state of the accessory BEFORE + * they are updated, so we are only updating the accessory state after calling the above. + */ + this.Active = value; + this.accessory.context.Active = this.Active; } /** @@ -179,7 +183,7 @@ export class Others { } } - async commandType() { + async commandType(): Promise { let commandType: string; if (this.device.customize) { commandType = 'customize'; @@ -189,7 +193,7 @@ export class Others { return commandType; } - async commandOn() { + async commandOn(): Promise { let command: string; if (this.device.customize && this.device.customOn) { command = this.device.customOn; @@ -199,10 +203,10 @@ export class Others { return command; } - async commandOff() { + async commandOff(): Promise { let command: string; - if (this.device.customize && this.device.customOn) { - command = this.device.customOn; + if (this.device.customize && this.device.customOff) { + command = this.device.customOff; } else { command = 'turnOff'; } diff --git a/src/irdevice/tv.ts b/src/irdevice/tv.ts index 1b52b1d9..e0c4f082 100644 --- a/src/irdevice/tv.ts +++ b/src/irdevice/tv.ts @@ -206,6 +206,12 @@ export class TV { } else { await this.pushTvOnChanges(); } + /** + * pushTvOnChanges and pushTvOffChanges above assume they are measuring the state of the accessory BEFORE + * they are updated, so we are only updating the accessory state after calling the above. + */ + this.Active = value; + this.accessory.context.Active = this.Active; } } @@ -396,7 +402,7 @@ export class TV { } } - async commandType() { + async commandType(): Promise { let commandType: string; if (this.device.customize) { commandType = 'customize'; @@ -406,7 +412,7 @@ export class TV { return commandType; } - async commandOn() { + async commandOn(): Promise { let command: string; if (this.device.customize && this.device.customOn) { command = this.device.customOn; @@ -416,10 +422,10 @@ export class TV { return command; } - async commandOff() { + async commandOff(): Promise { let command: string; - if (this.device.customize && this.device.customOn) { - command = this.device.customOn; + if (this.device.customize && this.device.customOff) { + command = this.device.customOff; } else { command = 'turnOff'; } diff --git a/src/irdevice/vacuumcleaner.ts b/src/irdevice/vacuumcleaner.ts index 7aeeef70..b0ca4631 100644 --- a/src/irdevice/vacuumcleaner.ts +++ b/src/irdevice/vacuumcleaner.ts @@ -56,13 +56,17 @@ export class VacuumCleaner { async OnSet(value: CharacteristicValue): Promise { this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} On: ${value}`); - this.On = value; - this.accessory.context.On = this.On; - if (this.On) { + if (value) { await this.pushOnChanges(); } else { await this.pushOffChanges(); } + /** + * pushOnChanges and pushOffChanges above assume they are measuring the state of the accessory BEFORE + * they are updated, so we are only updating the accessory state after calling the above. + */ + this.On = value; + this.accessory.context.On = this.On; } /** @@ -161,7 +165,7 @@ export class VacuumCleaner { } } - async commandType() { + async commandType(): Promise { let commandType: string; if (this.device.customize) { commandType = 'customize'; @@ -171,7 +175,7 @@ export class VacuumCleaner { return commandType; } - async commandOn() { + async commandOn(): Promise { let command: string; if (this.device.customize && this.device.customOn) { command = this.device.customOn; @@ -181,10 +185,10 @@ export class VacuumCleaner { return command; } - async commandOff() { + async commandOff(): Promise { let command: string; - if (this.device.customize && this.device.customOn) { - command = this.device.customOn; + if (this.device.customize && this.device.customOff) { + command = this.device.customOff; } else { command = 'turnOff'; } diff --git a/src/irdevice/waterheater.ts b/src/irdevice/waterheater.ts index 6c2647ce..fd2a3fea 100644 --- a/src/irdevice/waterheater.ts +++ b/src/irdevice/waterheater.ts @@ -5,6 +5,7 @@ import superStringify from 'super-stringify'; import { SwitchBotPlatform } from '../platform'; import { irDevicesConfig, irdevice, HostDomain, DevicePath } from '../settings'; import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'; +const version = process.env.npm_package_version; /** * Platform Accessory @@ -23,8 +24,8 @@ export class WaterHeater { constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: irdevice & irDevicesConfig) { // default placeholders - this.logs(device); - this.config(device); + this.logs({ device }); + this.config({ device }); this.context(); // set accessory information @@ -33,9 +34,9 @@ export class WaterHeater { .setCharacteristic(this.platform.Characteristic.Manufacturer, 'SwitchBot') .setCharacteristic(this.platform.Characteristic.Model, device.remoteType) .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!) - .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision(accessory, device)) + .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision({ accessory, device })) .getCharacteristic(this.platform.Characteristic.FirmwareRevision) - .updateValue(this.FirmwareRevision(accessory, device)); + .updateValue(this.FirmwareRevision({ accessory, device })); // get the Television service if it exists, otherwise create a new Television service // you can create multiple services for each accessory @@ -59,8 +60,6 @@ export class WaterHeater { async ActiveSet(value: CharacteristicValue): Promise { this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Active: ${value}`); - this.Active = value; - this.accessory.context.Active = this.Active; if (value === this.platform.Characteristic.Active.INACTIVE) { await this.pushWaterHeaterOffChanges(); this.valveService.setCharacteristic(this.platform.Characteristic.InUse, this.platform.Characteristic.InUse.NOT_IN_USE); @@ -68,6 +67,12 @@ export class WaterHeater { await this.pushWaterHeaterOnChanges(); this.valveService.setCharacteristic(this.platform.Characteristic.InUse, this.platform.Characteristic.InUse.IN_USE); } + /** + * pushWaterHeaterOnChanges and pushWaterHeaterOffChanges above assume they are measuring the state of the accessory BEFORE + * they are updated, so we are only updating the accessory state after calling the above. + */ + this.Active = value; + this.accessory.context.Active = this.Active; } /** @@ -85,7 +90,7 @@ export class WaterHeater { 'parameter': 'default', 'commandType': commandType, }); - await this.pushChanges(body); + await this.pushChanges({ body }); } } @@ -98,11 +103,11 @@ export class WaterHeater { 'parameter': 'default', 'commandType': commandType, }); - await this.pushChanges(body); + await this.pushChanges({ body }); } } - async pushChanges(body): Promise { + async pushChanges({ body }: { body: any; }): Promise { if (this.device.connectionType === 'OpenAPI') { try { // Make Push On request to the API @@ -114,7 +119,7 @@ export class WaterHeater { .digest(); const sign = signTerm.toString('base64'); this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} sign: ${sign}`); - this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`); + this.infoLog({ log: [`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`] }); const options = { hostname: HostDomain, port: 443, @@ -137,20 +142,24 @@ export class WaterHeater { }); }); req.on('error', (e: any) => { - this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} error message: ${e.message}`); + this.errorLog({ log: [`${this.device.remoteType}: ${this.accessory.displayName} error message: ${e.message}`] }); }); req.write(body); req.end(); this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`); this.updateHomeKitCharacteristics(); } catch (e: any) { - this.apiError(e); - this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,` - + ` Error Message: ${superStringify(e.message)}`); + this.apiError({ e }); + this.errorLog({ + log: [`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,` + + ` Error Message: ${superStringify(e.message)}`], + }); } } else { - this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}` - + ` Connection Type: ${this.device.connectionType}, commands will not be sent to OpenAPI`); + this.warnLog({ + log: [`${this.device.remoteType}: ${this.accessory.displayName}` + + ` Connection Type: ${this.device.connectionType}, commands will not be sent to OpenAPI`], + }); } } @@ -164,7 +173,7 @@ export class WaterHeater { } } - async commandType() { + async commandType(): Promise { let commandType: string; if (this.device.customize) { commandType = 'customize'; @@ -174,7 +183,7 @@ export class WaterHeater { return commandType; } - async commandOn() { + async commandOn(): Promise { let command: string; if (this.device.customize && this.device.customOn) { command = this.device.customOn; @@ -184,10 +193,10 @@ export class WaterHeater { return command; } - async commandOff() { + async commandOff(): Promise { let command: string; - if (this.device.customize && this.device.customOn) { - command = this.device.customOn; + if (this.device.customize && this.device.customOff) { + command = this.device.customOff; } else { command = 'turnOff'; } @@ -197,24 +206,26 @@ export class WaterHeater { async statusCode({ res }: { res: IncomingMessage }): Promise { switch (res.statusCode) { case 151: - this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this device type.`); + this.errorLog({ log: [`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this device type.`] }); break; case 152: - this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device not found.`); + this.errorLog({ log: [`${this.device.remoteType}: ${this.accessory.displayName} Device not found.`] }); break; case 160: - this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command is not supported.`); + this.errorLog({ log: [`${this.device.remoteType}: ${this.accessory.displayName} Command is not supported.`] }); break; case 161: - this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline.`); + this.errorLog({ log: [`${this.device.remoteType}: ${this.accessory.displayName} Device is offline.`] }); break; case 171: - this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`); + this.errorLog({ log: [`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`] }); break; case 190: this.errorLog( - `${this.device.remoteType}: ${this.accessory.displayName} Device internal error due to device states not synchronized` + - ` with server, Or command: ${superStringify(res)} format is invalid`, + { + log: [`${this.device.remoteType}: ${this.accessory.displayName} Device internal error due to device states not synchronized` + + ` with server, Or command: ${superStringify(res)} format is invalid`], + }, ); break; case 100: @@ -225,27 +236,27 @@ export class WaterHeater { } } - async apiError(e: any): Promise { + async apiError({ e }: { e: any; }): Promise { this.valveService.updateCharacteristic(this.platform.Characteristic.Active, e); } - FirmwareRevision(accessory: PlatformAccessory, device: irdevice & irDevicesConfig): string { + FirmwareRevision({ accessory, device }: { accessory: PlatformAccessory; device: irdevice & irDevicesConfig; }): string { let FirmwareRevision: string; this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName}` + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`); this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`); - this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`); + this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} version: ${version}`); if (accessory.context.FirmwareRevision) { FirmwareRevision = accessory.context.FirmwareRevision; } else if (device.firmware) { FirmwareRevision = device.firmware; } else { - FirmwareRevision = this.platform.version; + FirmwareRevision = version!; } return FirmwareRevision; } - async context() { + async context(): Promise { if (this.Active === undefined) { this.Active = this.platform.Characteristic.Active.INACTIVE; } else { @@ -253,7 +264,7 @@ export class WaterHeater { } } - async config(device: irdevice & irDevicesConfig): Promise { + async config({ device }: { device: irdevice & irDevicesConfig; }): Promise { let config = {}; if (device.irwh) { config = device.irwh; @@ -268,11 +279,11 @@ export class WaterHeater { config['external'] = device.external; } if (Object.entries(config).length !== 0) { - this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Config: ${superStringify(config)}`); + this.infoLog({ log: [`${this.device.remoteType}: ${this.accessory.displayName} Config: ${superStringify(config)}`] }); } } - async logs(device: irdevice & irDevicesConfig): Promise { + async logs({ device }: { device: irdevice & irDevicesConfig; }): Promise { if (this.platform.debugMode) { this.deviceLogging = this.accessory.context.logging = 'debugMode'; this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`); @@ -291,19 +302,19 @@ export class WaterHeater { /** * Logging for Device */ - infoLog(...log: any[]): void { + infoLog({ log = [] }: { log?: any[]; } = {}): void { if (this.enablingDeviceLogging()) { this.platform.log.info(String(...log)); } } - warnLog(...log: any[]): void { + warnLog({ log = [] }: { log?: any[]; } = {}): void { if (this.enablingDeviceLogging()) { this.platform.log.warn(String(...log)); } } - debugWarnLog(...log: any[]): void { + debugWarnLog({ log = [] }: { log?: any[]; } = {}): void { if (this.enablingDeviceLogging()) { if (this.deviceLogging?.includes('debug')) { this.platform.log.warn('[DEBUG]', String(...log)); @@ -311,13 +322,13 @@ export class WaterHeater { } } - errorLog(...log: any[]): void { + errorLog({ log = [] }: { log?: any[]; } = {}): void { if (this.enablingDeviceLogging()) { this.platform.log.error(String(...log)); } } - debugErrorLog(...log: any[]): void { + debugErrorLog({ log = [] }: { log?: any[]; } = {}): void { if (this.enablingDeviceLogging()) { if (this.deviceLogging?.includes('debug')) { this.platform.log.error('[DEBUG]', String(...log)); diff --git a/src/platform.ts b/src/platform.ts index 2230ed6e..5149f1e9 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -41,7 +41,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin { // this is used to track restored cached accessories public readonly accessories: PlatformAccessory[] = []; - version = require('../package.json').version || '1.12.8'; // eslint-disable-line @typescript-eslint/no-var-requires + version = process.env.npm_package_version!; debugMode!: boolean; platformLogging?: string; @@ -910,8 +910,8 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin { } if (device.group && !device.curtain?.disable_group) { - this.debugLog(`Your Curtains are grouped - , Secondary curtain automatically hidden. Main Curtain: ${device.deviceName}, DeviceID: ${device.deviceId}`); + this.debugLog('Your Curtains are grouped, ' + + `, Secondary curtain automatically hidden. Main Curtain: ${device.deviceName}, DeviceID: ${device.deviceId}`); } else { if (device.master) { this.warnLog(`Main Curtain: ${device.deviceName}, DeviceID: ${device.deviceId}`);