@switchbot/homebridge-switchbot 3.5.0 → 3.5.1-beta.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.
Files changed (134) 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 +32 -63
  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 +31 -63
  8. package/dist/device/bot.js.map +1 -1
  9. package/dist/device/ceilinglight.d.ts.map +1 -1
  10. package/dist/device/ceilinglight.js +51 -111
  11. package/dist/device/ceilinglight.js.map +1 -1
  12. package/dist/device/colorbulb.d.ts +1 -1
  13. package/dist/device/colorbulb.d.ts.map +1 -1
  14. package/dist/device/colorbulb.js +38 -113
  15. package/dist/device/colorbulb.js.map +1 -1
  16. package/dist/device/contact.d.ts.map +1 -1
  17. package/dist/device/contact.js +22 -49
  18. package/dist/device/contact.js.map +1 -1
  19. package/dist/device/curtain.d.ts.map +1 -1
  20. package/dist/device/curtain.js +53 -61
  21. package/dist/device/curtain.js.map +1 -1
  22. package/dist/device/device.d.ts +17 -1
  23. package/dist/device/device.d.ts.map +1 -1
  24. package/dist/device/device.js +112 -5
  25. package/dist/device/device.js.map +1 -1
  26. package/dist/device/fan.d.ts.map +1 -1
  27. package/dist/device/fan.js +42 -95
  28. package/dist/device/fan.js.map +1 -1
  29. package/dist/device/hub.d.ts +7 -1
  30. package/dist/device/hub.d.ts.map +1 -1
  31. package/dist/device/hub.js +52 -14
  32. package/dist/device/hub.js.map +1 -1
  33. package/dist/device/humidifier.d.ts.map +1 -1
  34. package/dist/device/humidifier.js +52 -99
  35. package/dist/device/humidifier.js.map +1 -1
  36. package/dist/device/iosensor.d.ts.map +1 -1
  37. package/dist/device/iosensor.js +25 -43
  38. package/dist/device/iosensor.js.map +1 -1
  39. package/dist/device/lightstrip.d.ts +1 -1
  40. package/dist/device/lightstrip.d.ts.map +1 -1
  41. package/dist/device/lightstrip.js +53 -115
  42. package/dist/device/lightstrip.js.map +1 -1
  43. package/dist/device/lock.d.ts +1 -1
  44. package/dist/device/lock.d.ts.map +1 -1
  45. package/dist/device/lock.js +33 -61
  46. package/dist/device/lock.js.map +1 -1
  47. package/dist/device/meter.d.ts.map +1 -1
  48. package/dist/device/meter.js +25 -43
  49. package/dist/device/meter.js.map +1 -1
  50. package/dist/device/meterplus.d.ts.map +1 -1
  51. package/dist/device/meterplus.js +24 -42
  52. package/dist/device/meterplus.js.map +1 -1
  53. package/dist/device/motion.d.ts.map +1 -1
  54. package/dist/device/motion.js +22 -40
  55. package/dist/device/motion.js.map +1 -1
  56. package/dist/device/plug.d.ts.map +1 -1
  57. package/dist/device/plug.js +29 -61
  58. package/dist/device/plug.js.map +1 -1
  59. package/dist/device/robotvacuumcleaner.d.ts +1 -1
  60. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  61. package/dist/device/robotvacuumcleaner.js +36 -77
  62. package/dist/device/robotvacuumcleaner.js.map +1 -1
  63. package/dist/device/waterdetector.d.ts.map +1 -1
  64. package/dist/device/waterdetector.js +21 -40
  65. package/dist/device/waterdetector.js.map +1 -1
  66. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  67. package/dist/irdevice/airconditioner.js +8 -25
  68. package/dist/irdevice/airconditioner.js.map +1 -1
  69. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  70. package/dist/irdevice/airpurifier.js +6 -17
  71. package/dist/irdevice/airpurifier.js.map +1 -1
  72. package/dist/irdevice/camera.d.ts.map +1 -1
  73. package/dist/irdevice/camera.js +6 -17
  74. package/dist/irdevice/camera.js.map +1 -1
  75. package/dist/irdevice/fan.d.ts.map +1 -1
  76. package/dist/irdevice/fan.js +6 -17
  77. package/dist/irdevice/fan.js.map +1 -1
  78. package/dist/irdevice/irdevice.d.ts +6 -0
  79. package/dist/irdevice/irdevice.d.ts.map +1 -1
  80. package/dist/irdevice/irdevice.js +24 -0
  81. package/dist/irdevice/irdevice.js.map +1 -1
  82. package/dist/irdevice/light.d.ts.map +1 -1
  83. package/dist/irdevice/light.js +6 -17
  84. package/dist/irdevice/light.js.map +1 -1
  85. package/dist/irdevice/other.d.ts.map +1 -1
  86. package/dist/irdevice/other.js +6 -17
  87. package/dist/irdevice/other.js.map +1 -1
  88. package/dist/irdevice/tv.d.ts.map +1 -1
  89. package/dist/irdevice/tv.js +6 -17
  90. package/dist/irdevice/tv.js.map +1 -1
  91. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  92. package/dist/irdevice/vacuumcleaner.js +6 -17
  93. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  94. package/dist/irdevice/waterheater.d.ts.map +1 -1
  95. package/dist/irdevice/waterheater.js +6 -17
  96. package/dist/irdevice/waterheater.js.map +1 -1
  97. package/dist/settings.d.ts +2 -1
  98. package/dist/settings.d.ts.map +1 -1
  99. package/dist/utils.d.ts +19 -1
  100. package/dist/utils.d.ts.map +1 -1
  101. package/dist/utils.js +20 -1
  102. package/dist/utils.js.map +1 -1
  103. package/package.json +8 -8
  104. package/src/device/blindtilt.ts +30 -63
  105. package/src/device/bot.ts +29 -63
  106. package/src/device/ceilinglight.ts +48 -111
  107. package/src/device/colorbulb.ts +37 -114
  108. package/src/device/contact.ts +20 -49
  109. package/src/device/curtain.ts +52 -62
  110. package/src/device/device.ts +124 -7
  111. package/src/device/fan.ts +40 -97
  112. package/src/device/hub.ts +53 -16
  113. package/src/device/humidifier.ts +49 -99
  114. package/src/device/iosensor.ts +23 -43
  115. package/src/device/lightstrip.ts +51 -116
  116. package/src/device/lock.ts +32 -62
  117. package/src/device/meter.ts +23 -43
  118. package/src/device/meterplus.ts +22 -42
  119. package/src/device/motion.ts +20 -40
  120. package/src/device/plug.ts +27 -61
  121. package/src/device/robotvacuumcleaner.ts +33 -78
  122. package/src/device/waterdetector.ts +20 -40
  123. package/src/irdevice/airconditioner.ts +8 -23
  124. package/src/irdevice/airpurifier.ts +6 -17
  125. package/src/irdevice/camera.ts +6 -17
  126. package/src/irdevice/fan.ts +6 -17
  127. package/src/irdevice/irdevice.ts +24 -0
  128. package/src/irdevice/light.ts +6 -17
  129. package/src/irdevice/other.ts +6 -17
  130. package/src/irdevice/tv.ts +6 -17
  131. package/src/irdevice/vacuumcleaner.ts +6 -17
  132. package/src/irdevice/waterheater.ts +6 -17
  133. package/src/settings.ts +2 -1
  134. package/src/utils.ts +20 -1
@@ -3,7 +3,6 @@
3
3
  * meterplus.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
5
  import { Units } from 'homebridge';
6
- import { Devices } from '../settings.js';
7
6
  import { deviceBase } from './device.js';
8
7
  import { Subject, interval, skipWhile } from 'rxjs';
9
8
 
@@ -172,8 +171,8 @@ export class MeterPlus extends deviceBase {
172
171
 
173
172
  // Current Temperature
174
173
  if (!this.device.meter?.hide_temperature) {
175
- serviceData.temperature!.c < 0 ? 0 : serviceData.temperature!.c > 100 ? 100 : serviceData.temperature!.c;
176
- this.TemperatureSensor!.CurrentTemperature = serviceData.temperature!.c;
174
+ const celcius = serviceData.temperature!.c < 0 ? 0 : serviceData.temperature!.c > 100 ? 100 : serviceData.temperature!.c;
175
+ this.TemperatureSensor!.CurrentTemperature = celcius;
177
176
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Temperature: ${this.TemperatureSensor!.CurrentTemperature}°c`);
178
177
  }
179
178
  }
@@ -241,58 +240,39 @@ export class MeterPlus extends deviceBase {
241
240
 
242
241
  async BLERefreshStatus(): Promise<void> {
243
242
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
244
- const switchbot = await this.platform.connectBLE();
245
- // Convert to BLE Address
246
- this.device.bleMac = this.device
247
- .deviceId!.match(/.{1,2}/g)!
248
- .join(':')
249
- .toLowerCase();
250
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
251
- this.getCustomBLEAddress(switchbot);
243
+ const switchbot = await this.switchbotBLE();
244
+
245
+ if (switchbot === undefined) {
246
+ await this.BLERefreshConnection(switchbot);
247
+ } else {
252
248
  // Start to monitor advertisement packets
253
- (async () => {
249
+ (async () => {
254
250
  // Start to monitor advertisement packets
255
- await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
256
- // Set an event handler
257
- switchbot.onadvertisement = (ad: any) => {
258
- if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
259
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
260
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
261
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
251
+ const serviceData: serviceData = await this.monitorAdvertisementPackets(switchbot);
252
+ // Update HomeKit
253
+ if (serviceData.model !== '' && serviceData.modelName !== '') {
254
+ await this.BLEparseStatus(serviceData);
255
+ await this.updateHomeKitCharacteristics();
262
256
  } else {
263
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
257
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
258
+ await this.BLERefreshConnection(switchbot);
264
259
  }
265
- };
266
- // Wait 10 seconds
267
- await switchbot.wait(this.scanDuration * 1000);
268
- // Stop to monitor
269
- await switchbot.stopScan();
270
- // Update HomeKit
271
- await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
272
- await this.updateHomeKitCharacteristics();
273
- })();
274
- if (switchbot === undefined) {
275
- await this.BLERefreshConnection(switchbot);
260
+ })();
276
261
  }
277
262
  }
278
263
 
279
264
  async openAPIRefreshStatus(): Promise<void> {
280
265
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
281
266
  try {
282
- const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
283
- `${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
284
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
267
+ const { body, statusCode } = await this.deviceRefreshStatus();
285
268
  const deviceStatus: any = await body.json();
286
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
287
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
269
+ await this.refreshStatusCodes(statusCode, deviceStatus);;
288
270
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
289
- this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
290
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
291
- this.openAPIparseStatus(deviceStatus);
292
- this.updateHomeKitCharacteristics();
271
+ await this.successfulRefreshStatus(statusCode, deviceStatus);
272
+ await this.openAPIparseStatus(deviceStatus);
273
+ await this.updateHomeKitCharacteristics();
293
274
  } else {
294
- this.statusCode(statusCode);
295
- this.statusCode(deviceStatus.statusCode);
275
+ await this.statusCodes(statusCode, deviceStatus);
296
276
  }
297
277
  } catch (e: any) {
298
278
  this.apiError(e);
@@ -3,7 +3,6 @@
3
3
  *
4
4
  * motion.ts: @switchbot/homebridge-switchbot.
5
5
  */
6
- import { Devices } from '../settings.js';
7
6
  import { deviceBase } from './device.js';
8
7
  import { Subject, interval, skipWhile } from 'rxjs';
9
8
 
@@ -250,58 +249,39 @@ export class Motion extends deviceBase {
250
249
 
251
250
  async BLERefreshStatus(): Promise<void> {
252
251
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
253
- const switchbot = await this.platform.connectBLE();
254
- // Convert to BLE Address
255
- this.device.bleMac = this.device
256
- .deviceId!.match(/.{1,2}/g)!
257
- .join(':')
258
- .toLowerCase();
259
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
260
- this.getCustomBLEAddress(switchbot);
252
+ const switchbot = await this.switchbotBLE();
253
+
254
+ if (switchbot === undefined) {
255
+ await this.BLERefreshConnection(switchbot);
256
+ } else {
261
257
  // Start to monitor advertisement packets
262
- (async () => {
258
+ (async () => {
263
259
  // Start to monitor advertisement packets
264
- await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
265
- // Set an event handler
266
- switchbot.onadvertisement = (ad: any) => {
267
- if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
268
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
269
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
270
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
260
+ const serviceData: serviceData = await this.monitorAdvertisementPackets(switchbot);
261
+ // Update HomeKit
262
+ if (serviceData.model !== '' && serviceData.modelName !== '') {
263
+ await this.BLEparseStatus(serviceData);
264
+ await this.updateHomeKitCharacteristics();
271
265
  } else {
272
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
266
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
267
+ await this.BLERefreshConnection(switchbot);
273
268
  }
274
- };
275
- // Wait 10 seconds
276
- await switchbot.wait(this.scanDuration * 1000);
277
- // Stop to monitor
278
- await switchbot.stopScan();
279
- // Update HomeKit
280
- await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
281
- await this.updateHomeKitCharacteristics();
282
- })();
283
- if (switchbot === undefined) {
284
- await this.BLERefreshConnection(switchbot);
269
+ })();
285
270
  }
286
271
  }
287
272
 
288
273
  async openAPIRefreshStatus(): Promise<void> {
289
274
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
290
275
  try {
291
- const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
292
- `${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
293
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
276
+ const { body, statusCode } = await this.deviceRefreshStatus();
294
277
  const deviceStatus: any = await body.json();
295
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
296
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
278
+ await this.refreshStatusCodes(statusCode, deviceStatus);;
297
279
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
298
- this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
299
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
300
- this.openAPIparseStatus(deviceStatus);
301
- this.updateHomeKitCharacteristics();
280
+ await this.successfulRefreshStatus(statusCode, deviceStatus);
281
+ await this.openAPIparseStatus(deviceStatus);
282
+ await this.updateHomeKitCharacteristics();
302
283
  } else {
303
- this.statusCode(statusCode);
304
- this.statusCode(deviceStatus.statusCode);
284
+ await this.statusCodes(statusCode, deviceStatus);
305
285
  }
306
286
  } catch (e: any) {
307
287
  this.apiError(e);
@@ -2,8 +2,6 @@
2
2
  *
3
3
  * plug.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, debounceTime, interval, skipWhile, take, tap } from 'rxjs';
9
7
 
@@ -146,58 +144,39 @@ export class Plug extends deviceBase {
146
144
 
147
145
  async BLERefreshStatus(): Promise<void> {
148
146
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
149
- const switchbot = await this.platform.connectBLE();
150
- // Convert to BLE Address
151
- this.device.bleMac = this.device
152
- .deviceId!.match(/.{1,2}/g)!
153
- .join(':')
154
- .toLowerCase();
155
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
156
- this.getCustomBLEAddress(switchbot);
147
+ const switchbot = await this.switchbotBLE();
148
+
149
+ if (switchbot === undefined) {
150
+ await this.BLERefreshConnection(switchbot);
151
+ } else {
157
152
  // Start to monitor advertisement packets
158
- (async () => {
153
+ (async () => {
159
154
  // Start to monitor advertisement packets
160
- await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
161
- // Set an event handler
162
- switchbot.onadvertisement = (ad: any) => {
163
- if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
164
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
165
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
166
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
155
+ const serviceData: serviceData = await this.monitorAdvertisementPackets(switchbot);
156
+ // Update HomeKit
157
+ if (serviceData.model !== '' && serviceData.modelName !== '') {
158
+ await this.BLEparseStatus(serviceData);
159
+ await this.updateHomeKitCharacteristics();
167
160
  } else {
168
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
161
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
162
+ await this.BLERefreshConnection(switchbot);
169
163
  }
170
- };
171
- // Wait 10 seconds
172
- await switchbot.wait(this.scanDuration * 1000);
173
- // Stop to monitor
174
- await switchbot.stopScan();
175
- // Update HomeKit
176
- await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
177
- await this.updateHomeKitCharacteristics();
178
- })();
179
- if (switchbot === undefined) {
180
- await this.BLERefreshConnection(switchbot);
164
+ })();
181
165
  }
182
166
  }
183
167
 
184
168
  async openAPIRefreshStatus(): Promise<void> {
185
169
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
186
170
  try {
187
- const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
188
- `${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
189
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
171
+ const { body, statusCode } = await this.deviceRefreshStatus();
190
172
  const deviceStatus: any = await body.json();
191
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
192
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
173
+ await this.refreshStatusCodes(statusCode, deviceStatus);;
193
174
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
194
- this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
195
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
196
- this.openAPIparseStatus(deviceStatus);
197
- this.updateHomeKitCharacteristics();
175
+ await this.successfulRefreshStatus(statusCode, deviceStatus);
176
+ await this.openAPIparseStatus(deviceStatus);
177
+ await this.updateHomeKitCharacteristics();
198
178
  } else {
199
- this.statusCode(statusCode);
200
- this.statusCode(deviceStatus.statusCode);
179
+ await this.statusCodes(statusCode, deviceStatus);
201
180
  }
202
181
  } catch (e: any) {
203
182
  this.apiError(e);
@@ -264,11 +243,7 @@ export class Plug extends deviceBase {
264
243
  + ` On: ${this.Outlet.On} OnCached: ${this.accessory.context.On}`);
265
244
  const switchbot = await this.platform.connectBLE();
266
245
  // Convert to BLE Address
267
- this.device.bleMac = this.device
268
- .deviceId!.match(/.{1,2}/g)!
269
- .join(':')
270
- .toLowerCase();
271
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
246
+ await this.convertBLEAddress();
272
247
  switchbot
273
248
  .discover({
274
249
  model: this.device.bleModel,
@@ -321,24 +296,15 @@ export class Plug extends deviceBase {
321
296
  });
322
297
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
323
298
  try {
324
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/commands`, {
325
- body: bodyChange,
326
- method: 'POST',
327
- headers: this.platform.generateHeaders(),
328
- });
329
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
299
+ const { body, statusCode } = await this.pushChangeRequest(bodyChange);
330
300
  const deviceStatus: any = await body.json();
331
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
332
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus body: ${JSON.stringify(deviceStatus.body)}`);
333
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
301
+ await this.pushStatusCodes(statusCode, deviceStatus);
334
302
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
335
- this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
336
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
337
- this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
338
- + `request to SwitchBot API, body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
303
+ await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
304
+ await this.updateHomeKitCharacteristics();
339
305
  } else {
340
- this.statusCode(statusCode);
341
- this.statusCode(deviceStatus.statusCode);
306
+ await this.statusCode(statusCode);
307
+ await this.statusCode(deviceStatus.statusCode);
342
308
  }
343
309
  } catch (e: any) {
344
310
  this.apiError(e);
@@ -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,58 +229,39 @@ 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
267
  this.apiError(e);
@@ -333,8 +307,8 @@ export class RobotVacuumCleaner extends deviceBase {
333
307
  async pushChanges(): Promise<void> {
334
308
  if (!this.device.enableCloudService && this.OpenAPI) {
335
309
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} pushChanges enableCloudService: ${this.device.enableCloudService}`);
336
- /*} else if (this.BLE) {
337
- await this.BLEpushChanges();*/
310
+ } else if (this.BLE) {
311
+ await this.BLEpushChanges();
338
312
  } else if (this.OpenAPI && this.platform.config.credentials?.token) {
339
313
  await this.openAPIpushChanges();
340
314
  } else {
@@ -358,11 +332,7 @@ export class RobotVacuumCleaner extends deviceBase {
358
332
  + ` On: ${this.LightBulb.On} OnCached: ${this.accessory.context.On}`);
359
333
  const switchbot = await this.platform.connectBLE();
360
334
  // 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}`);
335
+ await this.convertBLEAddress();
366
336
  switchbot
367
337
  .discover({
368
338
  model: '?',
@@ -405,16 +375,9 @@ export class RobotVacuumCleaner extends deviceBase {
405
375
  const bodyChange = await this.commands();
406
376
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
407
377
  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}`);
378
+ const { body, statusCode } = await this.pushChangeRequest(bodyChange);
414
379
  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}`);
380
+ await this.pushStatusCodes(statusCode, deviceStatus);
418
381
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
419
382
  this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
420
383
  + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
@@ -440,23 +403,15 @@ export class RobotVacuumCleaner extends deviceBase {
440
403
  const bodyChange = await this.brightnessCommands();
441
404
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
442
405
  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}`);
406
+ const { body, statusCode } = await this.pushChangeRequest(bodyChange);
449
407
  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}`);
408
+ await this.refreshStatusCodes(statusCode, deviceStatus);;
452
409
  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`);
410
+ await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
411
+ await this.updateHomeKitCharacteristics();
457
412
  } else {
458
- this.statusCode(statusCode);
459
- this.statusCode(deviceStatus.statusCode);
413
+ await this.statusCode(statusCode);
414
+ await this.statusCode(deviceStatus.statusCode);
460
415
  }
461
416
  } catch (e: any) {
462
417
  this.apiError(e);
@@ -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,58 +192,39 @@ 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
230
  this.apiError(e);