@switchbot/homebridge-switchbot 3.5.0 → 3.5.1-beta.1

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.
Files changed (137) hide show
  1. package/.github/npm-version-script.cjs +81 -0
  2. package/config.schema.json +4 -4
  3. package/dist/device/blindtilt.d.ts.map +1 -1
  4. package/dist/device/blindtilt.js +64 -189
  5. package/dist/device/blindtilt.js.map +1 -1
  6. package/dist/device/bot.d.ts.map +1 -1
  7. package/dist/device/bot.js +34 -68
  8. package/dist/device/bot.js.map +1 -1
  9. package/dist/device/ceilinglight.d.ts +1 -1
  10. package/dist/device/ceilinglight.d.ts.map +1 -1
  11. package/dist/device/ceilinglight.js +65 -158
  12. package/dist/device/ceilinglight.js.map +1 -1
  13. package/dist/device/colorbulb.d.ts +1 -1
  14. package/dist/device/colorbulb.d.ts.map +1 -1
  15. package/dist/device/colorbulb.js +47 -159
  16. package/dist/device/colorbulb.js.map +1 -1
  17. package/dist/device/contact.d.ts.map +1 -1
  18. package/dist/device/contact.js +42 -105
  19. package/dist/device/contact.js.map +1 -1
  20. package/dist/device/curtain.d.ts +1 -0
  21. package/dist/device/curtain.d.ts.map +1 -1
  22. package/dist/device/curtain.js +61 -182
  23. package/dist/device/curtain.js.map +1 -1
  24. package/dist/device/device.d.ts +41 -2
  25. package/dist/device/device.d.ts.map +1 -1
  26. package/dist/device/device.js +182 -5
  27. package/dist/device/device.js.map +1 -1
  28. package/dist/device/fan.d.ts.map +1 -1
  29. package/dist/device/fan.js +76 -145
  30. package/dist/device/fan.js.map +1 -1
  31. package/dist/device/hub.d.ts +7 -1
  32. package/dist/device/hub.d.ts.map +1 -1
  33. package/dist/device/hub.js +54 -17
  34. package/dist/device/hub.js.map +1 -1
  35. package/dist/device/humidifier.d.ts.map +1 -1
  36. package/dist/device/humidifier.js +55 -104
  37. package/dist/device/humidifier.js.map +1 -1
  38. package/dist/device/iosensor.d.ts.map +1 -1
  39. package/dist/device/iosensor.js +27 -46
  40. package/dist/device/iosensor.js.map +1 -1
  41. package/dist/device/lightstrip.d.ts +1 -1
  42. package/dist/device/lightstrip.d.ts.map +1 -1
  43. package/dist/device/lightstrip.js +56 -120
  44. package/dist/device/lightstrip.js.map +1 -1
  45. package/dist/device/lock.d.ts +1 -1
  46. package/dist/device/lock.d.ts.map +1 -1
  47. package/dist/device/lock.js +36 -66
  48. package/dist/device/lock.js.map +1 -1
  49. package/dist/device/meter.d.ts.map +1 -1
  50. package/dist/device/meter.js +27 -46
  51. package/dist/device/meter.js.map +1 -1
  52. package/dist/device/meterplus.d.ts.map +1 -1
  53. package/dist/device/meterplus.js +26 -45
  54. package/dist/device/meterplus.js.map +1 -1
  55. package/dist/device/motion.d.ts.map +1 -1
  56. package/dist/device/motion.js +24 -43
  57. package/dist/device/motion.js.map +1 -1
  58. package/dist/device/plug.d.ts.map +1 -1
  59. package/dist/device/plug.js +32 -66
  60. package/dist/device/plug.js.map +1 -1
  61. package/dist/device/robotvacuumcleaner.d.ts +1 -1
  62. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  63. package/dist/device/robotvacuumcleaner.js +43 -88
  64. package/dist/device/robotvacuumcleaner.js.map +1 -1
  65. package/dist/device/waterdetector.d.ts.map +1 -1
  66. package/dist/device/waterdetector.js +23 -43
  67. package/dist/device/waterdetector.js.map +1 -1
  68. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  69. package/dist/irdevice/airconditioner.js +10 -28
  70. package/dist/irdevice/airconditioner.js.map +1 -1
  71. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  72. package/dist/irdevice/airpurifier.js +8 -20
  73. package/dist/irdevice/airpurifier.js.map +1 -1
  74. package/dist/irdevice/camera.d.ts.map +1 -1
  75. package/dist/irdevice/camera.js +8 -20
  76. package/dist/irdevice/camera.js.map +1 -1
  77. package/dist/irdevice/fan.d.ts.map +1 -1
  78. package/dist/irdevice/fan.js +8 -20
  79. package/dist/irdevice/fan.js.map +1 -1
  80. package/dist/irdevice/irdevice.d.ts +7 -0
  81. package/dist/irdevice/irdevice.d.ts.map +1 -1
  82. package/dist/irdevice/irdevice.js +28 -0
  83. package/dist/irdevice/irdevice.js.map +1 -1
  84. package/dist/irdevice/light.d.ts.map +1 -1
  85. package/dist/irdevice/light.js +8 -20
  86. package/dist/irdevice/light.js.map +1 -1
  87. package/dist/irdevice/other.d.ts.map +1 -1
  88. package/dist/irdevice/other.js +8 -20
  89. package/dist/irdevice/other.js.map +1 -1
  90. package/dist/irdevice/tv.d.ts.map +1 -1
  91. package/dist/irdevice/tv.js +8 -20
  92. package/dist/irdevice/tv.js.map +1 -1
  93. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  94. package/dist/irdevice/vacuumcleaner.js +8 -20
  95. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  96. package/dist/irdevice/waterheater.d.ts.map +1 -1
  97. package/dist/irdevice/waterheater.js +8 -20
  98. package/dist/irdevice/waterheater.js.map +1 -1
  99. package/dist/settings.d.ts +4 -2
  100. package/dist/settings.d.ts.map +1 -1
  101. package/dist/settings.js.map +1 -1
  102. package/dist/utils.d.ts +19 -1
  103. package/dist/utils.d.ts.map +1 -1
  104. package/dist/utils.js +20 -1
  105. package/dist/utils.js.map +1 -1
  106. package/package.json +8 -8
  107. package/src/device/blindtilt.ts +71 -186
  108. package/src/device/bot.ts +32 -68
  109. package/src/device/ceilinglight.ts +67 -153
  110. package/src/device/colorbulb.ts +51 -155
  111. package/src/device/contact.ts +49 -104
  112. package/src/device/curtain.ts +70 -177
  113. package/src/device/device.ts +207 -8
  114. package/src/device/fan.ts +75 -147
  115. package/src/device/hub.ts +55 -19
  116. package/src/device/humidifier.ts +52 -104
  117. package/src/device/iosensor.ts +25 -46
  118. package/src/device/lightstrip.ts +54 -121
  119. package/src/device/lock.ts +35 -67
  120. package/src/device/meter.ts +25 -46
  121. package/src/device/meterplus.ts +24 -45
  122. package/src/device/motion.ts +22 -43
  123. package/src/device/plug.ts +30 -66
  124. package/src/device/robotvacuumcleaner.ts +40 -89
  125. package/src/device/waterdetector.ts +22 -43
  126. package/src/irdevice/airconditioner.ts +10 -26
  127. package/src/irdevice/airpurifier.ts +8 -20
  128. package/src/irdevice/camera.ts +8 -20
  129. package/src/irdevice/fan.ts +8 -20
  130. package/src/irdevice/irdevice.ts +29 -0
  131. package/src/irdevice/light.ts +8 -20
  132. package/src/irdevice/other.ts +8 -20
  133. package/src/irdevice/tv.ts +8 -20
  134. package/src/irdevice/vacuumcleaner.ts +8 -20
  135. package/src/irdevice/waterheater.ts +8 -20
  136. package/src/settings.ts +4 -2
  137. package/src/utils.ts +20 -1
@@ -2,15 +2,13 @@
2
2
  *
3
3
  * robotvacuumcleaner.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
- import { request } from 'undici';
6
- import { Devices } from '../settings.js';
7
5
  import { deviceBase } from './device.js';
8
6
  import { Subject, interval, skipWhile } from 'rxjs';
9
7
  import { debounceTime, take, tap } from 'rxjs/operators';
10
8
 
11
9
  import type { SwitchBotPlatform } from '../platform.js';
12
10
  import type { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
13
- import type { device, devicesConfig, deviceStatus, serviceData } from '../settings.js';
11
+ import type { device, devicesConfig, serviceData, deviceStatus } from '../settings.js';
14
12
 
15
13
  export class RobotVacuumCleaner extends deviceBase {
16
14
  // Services
@@ -134,12 +132,7 @@ export class RobotVacuumCleaner extends deviceBase {
134
132
  )
135
133
  .subscribe(async () => {
136
134
  try {
137
- if (this.LightBulb.On !== accessory.context.On) {
138
- await this.pushChanges();
139
- }
140
- if (this.LightBulb.On && this.LightBulb.Brightness !== accessory.context.Brightness) {
141
- await this.openAPIpushBrightnessChanges();
142
- }
135
+ await this.pushChanges();
143
136
  } catch (e: any) {
144
137
  this.apiError(e);
145
138
  this.errorLog(`${device.deviceType}: ${accessory.displayName} failed pushChanges with ${device.connectionType} Connection,`
@@ -236,63 +229,43 @@ export class RobotVacuumCleaner extends deviceBase {
236
229
 
237
230
  async BLERefreshStatus(): Promise<void> {
238
231
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
239
- const switchbot = await this.platform.connectBLE();
240
- // Convert to BLE Address
241
- this.device.bleMac = this.device
242
- .deviceId!.match(/.{1,2}/g)!
243
- .join(':')
244
- .toLowerCase();
245
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
246
- this.getCustomBLEAddress(switchbot);
232
+ const switchbot = await this.switchbotBLE();
233
+
234
+ if (switchbot === undefined) {
235
+ await this.BLERefreshConnection(switchbot);
236
+ } else {
247
237
  // Start to monitor advertisement packets
248
- (async () => {
238
+ (async () => {
249
239
  // Start to monitor advertisement packets
250
- await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
251
- // Set an event handler
252
- switchbot.onadvertisement = (ad: any) => {
253
- if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
254
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
255
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
256
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
240
+ const serviceData: serviceData = await this.monitorAdvertisementPackets(switchbot);
241
+ // Update HomeKit
242
+ if (serviceData.model !== '' && serviceData.modelName !== '') {
243
+ await this.BLEparseStatus(serviceData);
244
+ await this.updateHomeKitCharacteristics();
257
245
  } else {
258
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
246
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
247
+ await this.BLERefreshConnection(switchbot);
259
248
  }
260
- };
261
- // Wait 10 seconds
262
- await switchbot.wait(this.scanDuration * 1000);
263
- // Stop to monitor
264
- await switchbot.stopScan();
265
- // Update HomeKit
266
- await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
267
- await this.updateHomeKitCharacteristics();
268
- })();
269
- if (switchbot === undefined) {
270
- await this.BLERefreshConnection(switchbot);
249
+ })();
271
250
  }
272
251
  }
273
252
 
274
253
  async openAPIRefreshStatus(): Promise<void> {
275
254
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
276
255
  try {
277
- const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
278
- `${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
279
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
256
+ const { body, statusCode } = await this.deviceRefreshStatus();
280
257
  const deviceStatus: any = await body.json();
281
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
282
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
258
+ await this.refreshStatusCodes(statusCode, deviceStatus);;
283
259
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
284
- this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
285
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
286
- this.openAPIparseStatus(deviceStatus);
287
- this.updateHomeKitCharacteristics();
260
+ await this.successfulRefreshStatus(statusCode, deviceStatus);
261
+ await this.openAPIparseStatus(deviceStatus);
262
+ await this.updateHomeKitCharacteristics();
288
263
  } else {
289
- this.statusCode(statusCode);
290
- this.statusCode(deviceStatus.statusCode);
264
+ await this.statusCodes(statusCode, deviceStatus);
291
265
  }
292
266
  } catch (e: any) {
293
- this.apiError(e);
294
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
295
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
267
+ await this.apiError(e);
268
+ await this.openAPIRefreshError(e);
296
269
  }
297
270
  }
298
271
 
@@ -333,14 +306,13 @@ export class RobotVacuumCleaner extends deviceBase {
333
306
  async pushChanges(): Promise<void> {
334
307
  if (!this.device.enableCloudService && this.OpenAPI) {
335
308
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} pushChanges enableCloudService: ${this.device.enableCloudService}`);
336
- /*} else if (this.BLE) {
337
- await this.BLEpushChanges();*/
309
+ } else if (this.BLE) {
310
+ await this.BLEpushChanges();
338
311
  } else if (this.OpenAPI && this.platform.config.credentials?.token) {
339
312
  await this.openAPIpushChanges();
340
313
  } else {
341
314
  await this.offlineOff();
342
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
343
- + ` ${this.device.connectionType}, pushChanges will not happen.`);
315
+ await this.pushChangeDisabled();
344
316
  }
345
317
  // Refresh the status from the API
346
318
  interval(15000)
@@ -358,11 +330,7 @@ export class RobotVacuumCleaner extends deviceBase {
358
330
  + ` On: ${this.LightBulb.On} OnCached: ${this.accessory.context.On}`);
359
331
  const switchbot = await this.platform.connectBLE();
360
332
  // Convert to BLE Address
361
- this.device.bleMac = this.device
362
- .deviceId!.match(/.{1,2}/g)!
363
- .join(':')
364
- .toLowerCase();
365
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
333
+ await this.convertBLEAddress();
366
334
  switchbot
367
335
  .discover({
368
336
  model: '?',
@@ -405,16 +373,9 @@ export class RobotVacuumCleaner extends deviceBase {
405
373
  const bodyChange = await this.commands();
406
374
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
407
375
  try {
408
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/commands`, {
409
- body: bodyChange,
410
- method: 'POST',
411
- headers: this.platform.generateHeaders(),
412
- });
413
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
376
+ const { body, statusCode } = await this.pushChangeRequest(bodyChange);
414
377
  const deviceStatus: any = await body.json();
415
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
416
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus body: ${JSON.stringify(deviceStatus.body)}`);
417
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
378
+ await this.pushStatusCodes(statusCode, deviceStatus);
418
379
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
419
380
  this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
420
381
  + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
@@ -425,9 +386,8 @@ export class RobotVacuumCleaner extends deviceBase {
425
386
  this.statusCode(deviceStatus.statusCode);
426
387
  }
427
388
  } catch (e: any) {
428
- this.apiError(e);
429
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
430
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
389
+ await this.apiError(e);
390
+ await this.pushChangeError('openAPIpushChanges', e);
431
391
  }
432
392
  } else {
433
393
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges, On: ${this.LightBulb.On}, `
@@ -440,28 +400,19 @@ export class RobotVacuumCleaner extends deviceBase {
440
400
  const bodyChange = await this.brightnessCommands();
441
401
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
442
402
  try {
443
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/commands`, {
444
- body: bodyChange,
445
- method: 'POST',
446
- headers: this.platform.generateHeaders(),
447
- });
448
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
403
+ const { body, statusCode } = await this.pushChangeRequest(bodyChange);
449
404
  const deviceStatus: any = await body.json();
450
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
451
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
405
+ await this.refreshStatusCodes(statusCode, deviceStatus);;
452
406
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
453
- this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
454
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
455
- this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
456
- + `request to SwitchBot API, body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
407
+ await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
408
+ await this.updateHomeKitCharacteristics();
457
409
  } else {
458
- this.statusCode(statusCode);
459
- this.statusCode(deviceStatus.statusCode);
410
+ await this.statusCode(statusCode);
411
+ await this.statusCode(deviceStatus.statusCode);
460
412
  }
461
413
  } catch (e: any) {
462
- this.apiError(e);
463
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
464
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
414
+ await this.apiError(e);
415
+ await this.pushChangeError('openAPIpushBrightnessChanges', e);
465
416
  }
466
417
  }
467
418
 
@@ -4,7 +4,6 @@
4
4
  */
5
5
  import { deviceBase } from './device.js';
6
6
  import { interval, Subject } from 'rxjs';
7
- import { Devices } from '../settings.js';
8
7
  import { skipWhile } from 'rxjs/operators';
9
8
 
10
9
  import type { SwitchBotPlatform } from '../platform.js';
@@ -193,63 +192,43 @@ export class WaterDetector extends deviceBase {
193
192
 
194
193
  async BLERefreshStatus(): Promise<void> {
195
194
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
196
- const switchbot = await this.platform.connectBLE();
197
- // Convert to BLE Address
198
- this.device.bleMac = this.device
199
- .deviceId!.match(/.{1,2}/g)!
200
- .join(':')
201
- .toLowerCase();
202
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
203
- this.getCustomBLEAddress(switchbot);
195
+ const switchbot = await this.switchbotBLE();
196
+
197
+ if (switchbot === undefined) {
198
+ await this.BLERefreshConnection(switchbot);
199
+ } else {
204
200
  // Start to monitor advertisement packets
205
- (async () => {
201
+ (async () => {
206
202
  // Start to monitor advertisement packets
207
- await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
208
- // Set an event handler
209
- switchbot.onadvertisement = (ad: any) => {
210
- if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
211
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
212
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
213
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
203
+ const serviceData: serviceData = await this.monitorAdvertisementPackets(switchbot);
204
+ // Update HomeKit
205
+ if (serviceData.model !== '' && serviceData.modelName !== '') {
206
+ await this.BLEparseStatus(serviceData);
207
+ await this.updateHomeKitCharacteristics();
214
208
  } else {
215
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
209
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
210
+ await this.BLERefreshConnection(switchbot);
216
211
  }
217
- };
218
- // Wait 10 seconds
219
- await switchbot.wait(this.scanDuration * 1000);
220
- // Stop to monitor
221
- await switchbot.stopScan();
222
- // Update HomeKit
223
- await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
224
- await this.updateHomeKitCharacteristics();
225
- })();
226
- if (switchbot === undefined) {
227
- await this.BLERefreshConnection(switchbot);
212
+ })();
228
213
  }
229
214
  }
230
215
 
231
216
  async openAPIRefreshStatus(): Promise<void> {
232
217
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
233
218
  try {
234
- const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
235
- `${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
236
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
219
+ const { body, statusCode } = await this.deviceRefreshStatus();
237
220
  const deviceStatus: any = await body.json();
238
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
239
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
221
+ await this.refreshStatusCodes(statusCode, deviceStatus);
240
222
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
241
- this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
242
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
243
- this.openAPIparseStatus(deviceStatus);
244
- this.updateHomeKitCharacteristics();
223
+ await this.successfulRefreshStatus(statusCode, deviceStatus);
224
+ await this.openAPIparseStatus(deviceStatus);
225
+ await this.updateHomeKitCharacteristics();
245
226
  } else {
246
- this.statusCode(statusCode);
247
- this.statusCode(deviceStatus.statusCode);
227
+ await this.statusCodes(statusCode, deviceStatus);
248
228
  }
249
229
  } catch (e: any) {
250
- this.apiError(e);
251
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
252
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
230
+ await this.apiError(e);
231
+ await this.openAPIRefreshError(e);
253
232
  }
254
233
  }
255
234
 
@@ -2,8 +2,6 @@
2
2
  *
3
3
  * airconditioners.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
- import { request } from 'undici';
6
- import { Devices } from '../settings.js';
7
5
  import { irdeviceBase } from './irdevice.js';
8
6
 
9
7
  import type { SwitchBotPlatform } from '../platform.js';
@@ -262,10 +260,8 @@ export class AirConditioner extends irdeviceBase {
262
260
 
263
261
  if (this.HeaterCooler.Active === undefined) {
264
262
  this.HeaterCooler.Active = this.hap.Characteristic.Active.INACTIVE;
265
- } else if (this.HeaterCooler.Active) {
266
- this.HeaterCooler.Active;
267
263
  } else {
268
- this.HeaterCooler.Active = this.accessory.context.Active;
264
+ this.HeaterCooler.Active = this.HeaterCooler.Active ? this.HeaterCooler.Active : this.accessory.context.Active;
269
265
  }
270
266
 
271
267
  if (this.HeaterCooler.CurrentTemperature === undefined && this.accessory.context.CurrentTemperature === undefined) {
@@ -351,29 +347,19 @@ export class AirConditioner extends irdeviceBase {
351
347
  if (this.device.connectionType === 'OpenAPI' && !this.disablePushDetail) {
352
348
  this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
353
349
  try {
354
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/commands`, {
355
- body: bodyChange,
356
- method: 'POST',
357
- headers: this.platform.generateHeaders(),
358
- });
359
- this.debugWarnLog(`${this.device.remoteType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
350
+ const { body, statusCode } = await this.pushChangeRequest(bodyChange);
360
351
  const deviceStatus: any = await body.json();
361
- this.debugWarnLog(`${this.device.remoteType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
362
- this.debugWarnLog(`${this.device.remoteType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
352
+ await this.pushStatusCodes(statusCode, deviceStatus);
363
353
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
364
- this.debugSuccessLog(`${this.device.remoteType}: ${this.accessory.displayName} `
365
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
366
- this.successLog(`${this.device.remoteType}: ${this.accessory.displayName}`
367
- + ` request to SwitchBot API, body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
368
- this.updateHomeKitCharacteristics();
354
+ await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
355
+ await this.updateHomeKitCharacteristics();
369
356
  } else {
370
- this.statusCode(statusCode);
371
- this.statusCode(deviceStatus.statusCode);
357
+ await this.statusCode(statusCode);
358
+ await this.statusCode(deviceStatus.statusCode);
372
359
  }
373
360
  } catch (e: any) {
374
- this.apiError(e);
375
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}`
376
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
361
+ await this.apiError(e);
362
+ await this.pushChangeError(e);
377
363
  }
378
364
  } else {
379
365
  this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}`
@@ -520,10 +506,8 @@ export class AirConditioner extends irdeviceBase {
520
506
 
521
507
  if (this.HeaterCooler.Active === undefined) {
522
508
  this.HeaterCooler.Active = this.hap.Characteristic.Active.INACTIVE;
523
- } else if (this.HeaterCooler.Active) {
524
- this.HeaterCooler.Active;
525
509
  } else {
526
- this.HeaterCooler.Active = this.accessory.context.Active;
510
+ this.HeaterCooler.Active = this.HeaterCooler.Active ? this.HeaterCooler.Active : this.accessory.context.Active;
527
511
  }
528
512
 
529
513
  if (this.HeaterCooler.CurrentTemperature === undefined && this.accessory.context.CurrentTemperature === undefined) {
@@ -2,8 +2,6 @@
2
2
  *
3
3
  * airpurifier.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
- import { request } from 'undici';
6
- import { Devices } from '../settings.js';
7
5
  import { irdeviceBase } from './irdevice.js';
8
6
 
9
7
  import type { SwitchBotPlatform } from '../platform.js';
@@ -226,29 +224,19 @@ export class AirPurifier extends irdeviceBase {
226
224
  if (this.device.connectionType === 'OpenAPI') {
227
225
  this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
228
226
  try {
229
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/commands`, {
230
- body: bodyChange,
231
- method: 'POST',
232
- headers: this.platform.generateHeaders(),
233
- });
234
- this.debugWarnLog(`${this.device.remoteType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
227
+ const { body, statusCode } = await this.pushChangeRequest(bodyChange);
235
228
  const deviceStatus: any = await body.json();
236
- this.debugWarnLog(`${this.device.remoteType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
237
- this.debugWarnLog(`${this.device.remoteType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
229
+ await this.pushStatusCodes(statusCode, deviceStatus);
238
230
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
239
- this.debugSuccessLog(`${this.device.remoteType}: ${this.accessory.displayName} `
240
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
241
- this.successLog(`${this.device.remoteType}: ${this.accessory.displayName}`
242
- + ` request to SwitchBot API, body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
243
- this.updateHomeKitCharacteristics();
231
+ await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
232
+ await this.updateHomeKitCharacteristics();
244
233
  } else {
245
- this.statusCode(statusCode);
246
- this.statusCode(deviceStatus.statusCode);
234
+ await this.statusCode(statusCode);
235
+ await this.statusCode(deviceStatus.statusCode);
247
236
  }
248
237
  } catch (e: any) {
249
- this.apiError(e);
250
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}`
251
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
238
+ await this.apiError(e);
239
+ await this.pushChangeError(e);
252
240
  }
253
241
  } else {
254
242
  this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}`
@@ -2,8 +2,6 @@
2
2
  *
3
3
  * camera.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
- import { request } from 'undici';
6
- import { Devices } from '../settings.js';
7
5
  import { irdeviceBase } from './irdevice.js';
8
6
 
9
7
  import type { SwitchBotPlatform } from '../platform.js';
@@ -104,29 +102,19 @@ export class Camera extends irdeviceBase {
104
102
  if (this.device.connectionType === 'OpenAPI') {
105
103
  this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
106
104
  try {
107
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/commands`, {
108
- body: bodyChange,
109
- method: 'POST',
110
- headers: this.platform.generateHeaders(),
111
- });
112
- this.debugWarnLog(`${this.device.remoteType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
105
+ const { body, statusCode } = await this.pushChangeRequest(bodyChange);
113
106
  const deviceStatus: any = await body.json();
114
- this.debugWarnLog(`${this.device.remoteType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
115
- this.debugWarnLog(`${this.device.remoteType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
107
+ await this.pushStatusCodes(statusCode, deviceStatus);
116
108
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
117
- this.debugSuccessLog(`${this.device.remoteType}: ${this.accessory.displayName} `
118
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
119
- this.successLog(`${this.device.remoteType}: ${this.accessory.displayName}`
120
- + ` request to SwitchBot API, body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
121
- this.updateHomeKitCharacteristics();
109
+ await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
110
+ await this.updateHomeKitCharacteristics();
122
111
  } else {
123
- this.statusCode(statusCode);
124
- this.statusCode(deviceStatus.statusCode);
112
+ await this.statusCode(statusCode);
113
+ await this.statusCode(deviceStatus.statusCode);
125
114
  }
126
115
  } catch (e: any) {
127
- this.apiError(e);
128
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}`
129
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
116
+ await this.apiError(e);
117
+ await this.pushChangeError(e);
130
118
  }
131
119
  } else {
132
120
  this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}`
@@ -2,8 +2,6 @@
2
2
  *
3
3
  * fan.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
- import { request } from 'undici';
6
- import { Devices } from '../settings.js';
7
5
  import { irdeviceBase } from './irdevice.js';
8
6
 
9
7
  import type { SwitchBotPlatform } from '../platform.js';
@@ -204,29 +202,19 @@ export class IRFan extends irdeviceBase {
204
202
  if (this.device.connectionType === 'OpenAPI') {
205
203
  this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
206
204
  try {
207
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/commands`, {
208
- body: bodyChange,
209
- method: 'POST',
210
- headers: this.platform.generateHeaders(),
211
- });
212
- this.debugWarnLog(`${this.device.remoteType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
205
+ const { body, statusCode } = await this.pushChangeRequest(bodyChange);
213
206
  const deviceStatus: any = await body.json();
214
- this.debugWarnLog(`${this.device.remoteType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
215
- this.debugWarnLog(`${this.device.remoteType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
207
+ await this.pushStatusCodes(statusCode, deviceStatus);
216
208
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
217
- this.debugSuccessLog(`${this.device.remoteType}: ${this.accessory.displayName} `
218
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
219
- this.successLog(`${this.device.remoteType}: ${this.accessory.displayName}`
220
- + ` request to SwitchBot API, body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
221
- this.updateHomeKitCharacteristics();
209
+ await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
210
+ await this.updateHomeKitCharacteristics();
222
211
  } else {
223
- this.statusCode(statusCode);
224
- this.statusCode(deviceStatus.statusCode);
212
+ await this.statusCode(statusCode);
213
+ await this.statusCode(deviceStatus.statusCode);
225
214
  }
226
215
  } catch (e: any) {
227
- this.apiError(e);
228
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}`
229
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
216
+ await this.apiError(e);
217
+ await this.pushChangeError(e);
230
218
  }
231
219
  } else {
232
220
  this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}`
@@ -2,6 +2,9 @@
2
2
  *
3
3
  * device.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
+ import { request } from 'undici';
6
+ import { Devices } from '../settings.js';
7
+
5
8
  import type { SwitchBotPlatform } from '../platform.js';
6
9
  import type { API, HAP, Logging, PlatformAccessory } from 'homebridge';
7
10
  import type { SwitchBotPlatformConfig, irDevicesConfig, irdevice } from '../settings.js';
@@ -189,6 +192,32 @@ export abstract class irdeviceBase {
189
192
  this.debugSuccessLog(`${device.remoteType}: ${accessory.displayName} deviceVersion: ${accessory.context.deviceVersion}`);
190
193
  }
191
194
 
195
+ async pushChangeRequest(bodyChange: string): Promise<{ body: any; statusCode: any; }> {
196
+ return await request(`${Devices}/${this.device.deviceId}/commands`, {
197
+ body: bodyChange,
198
+ method: 'POST',
199
+ headers: this.platform.generateHeaders(),
200
+ });
201
+ }
202
+
203
+ async pushStatusCodes(statusCode: any, deviceStatus: any) {
204
+ this.debugWarnLog(`${this.device.remoteType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
205
+ this.debugWarnLog(`${this.device.remoteType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
206
+ this.debugWarnLog(`${this.device.remoteType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
207
+ }
208
+
209
+ async successfulPushChange(statusCode: any, deviceStatus: any, bodyChange: any) {
210
+ this.debugSuccessLog(`${this.device.remoteType}: ${this.accessory.displayName} statusCode: ${statusCode} & deviceStatus `
211
+ + `StatusCode: ${deviceStatus.statusCode}`);
212
+ this.successLog(`${this.device.remoteType}: ${this.accessory.displayName} request to SwitchBot API,`
213
+ + ` body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
214
+ }
215
+
216
+ async pushChangeError(e: Error) {
217
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}`
218
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
219
+ }
220
+
192
221
  async disablePushOnChanges(device: irdevice & irDevicesConfig): Promise<void> {
193
222
  if (device.disablePushOn === undefined) {
194
223
  this.disablePushOn = false;
@@ -2,8 +2,6 @@
2
2
  *
3
3
  * light.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
- import { request } from 'undici';
6
- import { Devices } from '../settings.js';
7
5
  import { irdeviceBase } from './irdevice.js';
8
6
 
9
7
  import type { SwitchBotPlatform } from '../platform.js';
@@ -217,30 +215,20 @@ export class Light extends irdeviceBase {
217
215
  if (this.device.connectionType === 'OpenAPI') {
218
216
  this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
219
217
  try {
220
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/commands`, {
221
- body: bodyChange,
222
- method: 'POST',
223
- headers: this.platform.generateHeaders(),
224
- });
225
- this.debugWarnLog(`${this.device.remoteType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
218
+ const { body, statusCode } = await this.pushChangeRequest(bodyChange);
226
219
  const deviceStatus: any = await body.json();
227
- this.debugWarnLog(`${this.device.remoteType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
228
- this.debugWarnLog(`${this.device.remoteType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
220
+ await this.pushStatusCodes(statusCode, deviceStatus);
229
221
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
230
- this.debugSuccessLog(`${this.device.remoteType}: ${this.accessory.displayName} `
231
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
232
- this.successLog(`${this.device.remoteType}: ${this.accessory.displayName}`
233
- + ` request to SwitchBot API, body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
222
+ await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
234
223
  this.accessory.context.On = On;
235
- this.updateHomeKitCharacteristics();
224
+ await this.updateHomeKitCharacteristics();
236
225
  } else {
237
- this.statusCode(statusCode);
238
- this.statusCode(deviceStatus.statusCode);
226
+ await this.statusCode(statusCode);
227
+ await this.statusCode(deviceStatus.statusCode);
239
228
  }
240
229
  } catch (e: any) {
241
- this.apiError(e);
242
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}`
243
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
230
+ await this.apiError(e);
231
+ await this.pushChangeError(e);
244
232
  }
245
233
  } else {
246
234
  this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName} Connection Type: `