@switchbot/homebridge-switchbot 3.5.1-beta.2 → 3.5.1-beta.4

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 (187) hide show
  1. package/dist/device/blindtilt.d.ts +15 -6
  2. package/dist/device/blindtilt.d.ts.map +1 -1
  3. package/dist/device/blindtilt.js +203 -255
  4. package/dist/device/blindtilt.js.map +1 -1
  5. package/dist/device/bot.d.ts +9 -4
  6. package/dist/device/bot.d.ts.map +1 -1
  7. package/dist/device/bot.js +196 -218
  8. package/dist/device/bot.js.map +1 -1
  9. package/dist/device/ceilinglight.d.ts +9 -4
  10. package/dist/device/ceilinglight.d.ts.map +1 -1
  11. package/dist/device/ceilinglight.js +202 -247
  12. package/dist/device/ceilinglight.js.map +1 -1
  13. package/dist/device/colorbulb.d.ts +10 -5
  14. package/dist/device/colorbulb.d.ts.map +1 -1
  15. package/dist/device/colorbulb.js +329 -378
  16. package/dist/device/colorbulb.js.map +1 -1
  17. package/dist/device/contact.d.ts +9 -4
  18. package/dist/device/contact.d.ts.map +1 -1
  19. package/dist/device/contact.js +99 -142
  20. package/dist/device/contact.js.map +1 -1
  21. package/dist/device/curtain.d.ts +19 -7
  22. package/dist/device/curtain.d.ts.map +1 -1
  23. package/dist/device/curtain.js +203 -264
  24. package/dist/device/curtain.js.map +1 -1
  25. package/dist/device/device.d.ts +28 -32
  26. package/dist/device/device.d.ts.map +1 -1
  27. package/dist/device/device.js +186 -225
  28. package/dist/device/device.js.map +1 -1
  29. package/dist/device/fan.d.ts +9 -4
  30. package/dist/device/fan.d.ts.map +1 -1
  31. package/dist/device/fan.js +198 -227
  32. package/dist/device/fan.js.map +1 -1
  33. package/dist/device/hub.d.ts +9 -5
  34. package/dist/device/hub.d.ts.map +1 -1
  35. package/dist/device/hub.js +106 -231
  36. package/dist/device/hub.js.map +1 -1
  37. package/dist/device/humidifier.d.ts +12 -4
  38. package/dist/device/humidifier.d.ts.map +1 -1
  39. package/dist/device/humidifier.js +192 -232
  40. package/dist/device/humidifier.js.map +1 -1
  41. package/dist/device/iosensor.d.ts +9 -4
  42. package/dist/device/iosensor.d.ts.map +1 -1
  43. package/dist/device/iosensor.js +91 -157
  44. package/dist/device/iosensor.js.map +1 -1
  45. package/dist/device/lightstrip.d.ts +10 -5
  46. package/dist/device/lightstrip.d.ts.map +1 -1
  47. package/dist/device/lightstrip.js +287 -367
  48. package/dist/device/lightstrip.js.map +1 -1
  49. package/dist/device/lock.d.ts +10 -5
  50. package/dist/device/lock.d.ts.map +1 -1
  51. package/dist/device/lock.js +171 -216
  52. package/dist/device/lock.js.map +1 -1
  53. package/dist/device/meter.d.ts +9 -4
  54. package/dist/device/meter.d.ts.map +1 -1
  55. package/dist/device/meter.js +93 -158
  56. package/dist/device/meter.js.map +1 -1
  57. package/dist/device/meterplus.d.ts +9 -4
  58. package/dist/device/meterplus.d.ts.map +1 -1
  59. package/dist/device/meterplus.js +94 -155
  60. package/dist/device/meterplus.js.map +1 -1
  61. package/dist/device/motion.d.ts +9 -4
  62. package/dist/device/motion.d.ts.map +1 -1
  63. package/dist/device/motion.js +84 -142
  64. package/dist/device/motion.js.map +1 -1
  65. package/dist/device/plug.d.ts +9 -4
  66. package/dist/device/plug.d.ts.map +1 -1
  67. package/dist/device/plug.js +99 -124
  68. package/dist/device/plug.js.map +1 -1
  69. package/dist/device/robotvacuumcleaner.d.ts +9 -6
  70. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  71. package/dist/device/robotvacuumcleaner.js +170 -253
  72. package/dist/device/robotvacuumcleaner.js.map +1 -1
  73. package/dist/device/waterdetector.d.ts +12 -4
  74. package/dist/device/waterdetector.d.ts.map +1 -1
  75. package/dist/device/waterdetector.js +102 -128
  76. package/dist/device/waterdetector.js.map +1 -1
  77. package/dist/irdevice/airconditioner.d.ts +2 -1
  78. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  79. package/dist/irdevice/airconditioner.js.map +1 -1
  80. package/dist/irdevice/airpurifier.d.ts +2 -1
  81. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  82. package/dist/irdevice/airpurifier.js.map +1 -1
  83. package/dist/irdevice/camera.d.ts +2 -1
  84. package/dist/irdevice/camera.d.ts.map +1 -1
  85. package/dist/irdevice/camera.js.map +1 -1
  86. package/dist/irdevice/fan.d.ts +2 -1
  87. package/dist/irdevice/fan.d.ts.map +1 -1
  88. package/dist/irdevice/fan.js.map +1 -1
  89. package/dist/irdevice/irdevice.d.ts +2 -1
  90. package/dist/irdevice/irdevice.d.ts.map +1 -1
  91. package/dist/irdevice/irdevice.js +1 -1
  92. package/dist/irdevice/irdevice.js.map +1 -1
  93. package/dist/irdevice/light.d.ts +2 -1
  94. package/dist/irdevice/light.d.ts.map +1 -1
  95. package/dist/irdevice/light.js.map +1 -1
  96. package/dist/irdevice/other.d.ts +2 -1
  97. package/dist/irdevice/other.d.ts.map +1 -1
  98. package/dist/irdevice/other.js.map +1 -1
  99. package/dist/irdevice/tv.d.ts +2 -1
  100. package/dist/irdevice/tv.d.ts.map +1 -1
  101. package/dist/irdevice/tv.js.map +1 -1
  102. package/dist/irdevice/vacuumcleaner.d.ts +2 -1
  103. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  104. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  105. package/dist/irdevice/waterheater.d.ts +2 -1
  106. package/dist/irdevice/waterheater.d.ts.map +1 -1
  107. package/dist/irdevice/waterheater.js.map +1 -1
  108. package/dist/platform.d.ts +5 -7
  109. package/dist/platform.d.ts.map +1 -1
  110. package/dist/platform.js +51 -34
  111. package/dist/platform.js.map +1 -1
  112. package/dist/settings.d.ts +49 -191
  113. package/dist/settings.d.ts.map +1 -1
  114. package/dist/settings.js +19 -0
  115. package/dist/settings.js.map +1 -1
  116. package/dist/types/bledevicestatus.d.ts +279 -0
  117. package/dist/types/bledevicestatus.d.ts.map +1 -0
  118. package/dist/types/bledevicestatus.js +2 -0
  119. package/dist/types/bledevicestatus.js.map +1 -0
  120. package/dist/types/devicelist.d.ts +89 -0
  121. package/dist/types/devicelist.d.ts.map +1 -0
  122. package/dist/types/devicelist.js +6 -0
  123. package/dist/types/devicelist.js.map +1 -0
  124. package/dist/types/deviceresponse.d.ts +13 -0
  125. package/dist/types/deviceresponse.d.ts.map +1 -0
  126. package/dist/types/deviceresponse.js +2 -0
  127. package/dist/types/deviceresponse.js.map +1 -0
  128. package/dist/types/devicestatus.d.ts +149 -0
  129. package/dist/types/devicestatus.d.ts.map +1 -0
  130. package/dist/types/devicestatus.js +3 -0
  131. package/dist/types/devicestatus.js.map +1 -0
  132. package/dist/types/devicewebhookstatus.d.ts +156 -0
  133. package/dist/types/devicewebhookstatus.d.ts.map +1 -0
  134. package/dist/types/devicewebhookstatus.js +2 -0
  135. package/dist/types/devicewebhookstatus.js.map +1 -0
  136. package/dist/types/irdevicelist.d.ts +10 -0
  137. package/dist/types/irdevicelist.d.ts.map +1 -0
  138. package/dist/types/irdevicelist.js +2 -0
  139. package/dist/types/irdevicelist.js.map +1 -0
  140. package/dist/types/pushbody.d.ts +6 -0
  141. package/dist/types/pushbody.d.ts.map +1 -0
  142. package/dist/types/pushbody.js +2 -0
  143. package/dist/types/pushbody.js.map +1 -0
  144. package/dist/utils.d.ts +25 -0
  145. package/dist/utils.d.ts.map +1 -1
  146. package/dist/utils.js +28 -0
  147. package/dist/utils.js.map +1 -1
  148. package/package.json +10 -10
  149. package/src/device/blindtilt.ts +224 -264
  150. package/src/device/bot.ts +208 -221
  151. package/src/device/ceilinglight.ts +210 -257
  152. package/src/device/colorbulb.ts +334 -397
  153. package/src/device/contact.ts +111 -146
  154. package/src/device/curtain.ts +220 -283
  155. package/src/device/device.ts +194 -245
  156. package/src/device/fan.ts +214 -230
  157. package/src/device/hub.ts +126 -246
  158. package/src/device/humidifier.ts +216 -243
  159. package/src/device/iosensor.ts +114 -166
  160. package/src/device/lightstrip.ts +302 -377
  161. package/src/device/lock.ts +187 -221
  162. package/src/device/meter.ts +116 -177
  163. package/src/device/meterplus.ts +117 -174
  164. package/src/device/motion.ts +99 -144
  165. package/src/device/plug.ts +110 -128
  166. package/src/device/robotvacuumcleaner.ts +189 -252
  167. package/src/device/waterdetector.ts +120 -138
  168. package/src/irdevice/airconditioner.ts +2 -1
  169. package/src/irdevice/airpurifier.ts +2 -1
  170. package/src/irdevice/camera.ts +2 -1
  171. package/src/irdevice/fan.ts +2 -1
  172. package/src/irdevice/irdevice.ts +3 -2
  173. package/src/irdevice/light.ts +2 -1
  174. package/src/irdevice/other.ts +2 -1
  175. package/src/irdevice/tv.ts +2 -1
  176. package/src/irdevice/vacuumcleaner.ts +2 -1
  177. package/src/irdevice/waterheater.ts +2 -1
  178. package/src/platform.ts +52 -34
  179. package/src/settings.ts +30 -239
  180. package/src/types/bledevicestatus.ts +305 -0
  181. package/src/types/devicelist.ts +124 -0
  182. package/src/types/deviceresponse.ts +15 -0
  183. package/src/types/devicestatus.ts +178 -0
  184. package/src/types/devicewebhookstatus.ts +196 -0
  185. package/src/types/irdevicelist.ts +15 -0
  186. package/src/types/pushbody.ts +9 -0
  187. package/src/utils.ts +33 -0
@@ -3,12 +3,16 @@
3
3
  * curtain.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
5
  import { hostname } from 'os';
6
- import { interval, Subject } from 'rxjs';
7
6
  import { deviceBase } from './device.js';
8
- import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
7
+ import { SwitchBotBLEModel, SwitchBotBLEModelName } from 'node-switchbot';
8
+ import { Subject, debounceTime, interval, skipWhile, take, tap } from 'rxjs';
9
9
 
10
+ import type { devicesConfig } from '../settings.js';
11
+ import type { device } from '../types/devicelist.js';
10
12
  import type { SwitchBotPlatform } from '../platform.js';
11
- import type { device, devicesConfig, serviceData, deviceStatus } from '../settings.js';
13
+ import type { curtainStatus } from '../types/devicestatus.js';
14
+ import type { curtainServiceData, curtain3ServiceData } from '../types/bledevicestatus.js';
15
+ import type { curtain3WebhookContext, curtainWebhookContext } from '../types/devicewebhookstatus.js';
12
16
  import type { Service, PlatformAccessory, CharacteristicValue, CharacteristicChange } from 'homebridge';
13
17
 
14
18
  export class Curtain extends deviceBase {
@@ -50,8 +54,7 @@ export class Curtain extends deviceBase {
50
54
  device: device & devicesConfig,
51
55
  ) {
52
56
  super(platform, accessory, device);
53
- // default placeholder
54
- this.history(device);
57
+
55
58
  // this is subject we use to track when we need to POST changes to the SwitchBot API
56
59
  this.doCurtainUpdate = new Subject();
57
60
  this.curtainUpdateInProgress = false;
@@ -147,7 +150,7 @@ export class Curtain extends deviceBase {
147
150
  // Initialize LightSensor Service
148
151
  if (device.curtain?.hide_lightsensor) {
149
152
  if (this.LightSensor?.Service) {
150
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Light Sensor Service`);
153
+ this.debugLog('Removing Light Sensor Service');
151
154
  this.LightSensor.Service = this.accessory.getService(this.hap.Service.LightSensor) as Service;
152
155
  accessory.removeService(this.LightSensor.Service);
153
156
  accessory.context.LightSensor = {};
@@ -177,6 +180,12 @@ export class Curtain extends deviceBase {
177
180
  // Update Homekit
178
181
  this.updateHomeKitCharacteristics();
179
182
 
183
+ //regisiter webhook event handler
184
+ this.registerWebhook();
185
+
186
+ // History
187
+ this.history();
188
+
180
189
  // Start an update interval
181
190
  interval(this.deviceRefreshRate * 1000)
182
191
  .pipe(skipWhile(() => this.curtainUpdateInProgress))
@@ -184,9 +193,6 @@ export class Curtain extends deviceBase {
184
193
  await this.refreshStatus();
185
194
  });
186
195
 
187
- //regisiter webhook event handler
188
- this.registerWebhook(accessory, device);
189
-
190
196
  // update slide progress
191
197
  interval(this.deviceUpdateRate * 1000)
192
198
  //.pipe(skipWhile(() => this.curtainUpdateInProgress))
@@ -194,8 +200,7 @@ export class Curtain extends deviceBase {
194
200
  if (this.WindowCovering.PositionState === this.hap.Characteristic.PositionState.STOPPED) {
195
201
  return;
196
202
  }
197
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Refresh Status When Moving,`
198
- + ` PositionState: ${this.WindowCovering.PositionState}`);
203
+ await this.debugLog(`Refresh Status When Moving, PositionState: ${this.WindowCovering.PositionState}`);
199
204
  await this.refreshStatus();
200
205
  });
201
206
 
@@ -212,19 +217,18 @@ export class Curtain extends deviceBase {
212
217
  try {
213
218
  await this.pushChanges();
214
219
  } catch (e: any) {
215
- this.apiError(e);
216
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
217
- + ` Error Message: ${JSON.stringify(e.message)}`);
220
+ await this.apiError(e);
221
+ await this.errorLog(`failed pushChanges with ${device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
218
222
  }
219
223
  this.curtainUpdateInProgress = false;
220
224
  });
221
225
 
222
226
  // Setup EVE history features
223
- this.setupHistoryService(accessory, device);
227
+ this.setupHistoryService();
224
228
  }
225
229
 
226
- private history(device: device & devicesConfig) {
227
- if (device.history === true) {
230
+ async history() {
231
+ if (this.device.history === true) {
228
232
  // initialize when this accessory is newly created.
229
233
  this.accessory.context.lastActivation = this.accessory.context.lastActivation ?? 0;
230
234
  } else {
@@ -236,8 +240,8 @@ export class Curtain extends deviceBase {
236
240
  /*
237
241
  * Setup EVE history features for curtain devices.
238
242
  */
239
- async setupHistoryService(accessory: PlatformAccessory, device: device & devicesConfig): Promise<void> {
240
- if (device.history !== true) {
243
+ async setupHistoryService(): Promise<void> {
244
+ if (this.device.history !== true) {
241
245
  return;
242
246
  }
243
247
 
@@ -284,192 +288,90 @@ export class Curtain extends deviceBase {
284
288
  time: Math.round(new Date().valueOf() / 1000),
285
289
  motion: motion,
286
290
  });
287
- setTimeout(
288
- () => {
289
- this.updateHistory();
290
- },
291
- 10 * 60 * 1000,
292
- );
291
+ setTimeout(async () => {
292
+ await this.updateHistory();
293
+ }, 10 * 60 * 1000);
293
294
  }
294
295
 
295
- async BLEparseStatus(serviceData: serviceData): Promise<void> {
296
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
297
- this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(serviceData)}`);
296
+ async BLEparseStatus(serviceData: curtainServiceData | curtain3ServiceData): Promise<void> {
297
+ await this.debugLog('BLEparseStatus');
298
298
  // CurrentPosition
299
- this.WindowCovering.CurrentPosition = 100 - Number(serviceData.position!);
300
- await this.setMinMax();
301
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition ${this.WindowCovering.CurrentPosition}`);
302
- if (this.setNewTarget) {
303
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Checking Status ...`);
304
- await this.setMinMax();
305
- if (Number(this.WindowCovering.TargetPosition) > this.WindowCovering.CurrentPosition) {
306
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
307
- this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
308
- this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
309
- this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} INCREASING`
310
- + ` PositionState: ${this.WindowCovering.PositionState}`);
311
- } else if (Number(this.WindowCovering.TargetPosition) < this.WindowCovering.CurrentPosition) {
312
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
313
- this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
314
- this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
315
- this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} DECREASING`
316
- + ` PositionState: ${this.WindowCovering.PositionState}`);
317
- } else {
318
- this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} Standby,`
319
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
320
- this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
321
- this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
322
- this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} STOPPED`
323
- + ` PositionState: ${this.WindowCovering.PositionState}`);
324
- }
325
- } else {
326
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
327
- this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition;
328
- this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
329
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Stopped`);
330
- }
331
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition},`
332
- + ` TargetPosition: ${this.WindowCovering.TargetPosition}, PositionState: ${this.WindowCovering.PositionState},`);
333
-
334
- if (!this.device.curtain?.hide_lightsensor) {
299
+ this.WindowCovering.CurrentPosition = 100 - serviceData.position;
300
+ await this.getCurrentPostion();
301
+ // CurrentAmbientLightLevel
302
+ if (!this.device.curtain?.hide_lightsensor && this.LightSensor?.Service) {
335
303
  const set_minLux = this.device.curtain?.set_minLux ?? 1;
336
304
  const set_maxLux = this.device.curtain?.set_maxLux ?? 6001;
337
- const spaceBetweenLevels = 9;
338
-
339
- // Brightness
340
- switch (serviceData.lightLevel) {
341
- case 1:
342
- this.LightSensor!.CurrentAmbientLightLevel = set_minLux;
343
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
344
- break;
345
- case 2:
346
- this.LightSensor!.CurrentAmbientLightLevel = (set_maxLux - set_minLux) / spaceBetweenLevels;
347
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel},`
348
- + ` Calculation: ${(set_maxLux - set_minLux) / spaceBetweenLevels}`);
349
- break;
350
- case 3:
351
- this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 2;
352
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
353
- break;
354
- case 4:
355
- this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 3;
356
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
357
- break;
358
- case 5:
359
- this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 4;
360
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
361
- break;
362
- case 6:
363
- this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 5;
364
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
365
- break;
366
- case 7:
367
- this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 6;
368
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
369
- break;
370
- case 8:
371
- this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 7;
372
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
373
- break;
374
- case 9:
375
- this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 8;
376
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
377
- break;
378
- case 10:
379
- default:
380
- this.LightSensor!.CurrentAmbientLightLevel = set_maxLux;
381
- this.debugLog();
382
- }
383
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel},`
384
- + ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
305
+ const lightLevel = Number(serviceData.lightLevel);
306
+ this.LightSensor.CurrentAmbientLightLevel = await this.getLightLevel(lightLevel, set_minLux, set_maxLux, 19);
307
+ this.debugLog(`LightLevel: ${serviceData.lightLevel},`
308
+ + ` CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`);
385
309
  }
386
- // Battery
310
+ // BatteryLevel
387
311
  this.Battery.BatteryLevel = Number(serviceData.battery);
388
- if (this.Battery.BatteryLevel < 10) {
389
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
390
- } else {
391
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
392
- }
393
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
394
- + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
312
+ await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
313
+ // StatusLowBattery
314
+ this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
315
+ ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
316
+ await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`);
395
317
  }
396
318
 
397
- async openAPIparseStatus(deviceStatus: deviceStatus): Promise<void> {
398
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
319
+ async openAPIparseStatus(deviceStatus: curtainStatus): Promise<void> {
320
+ await this.debugLog('openAPIparseStatus');
399
321
  // CurrentPosition
400
- this.WindowCovering!.CurrentPosition = 100 - Number(deviceStatus.body.slidePosition);
322
+ this.WindowCovering.CurrentPosition = 100 - deviceStatus.slidePosition;
401
323
  await this.setMinMax();
402
- this.debugLog(`Curtain ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
324
+ await this.debugLog(`Curtain ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
403
325
  if (this.setNewTarget) {
404
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Checking Status ...`);
326
+ await this.infoLog('Checking Status ...');
405
327
  }
406
-
407
- if (this.setNewTarget && deviceStatus.body.moving) {
328
+ if (this.setNewTarget && deviceStatus.moving) {
408
329
  await this.setMinMax();
409
330
  if (Number(this.WindowCovering.TargetPosition) > this.WindowCovering.CurrentPosition) {
410
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition} `);
331
+ await this.debugLog(`Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
411
332
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
412
333
  this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
413
- this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} INCREASING`
414
- + ` PositionState: ${this.WindowCovering.PositionState}`);
334
+ await this.debugLog(`Increasing, PositionState: ${this.WindowCovering.PositionState}`);
415
335
  } else if (Number(this.WindowCovering.TargetPosition) < this.WindowCovering.CurrentPosition) {
416
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition} `);
336
+ await this.debugLog(`Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
417
337
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
418
338
  this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
419
- this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} DECREASING`
420
- + ` PositionState: ${this.WindowCovering.PositionState}`);
339
+ await this.debugLog(`Decreasing, PositionState: ${this.WindowCovering.PositionState}`);
421
340
  } else {
422
- this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} Standby,`
423
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
341
+ await this.debugLog(`Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
424
342
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
425
343
  this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
426
- this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} STOPPED`
427
- + ` PositionState: ${this.WindowCovering.PositionState}`);
344
+ await this.debugLog(`Stopped, PositionState: ${this.WindowCovering.PositionState}`);
428
345
  }
429
346
  } else {
430
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
347
+ await this.debugLog(`Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
431
348
  this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition;
432
349
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
433
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Stopped`);
350
+ await this.debugLog(`Stopped, PositionState: ${this.WindowCovering.PositionState}`);
434
351
  }
435
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition},`
436
- + ` TargetPosition: ${this.WindowCovering.TargetPosition}, PositionState: ${this.WindowCovering.PositionState},`);
437
-
352
+ await this.debugLog(`CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition: ${this.WindowCovering.TargetPosition},`
353
+ + ` PositionState: ${this.WindowCovering.PositionState},`);
438
354
  // Brightness
439
- if (!this.device.curtain?.hide_lightsensor) {
355
+ if (!this.device.curtain?.hide_lightsensor && this.LightSensor?.Service) {
440
356
  const set_minLux = this.device.curtain?.set_minLux ?? 1;
441
357
  const set_maxLux = this.device.curtain?.set_maxLux ?? 6001;
442
- switch (deviceStatus.body.brightness) {
443
- case 'bright':
444
- this.LightSensor!.CurrentAmbientLightLevel = set_maxLux;
445
- this.Battery.ChargingState = this.hap.Characteristic.ChargingState.CHARGING;
446
- break;
447
- case 'dim':
448
- default:
449
- this.LightSensor!.CurrentAmbientLightLevel = set_minLux;
450
- }
451
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
452
- + ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
358
+ const lightLevel = deviceStatus.lightLevel === 'bright' ? set_maxLux : set_minLux;
359
+ this.LightSensor.CurrentAmbientLightLevel = await this.getLightLevel(lightLevel, set_minLux, set_maxLux, 2);
360
+ await this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
361
+ + ` CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`);
453
362
  }
454
-
455
363
  // BatteryLevel
456
- this.Battery.BatteryLevel = Number(deviceStatus.body.battery);
457
- if (this.Battery.BatteryLevel < 10) {
458
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
459
- } else {
460
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
461
- }
462
- if (Number.isNaN(this.Battery.BatteryLevel)) {
463
- this.Battery.BatteryLevel = 100;
464
- }
465
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
466
- + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
467
-
364
+ this.Battery.BatteryLevel = Number(deviceStatus.battery);
365
+ await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
366
+ // StatusLowBattery
367
+ this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
368
+ ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
369
+ await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`);
468
370
  // Firmware Version
469
- const version = deviceStatus.body.version?.toString();
470
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Firmware Version: ${version?.replace(/^V|-.*$/g, '')}`);
471
- if (deviceStatus.body.version) {
472
- const deviceVersion = version?.replace(/^V|-.*$/g, '') ?? '0.0.0';
371
+ if (deviceStatus.version) {
372
+ const version = deviceStatus.version.toString();
373
+ await this.debugLog(`Firmware Version: ${version.replace(/^V|-.*$/g, '')}`);
374
+ const deviceVersion = version.replace(/^V|-.*$/g, '') ?? '0.0.0';
473
375
  this.accessory
474
376
  .getService(this.hap.Service.AccessoryInformation)!
475
377
  .setCharacteristic(this.hap.Characteristic.HardwareRevision, deviceVersion)
@@ -477,26 +379,44 @@ export class Curtain extends deviceBase {
477
379
  .getCharacteristic(this.hap.Characteristic.FirmwareRevision)
478
380
  .updateValue(deviceVersion);
479
381
  this.accessory.context.deviceVersion = deviceVersion;
480
- this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceVersion: ${this.accessory.context.deviceVersion}`);
382
+ await this.debugSuccessLog(`deviceVersion: ${this.accessory.context.deviceVersion}`);
481
383
  }
482
384
  }
483
385
 
386
+ async parseStatusWebhook(context: curtainWebhookContext | curtain3WebhookContext): Promise<void> {
387
+ await this.debugLog('parseStatusWebhook');
388
+ await this.debugLog(`(slidePosition, battery) = Webhook:(${context.slidePosition}, ${context.battery}),`
389
+ + ` current:(${this.WindowCovering.CurrentPosition}, ${this.Battery.BatteryLevel})`);
390
+ // CurrentPosition
391
+ this.WindowCovering.CurrentPosition = 100 - context.slidePosition;
392
+ await this.getCurrentPostion();
393
+ // BatteryLevel
394
+ this.Battery.BatteryLevel = context.battery;
395
+ await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
396
+ // StatusLowBattery
397
+ this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
398
+ ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
399
+ await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`);
400
+ }
401
+
402
+ /**
403
+ * Asks the SwitchBot API for the latest device information
404
+ */
484
405
  async refreshStatus(): Promise<void> {
485
406
  if (!this.device.enableCloudService && this.OpenAPI) {
486
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} refreshStatus enableCloudService: ${this.device.enableCloudService}`);
407
+ await this.errorLog(`refreshStatus enableCloudService: ${this.device.enableCloudService}`);
487
408
  } else if (this.BLE) {
488
409
  await this.BLERefreshStatus();
489
410
  } else if (this.OpenAPI && this.platform.config.credentials?.token) {
490
411
  await this.openAPIRefreshStatus();
491
412
  } else {
492
413
  await this.offlineOff();
493
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
494
- + ` ${this.device.connectionType}, refreshStatus will not happen.`);
414
+ await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, refreshStatus will not happen.`);
495
415
  }
496
416
  }
497
417
 
498
418
  async BLERefreshStatus(): Promise<void> {
499
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
419
+ await this.debugLog('BLERefreshStatus');
500
420
  const switchbot = await this.switchbotBLE();
501
421
 
502
422
  if (switchbot === undefined) {
@@ -505,13 +425,14 @@ export class Curtain extends deviceBase {
505
425
  // Start to monitor advertisement packets
506
426
  (async () => {
507
427
  // Start to monitor advertisement packets
508
- const serviceData: serviceData = await this.monitorAdvertisementPackets(switchbot);
428
+ const serviceData = await this.monitorAdvertisementPackets(switchbot) as curtainServiceData | curtain3ServiceData;
509
429
  // Update HomeKit
510
- if (serviceData.model !== '' && serviceData.modelName !== '') {
430
+ if ((serviceData.model === SwitchBotBLEModel.Curtain || SwitchBotBLEModel.Curtain3)
431
+ && (serviceData.modelName === SwitchBotBLEModelName.Curtain || SwitchBotBLEModelName.Curtain3)) {
511
432
  await this.BLEparseStatus(serviceData);
512
433
  await this.updateHomeKitCharacteristics();
513
434
  } else {
514
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
435
+ await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
515
436
  await this.BLERefreshConnection(switchbot);
516
437
  }
517
438
  })();
@@ -519,56 +440,55 @@ export class Curtain extends deviceBase {
519
440
  }
520
441
 
521
442
  async openAPIRefreshStatus(): Promise<void> {
522
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
443
+ await this.debugLog('openAPIRefreshStatus');
523
444
  try {
524
445
  const { body, statusCode } = await this.deviceRefreshStatus();
525
446
  const deviceStatus: any = await body.json();
526
- await this.refreshStatusCodes(statusCode, deviceStatus);
527
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
528
- await this.successfulRefreshStatus(statusCode, deviceStatus);
529
- await this.openAPIparseStatus(deviceStatus);
447
+ await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);;
448
+ if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
449
+ await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
450
+ await this.openAPIparseStatus(deviceStatus.body);
530
451
  await this.updateHomeKitCharacteristics();
531
452
  } else {
532
- await this.statusCodes(statusCode, deviceStatus);
453
+ await this.debugWarnLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
454
+ await this.debugWarnLog(statusCode, deviceStatus);
533
455
  }
534
456
  } catch (e: any) {
535
457
  await this.apiError(e);
536
- await this.openAPIRefreshError(e);
458
+ await this.errorLog(`failed openAPIRefreshStatus with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
537
459
  }
538
460
  }
539
461
 
540
- async registerWebhook(accessory: PlatformAccessory, device: device & devicesConfig) {
541
- if (device.webhook) {
542
- this.debugLog(`${device.deviceType}: ${accessory.displayName} is listening webhook.`);
543
- this.platform.webhookEventHandler[device.deviceId] = async (context) => {
462
+ async registerWebhook() {
463
+ if (this.device.webhook) {
464
+ await this.debugLog('is listening webhook.');
465
+ this.platform.webhookEventHandler[this.device.deviceId] = async (context: curtainWebhookContext | curtain3WebhookContext) => {
544
466
  try {
545
- this.debugLog(`${device.deviceType}: ${accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
546
- const { slidePosition, battery } = context;
547
- this.debugLog(`${device.deviceType}: ${accessory.displayName} ` +
548
- '(slidePosition, battery) = ' +
549
- `Webhook:(${slidePosition}, ${battery}), `
550
- + `current:(${this.WindowCovering.CurrentPosition}, ${this.Battery.BatteryLevel})`);
551
- this.WindowCovering.CurrentPosition = slidePosition;
552
- this.Battery.BatteryLevel = battery;
553
- this.updateHomeKitCharacteristics();
467
+ await this.debugLog(`received Webhook: ${JSON.stringify(context)}`);
468
+ await this.parseStatusWebhook(context);
469
+ await this.updateHomeKitCharacteristics();
554
470
  } catch (e: any) {
555
- this.errorLog(`${device.deviceType}: ${accessory.displayName} `
556
- + `failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
471
+ await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
557
472
  }
558
473
  };
474
+ } else {
475
+ await this.debugLog('is not listening webhook.');
559
476
  }
560
477
  }
561
478
 
479
+ /**
480
+ * Pushes the requested changes to the SwitchBot API
481
+ */
562
482
  async pushChanges(): Promise<void> {
563
483
  if (!this.device.enableCloudService && this.OpenAPI) {
564
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} pushChanges enableCloudService: ${this.device.enableCloudService}`);
484
+ await this.errorLog(`pushChanges enableCloudService: ${this.device.enableCloudService}`);
565
485
  } else if (this.BLE) {
566
486
  await this.BLEpushChanges();
567
487
  } else if (this.OpenAPI && this.platform.config.credentials?.token) {
568
488
  await this.openAPIpushChanges();
569
489
  } else {
570
490
  await this.offlineOff();
571
- await this.pushChangeDisabled();
491
+ await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, pushChanges will not happen.`);
572
492
  }
573
493
  // Refresh the status from the API
574
494
  interval(15000)
@@ -580,93 +500,84 @@ export class Curtain extends deviceBase {
580
500
  }
581
501
 
582
502
  async BLEpushChanges(): Promise<void> {
583
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
503
+ await this.debugLog('BLEpushChanges');
584
504
  if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition) {
585
- const switchbot = await this.platform.connectBLE();
586
- // Convert to BLE Address
505
+ const switchbot = await this.platform.connectBLE(this.accessory, this.device);
587
506
  await this.convertBLEAddress();
588
507
  const { setPositionMode, Mode }: { setPositionMode: number; Mode: string; } = await this.setPerformance();
589
508
  const adjustedMode = setPositionMode === 1 ? 0x01 : 0xff;
590
- this.debugLog(`${this.accessory.displayName} Mode: ${Mode}`);
509
+ await this.debugLog(`Mode: ${Mode}, setPositionMode: ${setPositionMode}`);
591
510
  if (switchbot !== false) {
592
- try {
593
- const device_list = await switchbot.discover({ model: this.device.bleModel, quick: true, id: this.device.bleMac });
594
- this.infoLog(`${this.accessory.displayName} Target Position: ${this.WindowCovering.TargetPosition}`);
595
-
596
- await this.retryBLE({
597
- max: await this.maxRetryBLE(),
598
- fn: async () => {
599
- await device_list[0].runToPos(100 - Number(this.WindowCovering.TargetPosition), adjustedMode);
600
- },
511
+ switchbot
512
+ .discover({ model: this.device.bleModel, quick: true, id: this.device.bleMac })
513
+ .then(async (device_list: any) => {
514
+ return await this.retryBLE({
515
+ max: await this.maxRetryBLE(),
516
+ fn: async () => {
517
+ return await device_list[0].runToPos(100 - Number(this.WindowCovering.TargetPosition), adjustedMode);
518
+ },
519
+ });
520
+ })
521
+ .then(async () => {
522
+ await this.successLog(`TargetPostion: ${this.WindowCovering.TargetPosition} sent over SwitchBot BLE, sent successfully`);
523
+ await this.updateHomeKitCharacteristics();
524
+ })
525
+ .catch(async (e: any) => {
526
+ await this.apiError(e);
527
+ await this.errorLog(`failed BLEpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
528
+ await this.BLEPushConnection();
601
529
  });
602
-
603
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
604
- this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
605
- + `TargetPosition: ${this.WindowCovering.TargetPosition} sent over BLE, sent successfully`);
606
- } catch (e) {
607
- this.apiError(e);
608
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
609
- + ` Connection, Error Message: ${JSON.stringify((e as Error).message)}`);
610
- await this.BLEPushConnection();
611
- throw new Error('Connection error');
612
- }
613
530
  } else {
614
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
531
+ await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
615
532
  await this.BLEPushConnection();
616
533
  }
617
534
  } else {
618
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges, CurrentPosition & TargetPosition Are the Same.`
619
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition ${this.WindowCovering.TargetPosition}`);
535
+ await this.debugLog(`No changes (BLEpushChanges), TargetPosition: ${this.WindowCovering.TargetPosition},`
536
+ + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
620
537
  }
621
538
  }
622
539
 
623
540
  async openAPIpushChanges(): Promise<void> {
624
- let command: string;
625
- let parameter: string;
626
- let commandType: string;
627
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
541
+ await this.debugLog('openAPIpushChanges');
628
542
  if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition || this.device.disableCaching) {
629
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Pushing ${this.WindowCovering.TargetPosition}`);
543
+ await this.debugLog(`Pushing ${this.WindowCovering.TargetPosition}`);
630
544
  const adjustedTargetPosition = 100 - Number(this.WindowCovering.TargetPosition);
631
545
  const { setPositionMode, Mode }: { setPositionMode: number; Mode: string; } = await this.setPerformance();
632
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Mode: ${Mode}`);
546
+ await this.debugLog(`Mode: ${Mode}, setPositionMode: ${setPositionMode}`);
633
547
  const adjustedMode = setPositionMode || 'ff';
548
+ let bodyChange: string;
634
549
  if (this.WindowCovering.HoldPosition) {
635
- command = 'pause';
636
- parameter = 'default';
637
- commandType = 'command';
550
+ bodyChange = JSON.stringify({
551
+ command: 'pause',
552
+ parameter: 'default',
553
+ commandType: 'command',
554
+ });
638
555
  } else {
639
- command = 'setPosition';
640
- parameter = `0,${adjustedMode},${adjustedTargetPosition}`;
641
- commandType = 'command';
556
+ bodyChange = JSON.stringify({
557
+ command: 'setPosition',
558
+ parameter: `0,${adjustedMode},${adjustedTargetPosition}`,
559
+ commandType: 'command',
560
+ });
642
561
  }
643
- const bodyChange = JSON.stringify({
644
- command: command,
645
- parameter: parameter,
646
- commandType: commandType,
647
- });
648
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
562
+ await this.debugLog(`SwitchBot OpenAPI bodyChange: ${JSON.stringify(bodyChange)}`);
649
563
  try {
650
564
  const { body, statusCode } = await this.pushChangeRequest(bodyChange);
651
565
  const deviceStatus: any = await body.json();
652
- await this.pushStatusCodes(statusCode, deviceStatus);
653
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
654
- this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
655
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
656
- this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
657
- + `request to SwitchBot API, body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
566
+ await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
567
+ if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
568
+ await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
569
+ await this.updateHomeKitCharacteristics();
658
570
  } else {
659
- this.statusCode(statusCode);
660
- this.statusCode(deviceStatus.statusCode);
571
+ await this.statusCode(statusCode);
572
+ await this.statusCode(deviceStatus.statusCode);
661
573
  }
662
574
  } catch (e: any) {
663
- this.apiError(e);
664
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
665
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
575
+ await this.apiError(e);
576
+ await this.errorLog(`failed openAPIpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
666
577
  }
667
578
  } else {
668
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No OpenAPI Changes, CurrentPosition & TargetPosition Are the Same.`
669
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition ${this.WindowCovering.TargetPosition}`);
579
+ await this.debugLog(`No changes (openAPIpushChanges), CurrentPosition: ${this.WindowCovering.CurrentPosition},`
580
+ + ` TargetPosition: ${this.WindowCovering.TargetPosition}`);
670
581
  }
671
582
  }
672
583
 
@@ -674,10 +585,10 @@ export class Curtain extends deviceBase {
674
585
  * Handle requests to set the value of the "Target Position" characteristic
675
586
  */
676
587
  async TargetPositionSet(value: CharacteristicValue): Promise<void> {
677
- if (this.WindowCovering.TargetPosition === this.accessory.context.TargetPosition) {
678
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set TargetPosition: ${value}`);
588
+ if (this.WindowCovering.TargetPosition !== this.accessory.context.TargetPosition) {
589
+ await this.infoLog(`Set TargetPosition: ${value}`);
679
590
  } else {
680
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetPosition: ${value}`);
591
+ await this.debugLog(`No Changes, TargetPosition: ${value}`);
681
592
  }
682
593
 
683
594
  // Set HoldPosition to false when TargetPosition is changed
@@ -695,18 +606,15 @@ export class Curtain extends deviceBase {
695
606
  if (this.WindowCovering.TargetPosition > this.WindowCovering.CurrentPosition) {
696
607
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
697
608
  this.setNewTarget = true;
698
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.WindowCovering.TargetPosition},`
699
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
609
+ await this.debugLog(`value: ${this.WindowCovering.TargetPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
700
610
  } else if (this.WindowCovering.TargetPosition < this.WindowCovering.CurrentPosition) {
701
611
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
702
612
  this.setNewTarget = true;
703
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.WindowCovering.TargetPosition},`
704
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
613
+ await this.debugLog(`value: ${this.WindowCovering.TargetPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
705
614
  } else {
706
615
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
707
616
  this.setNewTarget = false;
708
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.WindowCovering.TargetPosition},`
709
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
617
+ await this.debugLog(`value: ${this.WindowCovering.TargetPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
710
618
  }
711
619
  this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.WindowCovering.PositionState);
712
620
  this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
@@ -716,10 +624,10 @@ export class Curtain extends deviceBase {
716
624
  * The minimum time depends on the network control latency.
717
625
  */
718
626
  clearTimeout(this.setNewTargetTimer);
719
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateRate: ${this.deviceUpdateRate}`);
627
+ await this.debugLog(`deviceUpdateRate: ${this.deviceUpdateRate}`);
720
628
  if (this.setNewTarget) {
721
- this.setNewTargetTimer = setTimeout(() => {
722
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} setNewTarget ${this.setNewTarget} timeout`);
629
+ this.setNewTargetTimer = setTimeout(async () => {
630
+ await this.debugLog(`setNewTarget ${this.setNewTarget} timeout`);
723
631
  this.setNewTarget = false;
724
632
  }, this.deviceUpdateRate * 1000);
725
633
  }
@@ -730,7 +638,7 @@ export class Curtain extends deviceBase {
730
638
  * Handle requests to set the value of the "Target Position" characteristic
731
639
  */
732
640
  async HoldPositionSet(value: CharacteristicValue): Promise<void> {
733
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} HoldPosition: ${value}`);
641
+ this.debugLog(`HoldPosition: ${value}`);
734
642
  this.WindowCovering.HoldPosition = value;
735
643
  this.doCurtainUpdate.next();
736
644
  }
@@ -768,18 +676,15 @@ export class Curtain extends deviceBase {
768
676
 
769
677
  async BLEPushConnection() {
770
678
  if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
771
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Push Changes`);
679
+ await this.warnLog('Using OpenAPI Connection to Push Changes');
772
680
  await this.openAPIpushChanges();
773
681
  }
774
682
  }
775
683
 
776
684
  async BLERefreshConnection(switchbot: any): Promise<void> {
777
- if (switchbot !== undefined) {
778
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot:`
779
- + ` ${JSON.stringify(switchbot)}`);
780
- }
685
+ await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${JSON.stringify(switchbot)}`);
781
686
  if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
782
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Refresh Status`);
687
+ await this.warnLog('Using OpenAPI Connection to Refresh Status');
783
688
  await this.openAPIRefreshStatus();
784
689
  }
785
690
  }
@@ -813,6 +718,38 @@ export class Curtain extends deviceBase {
813
718
  return { setPositionMode, Mode };
814
719
  }
815
720
 
721
+ async getCurrentPostion() {
722
+ await this.setMinMax();
723
+ await this.debugLog(`CurrentPosition ${this.WindowCovering.CurrentPosition}`);
724
+ if (this.setNewTarget) {
725
+ this.infoLog('Checking Status ...');
726
+ await this.setMinMax();
727
+ if (this.WindowCovering.TargetPosition > this.WindowCovering.CurrentPosition) {
728
+ await this.debugLog(`Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
729
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
730
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
731
+ await this.debugLog(`Increasing, PositionState: ${this.WindowCovering.PositionState}`);
732
+ } else if (this.WindowCovering.TargetPosition < this.WindowCovering.CurrentPosition) {
733
+ await this.debugLog(`Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
734
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
735
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
736
+ await this.debugLog(`Decreasing, PositionState: ${this.WindowCovering.PositionState}`);
737
+ } else {
738
+ await this.debugLog(`Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
739
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
740
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
741
+ await this.debugLog(`Stopped, PositionState: ${this.WindowCovering.PositionState}`);
742
+ }
743
+ } else {
744
+ await this.debugLog(`Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
745
+ this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition;
746
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
747
+ await this.debugLog(`Stopped, PositionState: ${this.WindowCovering.PositionState}`);
748
+ }
749
+ await this.debugLog(`CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition: ${this.WindowCovering.TargetPosition},`
750
+ + ` PositionState: ${this.WindowCovering.PositionState},`);
751
+ }
752
+
816
753
  async setMinMax(): Promise<void> {
817
754
  if (this.device.curtain?.set_min) {
818
755
  if (Number(this.WindowCovering.CurrentPosition) <= this.device.curtain?.set_min) {
@@ -846,9 +783,9 @@ export class Curtain extends deviceBase {
846
783
  this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
847
784
  this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
848
785
  this.Battery.Service.updateCharacteristic(this.hap.Characteristic.ChargingState, e);
849
- if (!this.device.curtain?.hide_lightsensor) {
850
- this.LightSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e);
851
- this.LightSensor!.Service.updateCharacteristic(this.hap.Characteristic.StatusActive, e);
786
+ if (!this.device.curtain?.hide_lightsensor && this.LightSensor?.Service) {
787
+ this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e);
788
+ this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.StatusActive, e);
852
789
  }
853
790
  }
854
791
  }