@switchbot/homebridge-switchbot 3.5.1-beta.0 → 3.5.1-beta.10

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 (197) hide show
  1. package/README.md +16 -0
  2. package/dist/device/blindtilt.d.ts +15 -6
  3. package/dist/device/blindtilt.d.ts.map +1 -1
  4. package/dist/device/blindtilt.js +224 -370
  5. package/dist/device/blindtilt.js.map +1 -1
  6. package/dist/device/bot.d.ts +9 -4
  7. package/dist/device/bot.d.ts.map +1 -1
  8. package/dist/device/bot.js +197 -221
  9. package/dist/device/bot.js.map +1 -1
  10. package/dist/device/ceilinglight.d.ts +10 -5
  11. package/dist/device/ceilinglight.d.ts.map +1 -1
  12. package/dist/device/ceilinglight.js +214 -292
  13. package/dist/device/ceilinglight.js.map +1 -1
  14. package/dist/device/colorbulb.d.ts +10 -5
  15. package/dist/device/colorbulb.d.ts.map +1 -1
  16. package/dist/device/colorbulb.js +335 -421
  17. package/dist/device/colorbulb.js.map +1 -1
  18. package/dist/device/contact.d.ts +9 -4
  19. package/dist/device/contact.d.ts.map +1 -1
  20. package/dist/device/contact.js +121 -200
  21. package/dist/device/contact.js.map +1 -1
  22. package/dist/device/curtain.d.ts +20 -7
  23. package/dist/device/curtain.d.ts.map +1 -1
  24. package/dist/device/curtain.js +229 -403
  25. package/dist/device/curtain.js.map +1 -1
  26. package/dist/device/device.d.ts +41 -22
  27. package/dist/device/device.d.ts.map +1 -1
  28. package/dist/device/device.js +212 -181
  29. package/dist/device/device.js.map +1 -1
  30. package/dist/device/fan.d.ts +9 -4
  31. package/dist/device/fan.d.ts.map +1 -1
  32. package/dist/device/fan.js +204 -249
  33. package/dist/device/fan.js.map +1 -1
  34. package/dist/device/hub.d.ts +9 -5
  35. package/dist/device/hub.d.ts.map +1 -1
  36. package/dist/device/hub.js +107 -233
  37. package/dist/device/hub.js.map +1 -1
  38. package/dist/device/humidifier.d.ts +12 -4
  39. package/dist/device/humidifier.d.ts.map +1 -1
  40. package/dist/device/humidifier.js +193 -235
  41. package/dist/device/humidifier.js.map +1 -1
  42. package/dist/device/iosensor.d.ts +9 -4
  43. package/dist/device/iosensor.d.ts.map +1 -1
  44. package/dist/device/iosensor.js +92 -159
  45. package/dist/device/iosensor.js.map +1 -1
  46. package/dist/device/lightstrip.d.ts +10 -5
  47. package/dist/device/lightstrip.d.ts.map +1 -1
  48. package/dist/device/lightstrip.js +288 -370
  49. package/dist/device/lightstrip.js.map +1 -1
  50. package/dist/device/lock.d.ts +10 -5
  51. package/dist/device/lock.d.ts.map +1 -1
  52. package/dist/device/lock.js +172 -219
  53. package/dist/device/lock.js.map +1 -1
  54. package/dist/device/meter.d.ts +9 -4
  55. package/dist/device/meter.d.ts.map +1 -1
  56. package/dist/device/meter.js +94 -160
  57. package/dist/device/meter.js.map +1 -1
  58. package/dist/device/meterplus.d.ts +9 -4
  59. package/dist/device/meterplus.d.ts.map +1 -1
  60. package/dist/device/meterplus.js +95 -157
  61. package/dist/device/meterplus.js.map +1 -1
  62. package/dist/device/motion.d.ts +9 -4
  63. package/dist/device/motion.d.ts.map +1 -1
  64. package/dist/device/motion.js +85 -144
  65. package/dist/device/motion.js.map +1 -1
  66. package/dist/device/plug.d.ts +9 -4
  67. package/dist/device/plug.d.ts.map +1 -1
  68. package/dist/device/plug.js +100 -127
  69. package/dist/device/plug.js.map +1 -1
  70. package/dist/device/robotvacuumcleaner.d.ts +9 -6
  71. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  72. package/dist/device/robotvacuumcleaner.js +172 -259
  73. package/dist/device/robotvacuumcleaner.js.map +1 -1
  74. package/dist/device/waterdetector.d.ts +12 -4
  75. package/dist/device/waterdetector.d.ts.map +1 -1
  76. package/dist/device/waterdetector.js +106 -131
  77. package/dist/device/waterdetector.js.map +1 -1
  78. package/dist/irdevice/airconditioner.d.ts +2 -1
  79. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  80. package/dist/irdevice/airconditioner.js +2 -3
  81. package/dist/irdevice/airconditioner.js.map +1 -1
  82. package/dist/irdevice/airpurifier.d.ts +2 -1
  83. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  84. package/dist/irdevice/airpurifier.js +2 -3
  85. package/dist/irdevice/airpurifier.js.map +1 -1
  86. package/dist/irdevice/camera.d.ts +2 -1
  87. package/dist/irdevice/camera.d.ts.map +1 -1
  88. package/dist/irdevice/camera.js +2 -3
  89. package/dist/irdevice/camera.js.map +1 -1
  90. package/dist/irdevice/fan.d.ts +2 -1
  91. package/dist/irdevice/fan.d.ts.map +1 -1
  92. package/dist/irdevice/fan.js +2 -3
  93. package/dist/irdevice/fan.js.map +1 -1
  94. package/dist/irdevice/irdevice.d.ts +3 -1
  95. package/dist/irdevice/irdevice.d.ts.map +1 -1
  96. package/dist/irdevice/irdevice.js +5 -1
  97. package/dist/irdevice/irdevice.js.map +1 -1
  98. package/dist/irdevice/light.d.ts +2 -1
  99. package/dist/irdevice/light.d.ts.map +1 -1
  100. package/dist/irdevice/light.js +2 -3
  101. package/dist/irdevice/light.js.map +1 -1
  102. package/dist/irdevice/other.d.ts +2 -1
  103. package/dist/irdevice/other.d.ts.map +1 -1
  104. package/dist/irdevice/other.js +2 -3
  105. package/dist/irdevice/other.js.map +1 -1
  106. package/dist/irdevice/tv.d.ts +2 -1
  107. package/dist/irdevice/tv.d.ts.map +1 -1
  108. package/dist/irdevice/tv.js +2 -3
  109. package/dist/irdevice/tv.js.map +1 -1
  110. package/dist/irdevice/vacuumcleaner.d.ts +2 -1
  111. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  112. package/dist/irdevice/vacuumcleaner.js +2 -3
  113. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  114. package/dist/irdevice/waterheater.d.ts +2 -1
  115. package/dist/irdevice/waterheater.d.ts.map +1 -1
  116. package/dist/irdevice/waterheater.js +2 -3
  117. package/dist/irdevice/waterheater.js.map +1 -1
  118. package/dist/platform.d.ts +14 -14
  119. package/dist/platform.d.ts.map +1 -1
  120. package/dist/platform.js +102 -86
  121. package/dist/platform.js.map +1 -1
  122. package/dist/settings.d.ts +49 -190
  123. package/dist/settings.d.ts.map +1 -1
  124. package/dist/settings.js +19 -0
  125. package/dist/settings.js.map +1 -1
  126. package/dist/types/bledevicestatus.d.ts +279 -0
  127. package/dist/types/bledevicestatus.d.ts.map +1 -0
  128. package/dist/types/bledevicestatus.js +2 -0
  129. package/dist/types/bledevicestatus.js.map +1 -0
  130. package/dist/types/devicelist.d.ts +89 -0
  131. package/dist/types/devicelist.d.ts.map +1 -0
  132. package/dist/types/devicelist.js +6 -0
  133. package/dist/types/devicelist.js.map +1 -0
  134. package/dist/types/deviceresponse.d.ts +13 -0
  135. package/dist/types/deviceresponse.d.ts.map +1 -0
  136. package/dist/types/deviceresponse.js +2 -0
  137. package/dist/types/deviceresponse.js.map +1 -0
  138. package/dist/types/devicestatus.d.ts +149 -0
  139. package/dist/types/devicestatus.d.ts.map +1 -0
  140. package/dist/types/devicestatus.js +3 -0
  141. package/dist/types/devicestatus.js.map +1 -0
  142. package/dist/types/devicewebhookstatus.d.ts +156 -0
  143. package/dist/types/devicewebhookstatus.d.ts.map +1 -0
  144. package/dist/types/devicewebhookstatus.js +2 -0
  145. package/dist/types/devicewebhookstatus.js.map +1 -0
  146. package/dist/types/irdevicelist.d.ts +10 -0
  147. package/dist/types/irdevicelist.d.ts.map +1 -0
  148. package/dist/types/irdevicelist.js +2 -0
  149. package/dist/types/irdevicelist.js.map +1 -0
  150. package/dist/types/pushbody.d.ts +6 -0
  151. package/dist/types/pushbody.d.ts.map +1 -0
  152. package/dist/types/pushbody.js +2 -0
  153. package/dist/types/pushbody.js.map +1 -0
  154. package/dist/utils.d.ts +25 -0
  155. package/dist/utils.d.ts.map +1 -1
  156. package/dist/utils.js +28 -0
  157. package/dist/utils.js.map +1 -1
  158. package/package.json +11 -11
  159. package/src/device/blindtilt.ts +254 -376
  160. package/src/device/bot.ts +209 -224
  161. package/src/device/ceilinglight.ts +227 -297
  162. package/src/device/colorbulb.ts +345 -435
  163. package/src/device/contact.ts +139 -200
  164. package/src/device/curtain.ts +254 -414
  165. package/src/device/device.ts +221 -190
  166. package/src/device/fan.ts +222 -253
  167. package/src/device/hub.ts +127 -248
  168. package/src/device/humidifier.ts +217 -246
  169. package/src/device/iosensor.ts +115 -168
  170. package/src/device/lightstrip.ts +303 -380
  171. package/src/device/lock.ts +188 -224
  172. package/src/device/meter.ts +117 -179
  173. package/src/device/meterplus.ts +118 -176
  174. package/src/device/motion.ts +100 -146
  175. package/src/device/plug.ts +111 -131
  176. package/src/device/robotvacuumcleaner.ts +191 -258
  177. package/src/device/waterdetector.ts +124 -141
  178. package/src/irdevice/airconditioner.ts +4 -4
  179. package/src/irdevice/airpurifier.ts +4 -4
  180. package/src/irdevice/camera.ts +4 -4
  181. package/src/irdevice/fan.ts +4 -4
  182. package/src/irdevice/irdevice.ts +8 -2
  183. package/src/irdevice/light.ts +4 -4
  184. package/src/irdevice/other.ts +4 -4
  185. package/src/irdevice/tv.ts +4 -4
  186. package/src/irdevice/vacuumcleaner.ts +4 -4
  187. package/src/irdevice/waterheater.ts +4 -4
  188. package/src/platform.ts +104 -87
  189. package/src/settings.ts +30 -238
  190. package/src/types/bledevicestatus.ts +305 -0
  191. package/src/types/devicelist.ts +124 -0
  192. package/src/types/deviceresponse.ts +15 -0
  193. package/src/types/devicestatus.ts +178 -0
  194. package/src/types/devicewebhookstatus.ts +196 -0
  195. package/src/types/irdevicelist.ts +15 -0
  196. package/src/types/pushbody.ts +9 -0
  197. 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,219 +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
- serviceData.lightLevel = 1;
340
- // Brightness
341
- switch (serviceData.lightLevel) {
342
- case 1:
343
- this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * (serviceData.lightLevel === 1
344
- ? set_minLux : 2);
345
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} 1 LightLevel: ${serviceData.lightLevel},`
346
- + ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
347
- this.LightSensor!.CurrentAmbientLightLevel = set_minLux;
348
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} 2 LightLevel: ${serviceData.lightLevel},`
349
- + ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
350
- break;
351
- case 2:
352
- this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * (Number(serviceData.lightLevel) - 1);
353
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} 1 LightLevel: ${serviceData.lightLevel},`
354
- + ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
355
- this.LightSensor!.CurrentAmbientLightLevel = (set_maxLux - set_minLux) / spaceBetweenLevels;
356
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} 2 LightLevel: ${serviceData.lightLevel},`
357
- + ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
358
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} 3 LightLevel: ${serviceData.lightLevel},`
359
- + ` Calculation: ${(set_maxLux - set_minLux) / spaceBetweenLevels}`);
360
- break;
361
- case 3:
362
- this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * (Number(serviceData.lightLevel) - 1);
363
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} 1 LightLevel: ${serviceData.lightLevel},`
364
- + ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
365
- this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 2;
366
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} 2 LightLevel: ${serviceData.lightLevel},`
367
- + ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
368
- this.Battery.ChargingState = this.hap.Characteristic.ChargingState.CHARGING;
369
- break;
370
- case 4:
371
- this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 3;
372
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
373
- this.Battery.ChargingState = this.hap.Characteristic.ChargingState.CHARGING;
374
- break;
375
- case 5:
376
- this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 4;
377
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
378
- this.Battery.ChargingState = this.hap.Characteristic.ChargingState.CHARGING;
379
- break;
380
- case 6:
381
- this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 5;
382
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
383
- this.Battery.ChargingState = this.hap.Characteristic.ChargingState.CHARGING;
384
- break;
385
- case 7:
386
- this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 6;
387
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
388
- this.Battery.ChargingState = this.hap.Characteristic.ChargingState.CHARGING;
389
- break;
390
- case 8:
391
- this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 7;
392
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
393
- this.Battery.ChargingState = this.hap.Characteristic.ChargingState.CHARGING;
394
- break;
395
- case 9:
396
- this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 8;
397
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
398
- this.Battery.ChargingState = this.hap.Characteristic.ChargingState.CHARGING;
399
- break;
400
- case 10:
401
- default:
402
- this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * (Number(serviceData.lightLevel) - 1);
403
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} 1 LightLevel: ${serviceData.lightLevel},`
404
- + ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
405
- this.LightSensor!.CurrentAmbientLightLevel = set_maxLux;
406
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} 2 LightLevel: ${serviceData.lightLevel},`
407
- + ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
408
- this.debugLog();
409
- }
410
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel},`
411
- + ` 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}`);
412
309
  }
413
- // Battery
310
+ // BatteryLevel
414
311
  this.Battery.BatteryLevel = Number(serviceData.battery);
415
- if (this.Battery.BatteryLevel < 10) {
416
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
417
- } else {
418
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
419
- }
420
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
421
- + ` 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}`);
422
317
  }
423
318
 
424
- async openAPIparseStatus(deviceStatus: deviceStatus): Promise<void> {
425
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
319
+ async openAPIparseStatus(deviceStatus: curtainStatus): Promise<void> {
320
+ await this.debugLog('openAPIparseStatus');
426
321
  // CurrentPosition
427
- this.WindowCovering!.CurrentPosition = 100 - Number(deviceStatus.body.slidePosition);
322
+ this.WindowCovering.CurrentPosition = 100 - deviceStatus.slidePosition;
428
323
  await this.setMinMax();
429
- this.debugLog(`Curtain ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
324
+ await this.debugLog(`Curtain ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
430
325
  if (this.setNewTarget) {
431
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Checking Status ...`);
326
+ await this.infoLog('Checking Status ...');
432
327
  }
433
-
434
- if (this.setNewTarget && deviceStatus.body.moving) {
328
+ if (this.setNewTarget && deviceStatus.moving) {
435
329
  await this.setMinMax();
436
330
  if (Number(this.WindowCovering.TargetPosition) > this.WindowCovering.CurrentPosition) {
437
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition} `);
331
+ await this.debugLog(`Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
438
332
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
439
333
  this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
440
- this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} INCREASING`
441
- + ` PositionState: ${this.WindowCovering.PositionState}`);
334
+ await this.debugLog(`Increasing, PositionState: ${this.WindowCovering.PositionState}`);
442
335
  } else if (Number(this.WindowCovering.TargetPosition) < this.WindowCovering.CurrentPosition) {
443
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition} `);
336
+ await this.debugLog(`Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
444
337
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
445
338
  this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
446
- this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} DECREASING`
447
- + ` PositionState: ${this.WindowCovering.PositionState}`);
339
+ await this.debugLog(`Decreasing, PositionState: ${this.WindowCovering.PositionState}`);
448
340
  } else {
449
- this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} Standby,`
450
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
341
+ await this.debugLog(`Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
451
342
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
452
343
  this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
453
- this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} STOPPED`
454
- + ` PositionState: ${this.WindowCovering.PositionState}`);
344
+ await this.debugLog(`Stopped, PositionState: ${this.WindowCovering.PositionState}`);
455
345
  }
456
346
  } else {
457
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
347
+ await this.debugLog(`Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
458
348
  this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition;
459
349
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
460
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Stopped`);
350
+ await this.debugLog(`Stopped, PositionState: ${this.WindowCovering.PositionState}`);
461
351
  }
462
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition},`
463
- + ` TargetPosition: ${this.WindowCovering.TargetPosition}, PositionState: ${this.WindowCovering.PositionState},`);
464
-
352
+ await this.debugLog(`CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition: ${this.WindowCovering.TargetPosition},`
353
+ + ` PositionState: ${this.WindowCovering.PositionState},`);
465
354
  // Brightness
466
- if (!this.device.curtain?.hide_lightsensor) {
355
+ if (!this.device.curtain?.hide_lightsensor && this.LightSensor?.Service) {
467
356
  const set_minLux = this.device.curtain?.set_minLux ?? 1;
468
357
  const set_maxLux = this.device.curtain?.set_maxLux ?? 6001;
469
- switch (deviceStatus.body.brightness) {
470
- case 'bright':
471
- this.LightSensor!.CurrentAmbientLightLevel = set_maxLux;
472
- this.Battery.ChargingState = this.hap.Characteristic.ChargingState.CHARGING;
473
- break;
474
- case 'dim':
475
- default:
476
- this.LightSensor!.CurrentAmbientLightLevel = set_minLux;
477
- }
478
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
479
- + ` 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}`);
480
362
  }
481
-
482
363
  // BatteryLevel
483
- this.Battery.BatteryLevel = Number(deviceStatus.body.battery);
484
- if (this.Battery.BatteryLevel < 10) {
485
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
486
- } else {
487
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
488
- }
489
- if (Number.isNaN(this.Battery.BatteryLevel)) {
490
- this.Battery.BatteryLevel = 100;
491
- }
492
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
493
- + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
494
-
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}`);
495
370
  // Firmware Version
496
- const version = deviceStatus.body.version?.toString();
497
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Firmware Version: ${version?.replace(/^V|-.*$/g, '')}`);
498
- if (deviceStatus.body.version) {
499
- 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';
500
375
  this.accessory
501
376
  .getService(this.hap.Service.AccessoryInformation)!
502
377
  .setCharacteristic(this.hap.Characteristic.HardwareRevision, deviceVersion)
@@ -504,26 +379,44 @@ export class Curtain extends deviceBase {
504
379
  .getCharacteristic(this.hap.Characteristic.FirmwareRevision)
505
380
  .updateValue(deviceVersion);
506
381
  this.accessory.context.deviceVersion = deviceVersion;
507
- this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceVersion: ${this.accessory.context.deviceVersion}`);
382
+ await this.debugSuccessLog(`deviceVersion: ${this.accessory.context.deviceVersion}`);
508
383
  }
509
384
  }
510
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
+ */
511
405
  async refreshStatus(): Promise<void> {
512
406
  if (!this.device.enableCloudService && this.OpenAPI) {
513
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} refreshStatus enableCloudService: ${this.device.enableCloudService}`);
407
+ await this.errorLog(`refreshStatus enableCloudService: ${this.device.enableCloudService}`);
514
408
  } else if (this.BLE) {
515
409
  await this.BLERefreshStatus();
516
410
  } else if (this.OpenAPI && this.platform.config.credentials?.token) {
517
411
  await this.openAPIRefreshStatus();
518
412
  } else {
519
413
  await this.offlineOff();
520
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
521
- + ` ${this.device.connectionType}, refreshStatus will not happen.`);
414
+ await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, refreshStatus will not happen.`);
522
415
  }
523
416
  }
524
417
 
525
418
  async BLERefreshStatus(): Promise<void> {
526
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
419
+ await this.debugLog('BLERefreshStatus');
527
420
  const switchbot = await this.switchbotBLE();
528
421
 
529
422
  if (switchbot === undefined) {
@@ -532,13 +425,14 @@ export class Curtain extends deviceBase {
532
425
  // Start to monitor advertisement packets
533
426
  (async () => {
534
427
  // Start to monitor advertisement packets
535
- const serviceData: serviceData = await this.monitorAdvertisementPackets(switchbot);
428
+ const serviceData = await this.monitorAdvertisementPackets(switchbot) as curtainServiceData | curtain3ServiceData;
536
429
  // Update HomeKit
537
- if (serviceData.model !== '' && serviceData.modelName !== '') {
430
+ if ((serviceData.model === SwitchBotBLEModel.Curtain || SwitchBotBLEModel.Curtain3)
431
+ && (serviceData.modelName === SwitchBotBLEModelName.Curtain || SwitchBotBLEModelName.Curtain3)) {
538
432
  await this.BLEparseStatus(serviceData);
539
433
  await this.updateHomeKitCharacteristics();
540
434
  } else {
541
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
435
+ await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
542
436
  await this.BLERefreshConnection(switchbot);
543
437
  }
544
438
  })();
@@ -546,58 +440,55 @@ export class Curtain extends deviceBase {
546
440
  }
547
441
 
548
442
  async openAPIRefreshStatus(): Promise<void> {
549
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
443
+ await this.debugLog('openAPIRefreshStatus');
550
444
  try {
551
445
  const { body, statusCode } = await this.deviceRefreshStatus();
552
446
  const deviceStatus: any = await body.json();
553
- await this.refreshStatusCodes(statusCode, deviceStatus);
554
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
555
- await this.successfulRefreshStatus(statusCode, deviceStatus);
556
- 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);
557
451
  await this.updateHomeKitCharacteristics();
558
452
  } else {
559
- await this.statusCodes(statusCode, deviceStatus);
453
+ await this.debugWarnLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
454
+ await this.debugWarnLog(statusCode, deviceStatus);
560
455
  }
561
456
  } catch (e: any) {
562
- this.apiError(e);
563
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
564
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
457
+ await this.apiError(e);
458
+ await this.errorLog(`failed openAPIRefreshStatus with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
565
459
  }
566
460
  }
567
461
 
568
- async registerWebhook(accessory: PlatformAccessory, device: device & devicesConfig) {
569
- if (device.webhook) {
570
- this.debugLog(`${device.deviceType}: ${accessory.displayName} is listening webhook.`);
571
- 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) => {
572
466
  try {
573
- this.debugLog(`${device.deviceType}: ${accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
574
- const { slidePosition, battery } = context;
575
- this.debugLog(`${device.deviceType}: ${accessory.displayName} ` +
576
- '(slidePosition, battery) = ' +
577
- `Webhook:(${slidePosition}, ${battery}), `
578
- + `current:(${this.WindowCovering.CurrentPosition}, ${this.Battery.BatteryLevel})`);
579
- this.WindowCovering.CurrentPosition = slidePosition;
580
- this.Battery.BatteryLevel = battery;
581
- this.updateHomeKitCharacteristics();
467
+ await this.debugLog(`received Webhook: ${JSON.stringify(context)}`);
468
+ await this.parseStatusWebhook(context);
469
+ await this.updateHomeKitCharacteristics();
582
470
  } catch (e: any) {
583
- this.errorLog(`${device.deviceType}: ${accessory.displayName} `
584
- + `failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
471
+ await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
585
472
  }
586
473
  };
474
+ } else {
475
+ await this.debugLog('is not listening webhook.');
587
476
  }
588
477
  }
589
478
 
479
+ /**
480
+ * Pushes the requested changes to the SwitchBot API
481
+ */
590
482
  async pushChanges(): Promise<void> {
591
483
  if (!this.device.enableCloudService && this.OpenAPI) {
592
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} pushChanges enableCloudService: ${this.device.enableCloudService}`);
484
+ await this.errorLog(`pushChanges enableCloudService: ${this.device.enableCloudService}`);
593
485
  } else if (this.BLE) {
594
486
  await this.BLEpushChanges();
595
487
  } else if (this.OpenAPI && this.platform.config.credentials?.token) {
596
488
  await this.openAPIpushChanges();
597
489
  } else {
598
490
  await this.offlineOff();
599
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
600
- + ` ${this.device.connectionType}, pushChanges will not happen.`);
491
+ await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, pushChanges will not happen.`);
601
492
  }
602
493
  // Refresh the status from the API
603
494
  interval(15000)
@@ -609,93 +500,84 @@ export class Curtain extends deviceBase {
609
500
  }
610
501
 
611
502
  async BLEpushChanges(): Promise<void> {
612
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
503
+ await this.debugLog('BLEpushChanges');
613
504
  if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition) {
614
- const switchbot = await this.platform.connectBLE();
615
- // Convert to BLE Address
505
+ const switchbot = await this.platform.connectBLE(this.accessory, this.device);
616
506
  await this.convertBLEAddress();
617
507
  const { setPositionMode, Mode }: { setPositionMode: number; Mode: string; } = await this.setPerformance();
618
508
  const adjustedMode = setPositionMode === 1 ? 0x01 : 0xff;
619
- this.debugLog(`${this.accessory.displayName} Mode: ${Mode}`);
509
+ await this.debugLog(`Mode: ${Mode}, setPositionMode: ${setPositionMode}`);
620
510
  if (switchbot !== false) {
621
- try {
622
- const device_list = await switchbot.discover({ model: this.device.bleModel, quick: true, id: this.device.bleMac });
623
- this.infoLog(`${this.accessory.displayName} Target Position: ${this.WindowCovering.TargetPosition}`);
624
-
625
- await this.retryBLE({
626
- max: await this.maxRetryBLE(),
627
- fn: async () => {
628
- await device_list[0].runToPos(100 - Number(this.WindowCovering.TargetPosition), adjustedMode);
629
- },
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();
630
529
  });
631
-
632
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
633
- this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
634
- + `TargetPosition: ${this.WindowCovering.TargetPosition} sent over BLE, sent successfully`);
635
- } catch (e) {
636
- this.apiError(e);
637
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
638
- + ` Connection, Error Message: ${JSON.stringify((e as Error).message)}`);
639
- await this.BLEPushConnection();
640
- throw new Error('Connection error');
641
- }
642
530
  } else {
643
- 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}`);
644
532
  await this.BLEPushConnection();
645
533
  }
646
534
  } else {
647
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges, CurrentPosition & TargetPosition Are the Same.`
648
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition ${this.WindowCovering.TargetPosition}`);
535
+ await this.debugLog(`No changes (BLEpushChanges), TargetPosition: ${this.WindowCovering.TargetPosition},`
536
+ + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
649
537
  }
650
538
  }
651
539
 
652
540
  async openAPIpushChanges(): Promise<void> {
653
- let command: string;
654
- let parameter: string;
655
- let commandType: string;
656
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
541
+ await this.debugLog('openAPIpushChanges');
657
542
  if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition || this.device.disableCaching) {
658
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Pushing ${this.WindowCovering.TargetPosition}`);
543
+ await this.debugLog(`Pushing ${this.WindowCovering.TargetPosition}`);
659
544
  const adjustedTargetPosition = 100 - Number(this.WindowCovering.TargetPosition);
660
545
  const { setPositionMode, Mode }: { setPositionMode: number; Mode: string; } = await this.setPerformance();
661
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Mode: ${Mode}`);
546
+ await this.debugLog(`Mode: ${Mode}, setPositionMode: ${setPositionMode}`);
662
547
  const adjustedMode = setPositionMode || 'ff';
548
+ let bodyChange: string;
663
549
  if (this.WindowCovering.HoldPosition) {
664
- command = 'pause';
665
- parameter = 'default';
666
- commandType = 'command';
550
+ bodyChange = JSON.stringify({
551
+ command: 'pause',
552
+ parameter: 'default',
553
+ commandType: 'command',
554
+ });
667
555
  } else {
668
- command = 'setPosition';
669
- parameter = `0,${adjustedMode},${adjustedTargetPosition}`;
670
- commandType = 'command';
556
+ bodyChange = JSON.stringify({
557
+ command: 'setPosition',
558
+ parameter: `0,${adjustedMode},${adjustedTargetPosition}`,
559
+ commandType: 'command',
560
+ });
671
561
  }
672
- const bodyChange = JSON.stringify({
673
- command: command,
674
- parameter: parameter,
675
- commandType: commandType,
676
- });
677
- 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)}`);
678
563
  try {
679
564
  const { body, statusCode } = await this.pushChangeRequest(bodyChange);
680
565
  const deviceStatus: any = await body.json();
681
- await this.pushStatusCodes(statusCode, deviceStatus);
682
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
683
- this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
684
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
685
- this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
686
- + `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();
687
570
  } else {
688
- this.statusCode(statusCode);
689
- this.statusCode(deviceStatus.statusCode);
571
+ await this.statusCode(statusCode);
572
+ await this.statusCode(deviceStatus.statusCode);
690
573
  }
691
574
  } catch (e: any) {
692
- this.apiError(e);
693
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
694
- + ` 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)}`);
695
577
  }
696
578
  } else {
697
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No OpenAPI Changes, CurrentPosition & TargetPosition Are the Same.`
698
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition ${this.WindowCovering.TargetPosition}`);
579
+ await this.debugLog(`No changes (openAPIpushChanges), CurrentPosition: ${this.WindowCovering.CurrentPosition},`
580
+ + ` TargetPosition: ${this.WindowCovering.TargetPosition}`);
699
581
  }
700
582
  }
701
583
 
@@ -703,10 +585,10 @@ export class Curtain extends deviceBase {
703
585
  * Handle requests to set the value of the "Target Position" characteristic
704
586
  */
705
587
  async TargetPositionSet(value: CharacteristicValue): Promise<void> {
706
- if (this.WindowCovering.TargetPosition === this.accessory.context.TargetPosition) {
707
- 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}`);
708
590
  } else {
709
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetPosition: ${value}`);
591
+ await this.debugLog(`No Changes, TargetPosition: ${value}`);
710
592
  }
711
593
 
712
594
  // Set HoldPosition to false when TargetPosition is changed
@@ -714,27 +596,25 @@ export class Curtain extends deviceBase {
714
596
  this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.HoldPosition, this.WindowCovering.HoldPosition);
715
597
 
716
598
  this.WindowCovering.TargetPosition = value;
717
- if (this.device.mqttURL) {
718
- this.mqttPublish('TargetPosition', this.WindowCovering.TargetPosition.toString());
719
- this.mqttPublish('HoldPosition', this.WindowCovering.HoldPosition.toString()); // Convert boolean to string
720
- }
599
+ await this.mqtt('TargetPosition', this.WindowCovering.TargetPosition);
600
+ await this.mqtt('HoldPosition', this.WindowCovering.HoldPosition);
601
+ await this.startUpdatingCurtainIfNeeded();
602
+ }
721
603
 
604
+ async startUpdatingCurtainIfNeeded() {
722
605
  await this.setMinMax();
723
- if (value > this.WindowCovering.CurrentPosition) {
606
+ if (this.WindowCovering.TargetPosition > this.WindowCovering.CurrentPosition) {
724
607
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
725
608
  this.setNewTarget = true;
726
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value},`
727
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
728
- } else if (value < this.WindowCovering.CurrentPosition) {
609
+ await this.debugLog(`value: ${this.WindowCovering.TargetPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
610
+ } else if (this.WindowCovering.TargetPosition < this.WindowCovering.CurrentPosition) {
729
611
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
730
612
  this.setNewTarget = true;
731
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value},`
732
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
613
+ await this.debugLog(`value: ${this.WindowCovering.TargetPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
733
614
  } else {
734
615
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
735
616
  this.setNewTarget = false;
736
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value},`
737
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
617
+ await this.debugLog(`value: ${this.WindowCovering.TargetPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
738
618
  }
739
619
  this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.WindowCovering.PositionState);
740
620
  this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
@@ -744,10 +624,10 @@ export class Curtain extends deviceBase {
744
624
  * The minimum time depends on the network control latency.
745
625
  */
746
626
  clearTimeout(this.setNewTargetTimer);
747
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateRate: ${this.deviceUpdateRate}`);
627
+ await this.debugLog(`deviceUpdateRate: ${this.deviceUpdateRate}`);
748
628
  if (this.setNewTarget) {
749
- this.setNewTargetTimer = setTimeout(() => {
750
- 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`);
751
631
  this.setNewTarget = false;
752
632
  }, this.deviceUpdateRate * 1000);
753
633
  }
@@ -758,125 +638,53 @@ export class Curtain extends deviceBase {
758
638
  * Handle requests to set the value of the "Target Position" characteristic
759
639
  */
760
640
  async HoldPositionSet(value: CharacteristicValue): Promise<void> {
761
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} HoldPosition: ${value}`);
641
+ this.debugLog(`HoldPosition: ${value}`);
762
642
  this.WindowCovering.HoldPosition = value;
763
643
  this.doCurtainUpdate.next();
764
644
  }
765
645
 
766
646
  async updateHomeKitCharacteristics(): Promise<void> {
767
647
  await this.setMinMax();
768
- if (this.WindowCovering.CurrentPosition === undefined || Number.isNaN(this.WindowCovering.CurrentPosition)) {
769
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
770
- } else {
771
- this.accessory.context.CurrentPosition = this.WindowCovering.CurrentPosition;
772
- this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, Number(this.WindowCovering.CurrentPosition));
773
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
774
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
775
- if (this.device.mqttURL) {
776
- this.mqttPublish('CurrentPosition', this.WindowCovering.CurrentPosition.toString()); // Convert to string
777
- }
778
- }
779
- if (this.WindowCovering.PositionState === undefined) {
780
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} PositionState: ${this.WindowCovering.PositionState}`);
781
- } else {
782
- if (this.device.mqttURL) {
783
- this.mqttPublish('PositionState', this.WindowCovering.PositionState.toString());
784
- }
785
- this.accessory.context.PositionState = this.WindowCovering.PositionState;
786
- this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, Number(this.WindowCovering.PositionState));
787
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
788
- + ` PositionState: ${this.WindowCovering.PositionState}`);
789
- }
790
- if (this.WindowCovering.TargetPosition === undefined || Number.isNaN(this.WindowCovering.TargetPosition)) {
791
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} TargetPosition: ${this.WindowCovering.TargetPosition}`);
792
- } else {
793
- if (this.device.mqttURL) {
794
- this.mqttPublish('TargetPosition', this.WindowCovering.TargetPosition.toString());
795
- }
796
- this.accessory.context.TargetPosition = this.WindowCovering.TargetPosition;
797
- this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, Number(this.WindowCovering.TargetPosition));
798
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
799
- + ` TargetPosition: ${this.WindowCovering.TargetPosition}`);
800
- }
801
- if (this.WindowCovering.HoldPosition === undefined) {
802
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} HoldPosition: ${this.WindowCovering.HoldPosition}`);
803
- } else {
804
- if (this.device.mqttURL) {
805
- this.mqttPublish('HoldPosition', this.WindowCovering.HoldPosition.toString());
806
- }
807
- this.accessory.context.HoldPosition = this.WindowCovering.HoldPosition;
808
- this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.HoldPosition, this.WindowCovering.HoldPosition);
809
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
810
- + ` HoldPosition: ${this.WindowCovering.HoldPosition}`);
811
- }
812
- if (!this.device.curtain?.hide_lightsensor) {
813
- if (this.LightSensor!.CurrentAmbientLightLevel === undefined || Number.isNaN(this.LightSensor!.CurrentAmbientLightLevel)) {
814
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
815
- + ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
816
- } else {
817
- if (this.device.mqttURL) {
818
- this.mqttPublish('CurrentAmbientLightLevel', this.LightSensor!.CurrentAmbientLightLevel.toString());
819
- }
820
- this.accessory.context.CurrentAmbientLightLevel = this.LightSensor!.CurrentAmbientLightLevel;
821
- this.LightSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, this.LightSensor!.CurrentAmbientLightLevel);
822
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
823
- + ` updateCharacteristic CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
824
- if (this.device.history) {
825
- this.historyService?.addEntry({
826
- time: Math.round(new Date().valueOf() / 1000),
827
- lux: this.LightSensor!.CurrentAmbientLightLevel,
828
- });
829
- }
830
- }
831
- }
832
- if (this.Battery.BatteryLevel === undefined) {
833
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
834
- } else {
835
- if (this.device.mqttURL) {
836
- this.mqttPublish('BatteryLevel', this.Battery.BatteryLevel.toString());
837
- }
838
- this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
839
- this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
840
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.Battery.BatteryLevel}`);
841
- }
842
- if (this.Battery.StatusLowBattery === undefined) {
843
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
844
- } else {
845
- if (this.device.mqttURL) {
846
- this.mqttPublish('StatusLowBattery', this.Battery.StatusLowBattery.toString());
847
- }
848
- this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
849
- this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
850
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
851
- + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
852
- }
853
- if (this.Battery.ChargingState === undefined) {
854
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ChargingState: ${this.Battery.ChargingState}`);
855
- } else {
856
- if (this.device.mqttURL) {
857
- this.mqttPublish('ChargingState', this.Battery.ChargingState.toString());
858
- }
859
- this.accessory.context.ChargingState = this.Battery.ChargingState;
860
- this.Battery.Service.updateCharacteristic(this.hap.Characteristic.ChargingState, this.Battery.ChargingState);
861
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
862
- + ` ChargingState: ${this.Battery.ChargingState}`);
648
+ // CurrentPosition
649
+ await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.CurrentPosition,
650
+ this.WindowCovering.CurrentPosition, 'CurrentPosition');
651
+ // PositionState
652
+ await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.PositionState,
653
+ this.WindowCovering.PositionState, 'PositionState');
654
+ // TargetPosition
655
+ await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.TargetPosition,
656
+ this.WindowCovering.TargetPosition, 'TargetPosition');
657
+ // HoldPosition
658
+ await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.HoldPosition,
659
+ this.WindowCovering.HoldPosition, 'HoldPosition');
660
+ // CurrentAmbientLightLevel
661
+ if (!this.device.curtain?.hide_lightsensor && this.LightSensor?.Service) {
662
+ const history = { time: Math.round(new Date().valueOf() / 1000), lux: this.LightSensor.CurrentAmbientLightLevel };
663
+ await this.updateCharacteristic(this.LightSensor?.Service, this.hap.Characteristic.CurrentAmbientLightLevel,
664
+ this.LightSensor?.CurrentAmbientLightLevel, 'CurrentAmbientLightLevel', history);
863
665
  }
666
+ // BatteryLevel
667
+ await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.BatteryLevel,
668
+ this.Battery.BatteryLevel, 'BatteryLevel');
669
+ // StatusLowBattery
670
+ await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.StatusLowBattery,
671
+ this.Battery.StatusLowBattery, 'StatusLowBattery');
672
+ // ChargingState
673
+ await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.ChargingState,
674
+ this.Battery.ChargingState, 'ChargingState');
864
675
  }
865
676
 
866
677
  async BLEPushConnection() {
867
678
  if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
868
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Push Changes`);
679
+ await this.warnLog('Using OpenAPI Connection to Push Changes');
869
680
  await this.openAPIpushChanges();
870
681
  }
871
682
  }
872
683
 
873
684
  async BLERefreshConnection(switchbot: any): Promise<void> {
874
- if (switchbot !== undefined) {
875
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot:`
876
- + ` ${JSON.stringify(switchbot)}`);
877
- }
685
+ await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${JSON.stringify(switchbot)}`);
878
686
  if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
879
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Refresh Status`);
687
+ await this.warnLog('Using OpenAPI Connection to Refresh Status');
880
688
  await this.openAPIRefreshStatus();
881
689
  }
882
690
  }
@@ -910,6 +718,38 @@ export class Curtain extends deviceBase {
910
718
  return { setPositionMode, Mode };
911
719
  }
912
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
+
913
753
  async setMinMax(): Promise<void> {
914
754
  if (this.device.curtain?.set_min) {
915
755
  if (Number(this.WindowCovering.CurrentPosition) <= this.device.curtain?.set_min) {
@@ -943,9 +783,9 @@ export class Curtain extends deviceBase {
943
783
  this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
944
784
  this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
945
785
  this.Battery.Service.updateCharacteristic(this.hap.Characteristic.ChargingState, e);
946
- if (!this.device.curtain?.hide_lightsensor) {
947
- this.LightSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e);
948
- 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);
949
789
  }
950
790
  }
951
791
  }