homebridge-winix-purifiers 1.1.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # homebridge-winix-purifiers
2
2
 
3
- [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/regaw-leinad/homebridge-winix-purifiers/Build%20and%20Lint)](https://github.com/regaw-leinad/homebridge-winix-purifiers/actions)
3
+ [![verified-by-homebridge](https://badgen.net/badge/homebridge/verified/purple)](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
4
+ [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/regaw-leinad/homebridge-winix-purifiers/build.yml)](https://github.com/regaw-leinad/homebridge-winix-purifiers/actions)
4
5
  [![npm](https://img.shields.io/npm/dt/homebridge-winix-purifiers)](https://www.npmjs.com/package/homebridge-winix-purifiers)
5
6
 
6
7
  [Homebridge](https://homebridge.io) plugin providing support for [Winix](https://www.winixamerica.com) air purifiers.
@@ -30,6 +31,15 @@ The following features are optionally supported:
30
31
  * Expose ambient light
31
32
  * Expose switch to turn Plasmawave `on` / `off`
32
33
 
34
+ ### Winix API Response Caching
35
+
36
+ By default, all individual responses from the Winix API are cached for `60` seconds. This helps prevent rate limiting
37
+ and reduces the number of requests made to the Winix API. The value can be configured with the `cacheIntervalSeconds`
38
+ property (see [Properties](#properties) below).
39
+
40
+ I personally have `cacheIntervalSeconds` set to `600` seconds (10 minutes) since I don't need to know the air quality
41
+ every minute - this significantly reduces the number of requests made to the Winix API.
42
+
33
43
  ## Device Support
34
44
 
35
45
  Currently, this plugin supports the following Winix air purifiers
@@ -62,7 +72,8 @@ In your `config.json`, add and update the following under the `accessories` sect
62
72
  "serialNumber": "WNXAI40001234",
63
73
  "exposeAirQuality": true,
64
74
  "exposeAmbientLight": false,
65
- "exposePlasmawave": false
75
+ "exposePlasmawave": false,
76
+ "cacheIntervalSeconds": 60
66
77
  }
67
78
  ]
68
79
  }
@@ -70,16 +81,17 @@ In your `config.json`, add and update the following under the `accessories` sect
70
81
 
71
82
  ### Properties
72
83
 
73
- | Parameter | Note |
74
- |----------------------|---------------------------------------------------------------------------------|
75
- | `accessory` | must always be set to `WinixPurifier` |
76
- | `name` | a human-readable name for the air purifier |
77
- | `model` | the model of the [supported air purifier](#Device-Support) |
78
- | `deviceId` | the unique identifier of the device (see below for details on how to find this) |
79
- | `serialNumber` | _(optional)_ the serial number of the device |
80
- | `exposeAirQuality` | _(optional)_ whether to expose an air quality sensor |
81
- | `exposeAmbientLight` | _(optional)_ whether to expose an ambient light sensor |
82
- | `exposePlasmawave` | _(optional)_ whether to expose Plasmawave control as a `Switch` |
84
+ | Name | Default Value | Note |
85
+ |------------------------|---------------|---------------------------------------------------------------------------------|
86
+ | `accessory` | Required | must always be set to `WinixPurifier` |
87
+ | `name` | Required | a human-readable name for the air purifier |
88
+ | `model` | Required | the model of the [supported air purifier](#Device-Support) |
89
+ | `deviceId` | Required | the unique identifier of the device (see below for details on how to find this) |
90
+ | `serialNumber` | null | the serial number of the device |
91
+ | `exposeAirQuality` | `false` | whether to expose an air quality sensor |
92
+ | `exposeAmbientLight` | `false` | whether to expose an ambient light sensor |
93
+ | `exposePlasmawave` | `false` | whether to expose Plasmawave control as a `Switch` |
94
+ | `cacheIntervalSeconds` | `60` | the amount of seconds to cache the responses from the Winix API |
83
95
 
84
96
  ## Device ids
85
97
 
@@ -59,6 +59,14 @@
59
59
  "description": "Whether or not to expose the ambient light sensor to HomeKit",
60
60
  "type": "boolean",
61
61
  "default": false
62
+ },
63
+ "cacheIntervalSeconds": {
64
+ "title": "Winix Response Cache Interval (seconds)",
65
+ "description": "Time, in seconds, for how long to reuse the cached response from Winix",
66
+ "type": "integer",
67
+ "default": 60,
68
+ "minimum": 1,
69
+ "required": true
62
70
  }
63
71
  }
64
72
  }
package/dist/accessory.js CHANGED
@@ -11,6 +11,8 @@ class WinixPurifierAccessory {
11
11
  const deviceName = config.name;
12
12
  this.deviceId = config.deviceId;
13
13
  this.latestStatus = {};
14
+ this.cacheIntervalMs = config.cacheIntervalSeconds * 1000 || 60000;
15
+ this.lastWinixPoll = -1;
14
16
  this.services = [];
15
17
  // Create services
16
18
  this.purifier = this.registerService(new this.hap.Service.AirPurifier(deviceName));
@@ -45,6 +47,10 @@ class WinixPurifierAccessory {
45
47
  (_c = this.ambientLight) === null || _c === void 0 ? void 0 : _c.getCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel).onGet(this.getAmbientLight.bind(this));
46
48
  }
47
49
  async getActiveState() {
50
+ if (this.shouldUseCachedValue(this.latestStatus.power)) {
51
+ this.log.debug('getActiveState() (cached)', this.latestStatus.power);
52
+ return this.toActiveState(this.latestStatus.power);
53
+ }
48
54
  let power;
49
55
  try {
50
56
  power = await winix_api_1.WinixAPI.getPower(this.deviceId);
@@ -55,8 +61,9 @@ class WinixPurifierAccessory {
55
61
  throw new this.hap.HapStatusError(-70402 /* HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
56
62
  }
57
63
  this.latestStatus.power = power;
64
+ this.polledWinix();
58
65
  this.log.debug('getActiveState()', power);
59
- return power === winix_api_1.Power.On ? this.hap.Characteristic.Active.ACTIVE : this.hap.Characteristic.Active.INACTIVE;
66
+ return this.toActiveState(power);
60
67
  }
61
68
  async setActiveState(state) {
62
69
  const power = state === this.hap.Characteristic.Active.ACTIVE ? winix_api_1.Power.On : winix_api_1.Power.Off;
@@ -77,6 +84,10 @@ class WinixPurifierAccessory {
77
84
  this.sendHomekitUpdate();
78
85
  }
79
86
  async getCurrentState() {
87
+ if (this.shouldUseCachedValue(this.latestStatus.power)) {
88
+ this.log.debug('getCurrentState() (cached)', this.latestStatus.power);
89
+ return this.toCurrentState(this.latestStatus.power);
90
+ }
80
91
  let power;
81
92
  try {
82
93
  power = await winix_api_1.WinixAPI.getPower(this.deviceId);
@@ -87,11 +98,15 @@ class WinixPurifierAccessory {
87
98
  throw new this.hap.HapStatusError(-70402 /* HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
88
99
  }
89
100
  this.latestStatus.power = power;
101
+ this.polledWinix();
90
102
  this.log.debug('getCurrentState()', power);
91
- return power === winix_api_1.Power.On ? this.hap.Characteristic.CurrentAirPurifierState.PURIFYING_AIR :
92
- this.hap.Characteristic.CurrentAirPurifierState.INACTIVE;
103
+ return this.toCurrentState(power);
93
104
  }
94
105
  async getTargetState() {
106
+ if (this.shouldUseCachedValue(this.latestStatus.mode)) {
107
+ this.log.debug('getTargetState() (cached)', this.latestStatus.mode);
108
+ return this.toTargetState(this.latestStatus.mode);
109
+ }
95
110
  let mode;
96
111
  try {
97
112
  mode = await winix_api_1.WinixAPI.getMode(this.deviceId);
@@ -102,9 +117,9 @@ class WinixPurifierAccessory {
102
117
  throw new this.hap.HapStatusError(-70402 /* HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
103
118
  }
104
119
  this.latestStatus.mode = mode;
120
+ this.polledWinix();
105
121
  this.log.debug('getTargetState()', mode);
106
- return mode === winix_api_1.Mode.Auto ? this.hap.Characteristic.TargetAirPurifierState.AUTO :
107
- this.hap.Characteristic.TargetAirPurifierState.MANUAL;
122
+ return this.toTargetState(mode);
108
123
  }
109
124
  async setTargetState(state) {
110
125
  const mode = state === this.hap.Characteristic.TargetAirPurifierState.AUTO ? winix_api_1.Mode.Auto : winix_api_1.Mode.Manual;
@@ -137,6 +152,10 @@ class WinixPurifierAccessory {
137
152
  }, 2000);
138
153
  }
139
154
  async getRotationSpeed() {
155
+ if (this.shouldUseCachedValue(this.latestStatus.airflow)) {
156
+ this.log.debug('getRotationSpeed() (cached)', this.latestStatus.airflow);
157
+ return this.toRotationSpeed(this.latestStatus.airflow);
158
+ }
140
159
  let airflow;
141
160
  try {
142
161
  airflow = await winix_api_1.WinixAPI.getAirflow(this.deviceId);
@@ -147,6 +166,7 @@ class WinixPurifierAccessory {
147
166
  throw new this.hap.HapStatusError(-70402 /* HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
148
167
  }
149
168
  this.latestStatus.airflow = airflow;
169
+ this.polledWinix();
150
170
  this.log.debug('getRotationSpeed():', airflow);
151
171
  return this.toRotationSpeed(airflow);
152
172
  }
@@ -166,6 +186,10 @@ class WinixPurifierAccessory {
166
186
  this.sendHomekitUpdate();
167
187
  }
168
188
  async getAirQuality() {
189
+ if (this.shouldUseCachedValue(this.latestStatus.airQuality)) {
190
+ this.log.debug('getAirQuality() (cached)', this.latestStatus.airQuality);
191
+ return this.toAirQuality(this.latestStatus.airQuality);
192
+ }
169
193
  let airQuality;
170
194
  try {
171
195
  airQuality = await winix_api_1.WinixAPI.getAirQuality(this.deviceId);
@@ -176,10 +200,15 @@ class WinixPurifierAccessory {
176
200
  throw new this.hap.HapStatusError(-70402 /* HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
177
201
  }
178
202
  this.latestStatus.airQuality = airQuality;
203
+ this.polledWinix();
179
204
  this.log.debug('getAirQuality():', airQuality);
180
205
  return this.toAirQuality(airQuality);
181
206
  }
182
207
  async getPlasmawave() {
208
+ if (this.shouldUseCachedValue(this.latestStatus.plasmawave)) {
209
+ this.log.debug('getPlasmawave() (cached)', this.latestStatus.plasmawave);
210
+ return this.toSwitch(this.latestStatus.plasmawave);
211
+ }
183
212
  let plasmawave;
184
213
  try {
185
214
  plasmawave = await winix_api_1.WinixAPI.getPlasmawave(this.deviceId);
@@ -190,6 +219,7 @@ class WinixPurifierAccessory {
190
219
  throw new this.hap.HapStatusError(-70402 /* HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
191
220
  }
192
221
  this.latestStatus.plasmawave = plasmawave;
222
+ this.polledWinix();
193
223
  this.log.debug('getPlasmawave():', plasmawave);
194
224
  return this.toSwitch(plasmawave);
195
225
  }
@@ -208,6 +238,10 @@ class WinixPurifierAccessory {
208
238
  this.sendHomekitUpdate();
209
239
  }
210
240
  async getAmbientLight() {
241
+ if (this.shouldUseCachedValue(this.latestStatus.ambientLight)) {
242
+ this.log.debug('getAmbientLight() (cached)', this.latestStatus.ambientLight);
243
+ return this.latestStatus.ambientLight;
244
+ }
211
245
  let ambientLight;
212
246
  try {
213
247
  ambientLight = await winix_api_1.WinixAPI.getAmbientLight(this.deviceId);
@@ -220,6 +254,7 @@ class WinixPurifierAccessory {
220
254
  // Fix ambient light value under 0.0001 warning
221
255
  ambientLight = Math.max(ambientLight, MIN_AMBIENT_LIGHT);
222
256
  this.latestStatus.ambientLight = ambientLight;
257
+ this.polledWinix();
223
258
  this.log.debug('getAmbientLight():', ambientLight);
224
259
  return ambientLight;
225
260
  }
@@ -314,6 +349,12 @@ class WinixPurifierAccessory {
314
349
  return this.hap.Characteristic.AirQuality.UNKNOWN;
315
350
  }
316
351
  }
352
+ shouldUseCachedValue(v) {
353
+ return v !== undefined && Date.now() - this.lastWinixPoll < this.cacheIntervalMs;
354
+ }
355
+ polledWinix() {
356
+ this.lastWinixPoll = Date.now();
357
+ }
317
358
  toSwitch(plasmawave) {
318
359
  return plasmawave === winix_api_1.Plasmawave.On;
319
360
  }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "private": false,
3
3
  "displayName": "Winix Air Purifiers",
4
4
  "name": "homebridge-winix-purifiers",
5
- "version": "1.1.2",
5
+ "version": "1.3.0",
6
6
  "description": "Homebridge plugin for Winix air purifiers",
7
7
  "license": "Apache-2.0",
8
8
  "repository": {
@@ -39,7 +39,7 @@
39
39
  "winix air purifier"
40
40
  ],
41
41
  "dependencies": {
42
- "axios": "^1.1.2",
42
+ "axios": "1.6.0",
43
43
  "winix-api": "1.1.2"
44
44
  },
45
45
  "devDependencies": {