From 68c78b7b62574ff95c60a7e9bedd0974cc9851eb Mon Sep 17 00:00:00 2001 From: Harry Shamansky Date: Sat, 8 Feb 2020 20:55:21 -0800 Subject: [PATCH 1/4] Use filter codes instead of filter names --- lib/Client.ts | 3 ++- lib/Config.ts | 4 ++-- lib/interfaces/PurifierStatus.ts | 1 + lib/services/FilterService.ts | 12 ++++++------ 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/Client.ts b/lib/Client.ts index 805a958..ef98a20 100644 --- a/lib/Client.ts +++ b/lib/Client.ts @@ -41,7 +41,8 @@ export class Client { let filterStatuses = response.body.filterList.map(filter => { let filterStatus: FilterStatus = { name: filter.filterName, - lifeLevel: filter.filterPer + lifeLevel: filter.filterPer, + code: filter.filterCode } return filterStatus; diff --git a/lib/Config.ts b/lib/Config.ts index 0cbf70f..b0b99e6 100644 --- a/lib/Config.ts +++ b/lib/Config.ts @@ -34,7 +34,7 @@ export namespace Config { } export namespace Filters { - export const PRE_FILTER = 'Pre Filter'; - export const MAIN_FILTER = 'Max2 Filter'; + export const PRE_FILTER = '3121332'; + export const MAIN_FILTER = '3111735'; } } diff --git a/lib/interfaces/PurifierStatus.ts b/lib/interfaces/PurifierStatus.ts index 174c536..ac89593 100644 --- a/lib/interfaces/PurifierStatus.ts +++ b/lib/interfaces/PurifierStatus.ts @@ -39,6 +39,7 @@ export interface Status { export interface FilterStatus { name: string lifeLevel: number + code: string } export interface Metadata { diff --git a/lib/services/FilterService.ts b/lib/services/FilterService.ts index bf7a311..e1e0333 100644 --- a/lib/services/FilterService.ts +++ b/lib/services/FilterService.ts @@ -78,10 +78,10 @@ export class FilterService extends AbstractService { } } - async getChangeIndicationForFilter(name: string): Promise { + async getChangeIndicationForFilter(code: string): Promise { try { let status = await this.purifier.waitForFilterStatusUpdate(); - let statusForFilter = status.find(filter => filter.name == name); + let statusForFilter = status.find(filter => filter.code == code); let indication; if (statusForFilter.lifeLevel <= 20) { @@ -92,19 +92,19 @@ export class FilterService extends AbstractService { return indication; } catch(e) { - Logger.error(`Unable to get filter change indication for ${name}`, e); + Logger.error(`Unable to get filter change indication for ${code}`, e); throw e; } } - async getLifeLevelForFilter(name: string): Promise { + async getLifeLevelForFilter(code: string): Promise { try { let status = await this.purifier.waitForFilterStatusUpdate(); - let statusForFilter = status.find(filter => filter.name == name); + let statusForFilter = status.find(filter => filter.code == code); return statusForFilter.lifeLevel; } catch(e) { - Logger.error(`Unable to get filter life level for ${name}`, e); + Logger.error(`Unable to get filter life level for ${code}`, e); throw e; } } From 8d369cce8a1881392fde1ce36c3a25834948bc9e Mon Sep 17 00:00:00 2001 From: Harry Shamansky Date: Wed, 18 Nov 2020 11:17:12 -0800 Subject: [PATCH 2/4] Update package.json in preparation for publish --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 8ce02d9..5f5f0af 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "homebridge-airmega", - "version": "3.1.9", + "version": "3.1.10", "description": "Homebridge plugin for the Airmega air purifier", "main": "./dist/index.js", "author": "Andrew Schaper", @@ -24,7 +24,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/aschzero/homebridge-airmega" + "url": "https://github.com/shamanskyh/homebridge-airmega" }, "keywords": [ "coway", From 0f4f68681a02bce5fd23ed92c0e0d2bb24d2116b Mon Sep 17 00:00:00 2001 From: Harry Shamansky Date: Wed, 18 Nov 2020 11:27:31 -0800 Subject: [PATCH 3/4] Update package name --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5f5f0af..8cc8c51 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "homebridge-airmega", + "name": "homebridge-airmega-shamanskyh", "version": "3.1.10", "description": "Homebridge plugin for the Airmega air purifier", "main": "./dist/index.js", From 125b697478991abd9d8990b5899b747705066b82 Mon Sep 17 00:00:00 2001 From: BK <78316546+GTPatriots@users.noreply.github.com> Date: Mon, 15 Feb 2021 12:57:37 -0500 Subject: [PATCH 4/4] - 3.1.10 - Updated accessory names to be able to distinguish which is which - Updated purifier serivce logic so commands are sent properly - Added diagnostic config flag to diagnose future changes --- .gitignore | 8 +++++++- lib/AirmegaPlatform.ts | 4 ++-- lib/Client.ts | 3 +++ lib/Logger.ts | 15 ++++++++++++++- lib/interfaces/PluginConfig.ts | 1 + lib/services/AirQualityService.ts | 2 +- lib/services/FilterService.ts | 4 ++-- lib/services/LightbulbService.ts | 2 +- lib/services/PurifierService.ts | 24 +++++++++++++++++++++--- package-lock.json | 8 ++++---- package.json | 4 ++-- 11 files changed, 58 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index e0aab21..ed47d9d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,10 @@ .homebridge node_modules dist -package-lock.json \ No newline at end of file +package-lock.json +/.vs/VSWorkspaceState.json +/.vs/tasks.vs.json +/.vs/slnx.sqlite +/.vs/ProjectSettings.json +/.vs/homebridge-airmega/v16/.suo +/Readme.txt diff --git a/lib/AirmegaPlatform.ts b/lib/AirmegaPlatform.ts index c4422cd..cfc782a 100644 --- a/lib/AirmegaPlatform.ts +++ b/lib/AirmegaPlatform.ts @@ -15,7 +15,7 @@ export class AirmegaPlatform { log: Log; constructor(log: Log, config: PluginConfig, platform: Platform) { - Logger.setLogger(log, config.debug); + Logger.setLogger(log, config.debug, config.diagnostic); this.platform = platform; this.accessories = new Map(); @@ -55,7 +55,7 @@ export class AirmegaPlatform { accessory = new HAP.Accessory(purifier.name, uuid); this.accessories.set(accessory.UUID, accessory); - this.platform.registerPlatformAccessories('homebridge-airmega', 'Airmega', [accessory]); + this.platform.registerPlatformAccessories('homebridge-airmega', 'Airmega', [accessory]); } this.registerServices(purifier, accessory, config); diff --git a/lib/Client.ts b/lib/Client.ts index ef98a20..c961db2 100644 --- a/lib/Client.ts +++ b/lib/Client.ts @@ -54,6 +54,7 @@ export class Client { async setPower(id: string, on: boolean): Promise { let value = on ? '1' : '0'; let payload = await this.buildControlPayload(id, Config.Codes.POWER, value); + Logger.diagnostic(`Client.setPower: ${value}`); await this.sendControlRequest(id, payload); } @@ -61,6 +62,7 @@ export class Client { async setMode(id: string, auto: boolean): Promise { let value = auto ? '1' : '2'; let payload = await this.buildControlPayload(id, Config.Codes.MODE, value); + Logger.diagnostic(`Client.setMode: ${value}`); await this.sendControlRequest(id, payload); } @@ -68,6 +70,7 @@ export class Client { async setFanSpeed(id: string, speed: number): Promise { let value = speed.toString(); let payload = await this.buildControlPayload(id, Config.Codes.FAN, value); + Logger.diagnostic(`Client.setFanSpeed: ${value}`); await this.sendControlRequest(id, payload); } diff --git a/lib/Logger.ts b/lib/Logger.ts index fb53b30..94076cc 100644 --- a/lib/Logger.ts +++ b/lib/Logger.ts @@ -3,10 +3,12 @@ import { Log } from "./interfaces/HAP"; class AirmegaLogger { public log: Log; private debugMode: boolean; + private diagnosticMode: boolean; - setLogger(log: Log, debugMode: boolean): void { + setLogger(log: Log, debugMode: boolean, diagnosticMode: boolean): void { this.log = log; this.debugMode = debugMode; + this.diagnosticMode = diagnosticMode; } debug(message: string, data?: any): void { @@ -20,6 +22,17 @@ class AirmegaLogger { this.log(result); } + diagnostic(message: string, data?: any): void { + if (!this.diagnosticMode) return; + + let result = message; + if (data) { + result += `: ${JSON.stringify(data)}` + } + + this.log(result); + } + error(message: string, error: Error) { this.log(`[ERROR] ${message}. ${error.message}`) } diff --git a/lib/interfaces/PluginConfig.ts b/lib/interfaces/PluginConfig.ts index 14307e4..22eabcc 100644 --- a/lib/interfaces/PluginConfig.ts +++ b/lib/interfaces/PluginConfig.ts @@ -3,4 +3,5 @@ export interface PluginConfig { password: string; exclude?: string[]; debug?: boolean; + diagnostic?: boolean; } \ No newline at end of file diff --git a/lib/services/AirQualityService.ts b/lib/services/AirQualityService.ts index e771ca7..7ca4f99 100644 --- a/lib/services/AirQualityService.ts +++ b/lib/services/AirQualityService.ts @@ -16,7 +16,7 @@ export class AirQualityService extends AbstractService { let airQualityService = this.accessory.getService(HAP.Service.AirQualitySensor); if (!airQualityService) { - airQualityService = this.accessory.addService(HAP.Service.AirQualitySensor, this.purifier.name); + airQualityService = this.accessory.addService(HAP.Service.AirQualitySensor, this.purifier.name + ' Air Quality'); } return airQualityService; diff --git a/lib/services/FilterService.ts b/lib/services/FilterService.ts index e1e0333..0382b9f 100644 --- a/lib/services/FilterService.ts +++ b/lib/services/FilterService.ts @@ -26,7 +26,7 @@ export class FilterService extends AbstractService { let filterService = this.accessory.getServiceByUUIDAndSubType(HAP.Service.FilterMaintenance, 'main'); if (!filterService) { - filterService = this.accessory.addService(HAP.Service.FilterMaintenance, Config.Filters.MAIN_FILTER, 'main'); + filterService = this.accessory.addService(HAP.Service.FilterMaintenance, this.purifier.name + ' Max2-filter', Config.Filters.MAIN_FILTER); } return filterService; @@ -36,7 +36,7 @@ export class FilterService extends AbstractService { let filterService = this.accessory.getServiceByUUIDAndSubType(HAP.Service.FilterMaintenance, 'pre'); if (!filterService) { - filterService = this.accessory.addService(HAP.Service.FilterMaintenance, Config.Filters.PRE_FILTER, 'pre'); + filterService = this.accessory.addService(HAP.Service.FilterMaintenance, this.purifier.name +' Pre-filter', Config.Filters.PRE_FILTER); } return filterService; diff --git a/lib/services/LightbulbService.ts b/lib/services/LightbulbService.ts index 55ecacb..497d0ad 100644 --- a/lib/services/LightbulbService.ts +++ b/lib/services/LightbulbService.ts @@ -18,7 +18,7 @@ export class LightbulbService extends AbstractService { let lightbulbService = this.accessory.getService(HAP.Service.Lightbulb); if (!lightbulbService) { - lightbulbService = this.accessory.addService(HAP.Service.Lightbulb, this.purifier.name); + lightbulbService = this.accessory.addService(HAP.Service.Lightbulb, this.purifier.name + ' Light'); } return lightbulbService; diff --git a/lib/services/PurifierService.ts b/lib/services/PurifierService.ts index 46d0548..068705e 100644 --- a/lib/services/PurifierService.ts +++ b/lib/services/PurifierService.ts @@ -30,7 +30,7 @@ export class PurifierService extends AbstractService { let purifierService = this.accessory.getService(HAP.Service.AirPurifier); if (!purifierService) { - purifierService = this.accessory.addService(HAP.Service.AirPurifier, this.purifier.name); + purifierService = this.accessory.addService(HAP.Service.AirPurifier, this.purifier.name + ' Purifier'); } return purifierService; @@ -56,6 +56,7 @@ export class PurifierService extends AbstractService { // the fan speed (setRotationSpeed ensures device is on). if (Number(this.purifier.power) == targetState) { callback(); + Logger.diagnostic('PurifierService.setActiveState targetState = this.purifier.power'); return; } @@ -63,9 +64,11 @@ export class PurifierService extends AbstractService { await this.client.setPower(this.purifier.id, targetState); if (targetState) { + Logger.diagnostic('PurifierService.setActiveState targetState = Power.On'); this.purifierService.setCharacteristic(HAP.Characteristic.CurrentAirPurifierState, HAP.Characteristic.CurrentAirPurifierState.PURIFYING_AIR); this.purifier.power = Power.On; } else { + Logger.diagnostic('PurifierService.setActiveState targetState = Power.Off'); this.purifierService.setCharacteristic(HAP.Characteristic.CurrentAirPurifierState, HAP.Characteristic.CurrentAirPurifierState.INACTIVE); this.purifier.power = Power.Off; } @@ -119,14 +122,22 @@ export class PurifierService extends AbstractService { } async setTargetPurifierState(targetState, callback): Promise { - try { + if (Number(this.purifier.mode) == targetState) { + callback(); + Logger.diagnostic('PurifierService.setTargetPurifierState targetState = this.purifier.mode'); + return; + } + + try { await this.client.setMode(this.purifier.id, targetState); if (targetState) { + Logger.diagnostic('PurifierService.setTargetPurifierState targetState = Mode.Auto'); this.purifier.mode = Mode.Auto; this.purifierService.getCharacteristic(HAP.Characteristic.CurrentAirPurifierState) .updateValue(HAP.Characteristic.CurrentAirPurifierState.PURIFYING_AIR); } else { + Logger.diagnostic('PurifierService.setTargetPurifierState targetState = Mode.Manual'); this.purifier.mode = Mode.Manual; this.purifierService.getCharacteristic(HAP.Characteristic.CurrentAirPurifierState) .updateValue(HAP.Characteristic.CurrentAirPurifierState.IDLE); @@ -172,18 +183,25 @@ export class PurifierService extends AbstractService { } } - if (this.purifier.fan == targetSpeed) { + if (this.purifier.fan == targetSpeed && this.purifier.mode == Mode.Manual) { + Logger.diagnostic('PurifierService.setRotationSpeed targetState = this.purifier.fan && mode = Manual'); + return callback(); } + else + Logger.diagnostic(`PurifierService.setRotationSpeed Current speed = ${this.purifier.fan} & Target speed = ${targetSpeed} & Mode = ${this.purifier.mode}`); try { await this.client.setFanSpeed(this.purifier.id, targetSpeed); this.purifier.fan = targetSpeed; + Logger.diagnostic('PurifierService.setRotationSpeed CurrentAirPurifierState = PURIFYING_AIR'); this.purifierService.getCharacteristic(HAP.Characteristic.CurrentAirPurifierState) .updateValue(HAP.Characteristic.CurrentAirPurifierState.PURIFYING_AIR); + Logger.diagnostic('PurifierService.setRotationSpeed TargetAirPurifierState = MANUAL'); + this.purifier.mode = Mode.Manual; this.purifierService.getCharacteristic(HAP.Characteristic.TargetAirPurifierState) .updateValue(HAP.Characteristic.TargetAirPurifierState.MANUAL); diff --git a/package-lock.json b/package-lock.json index 5878dc3..b21170d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "homebridge-airmega", - "version": "3.1.9", + "version": "3.1.10", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -284,9 +284,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" }, "mime-db": { "version": "1.36.0", diff --git a/package.json b/package.json index 8cc8c51..ce7812d 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "homebridge-airmega-shamanskyh", + "name": "homebridge-airmega", "version": "3.1.10", "description": "Homebridge plugin for the Airmega air purifier", "main": "./dist/index.js", @@ -24,7 +24,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/shamanskyh/homebridge-airmega" + "url": "https://github.com/GTPatriots/homebridge-airmega" }, "keywords": [ "coway",