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

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 +223 -263
  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
@@ -2,10 +2,10 @@
2
2
  *
3
3
  * blindtilt.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
- import { interval, Subject } from 'rxjs';
6
5
  import { deviceBase } from './device.js';
7
6
  import { BlindTiltMappingMode } from '../utils.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
  export class BlindTilt extends deviceBase {
10
10
  platform;
11
11
  // Services
@@ -65,7 +65,7 @@ export class BlindTilt extends deviceBase {
65
65
  maxValue: 100,
66
66
  validValueRanges: [0, 100],
67
67
  }).onGet(() => {
68
- return this.WindowCovering?.CurrentPosition ?? 0;
68
+ return this.WindowCovering.CurrentPosition ?? 0;
69
69
  });
70
70
  // Initialize WindowCovering TargetHorizontalTiltAngle Characteristic
71
71
  this.WindowCovering.Service
@@ -108,11 +108,14 @@ export class BlindTilt extends deviceBase {
108
108
  // Initialize LightSensor Service
109
109
  if (device.blindTilt?.hide_lightsensor) {
110
110
  if (this.LightSensor?.Service) {
111
- this.debugLog(`${device.deviceType}: ${accessory.displayName} Removing Light Sensor Service`);
111
+ this.debugLog('Removing Light Sensor Service');
112
112
  this.LightSensor.Service = accessory.getService(this.hap.Service.LightSensor);
113
113
  accessory.removeService(this.LightSensor.Service);
114
114
  accessory.context.LightSensor = {};
115
115
  }
116
+ else {
117
+ this.debugLog('Light Sensor Service is already removed');
118
+ }
116
119
  }
117
120
  else {
118
121
  accessory.context.LightSensor = accessory.context.LightSensor ?? {};
@@ -135,22 +138,21 @@ export class BlindTilt extends deviceBase {
135
138
  this.refreshStatus();
136
139
  // Update Homekit
137
140
  this.updateHomeKitCharacteristics();
141
+ //regisiter webhook event handler
142
+ this.registerWebhook();
138
143
  // Start an update interval
139
144
  interval(this.deviceRefreshRate * 1000)
140
145
  .pipe(skipWhile(() => this.blindTiltUpdateInProgress))
141
146
  .subscribe(async () => {
142
147
  await this.refreshStatus();
143
148
  });
144
- //regisiter webhook event handler
145
- this.registerWebhook(accessory, device);
146
149
  // update slide progress
147
150
  interval(this.deviceUpdateRate * 1000)
148
151
  .subscribe(async () => {
149
152
  if (this.WindowCovering.PositionState === this.hap.Characteristic.PositionState.STOPPED) {
150
153
  return;
151
154
  }
152
- this.debugLog(`${device.deviceType}: ${accessory.displayName} Refresh Status When Moving,`
153
- + ` PositionState: ${this.WindowCovering.PositionState}`);
155
+ this.debugLog(`Refresh Status When Moving, PositionState: ${this.WindowCovering.PositionState}`);
154
156
  await this.refreshStatus();
155
157
  });
156
158
  // Watch for BlindTilt change events
@@ -164,9 +166,8 @@ export class BlindTilt extends deviceBase {
164
166
  await this.pushChanges();
165
167
  }
166
168
  catch (e) {
167
- this.apiError(e);
168
- this.errorLog(`${device.deviceType}: ${accessory.displayName} failed pushChanges with ${device.connectionType} Connection,`
169
- + ` Error Message: ${JSON.stringify(e.message)}`);
169
+ await this.apiError(e);
170
+ await this.errorLog(`failed pushChanges with ${device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
170
171
  }
171
172
  this.blindTiltUpdateInProgress = false;
172
173
  });
@@ -175,210 +176,121 @@ export class BlindTilt extends deviceBase {
175
176
  * Parse the device status from the SwitchBotBLE API
176
177
  */
177
178
  async BLEparseStatus(serviceData) {
178
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
179
+ await this.debugLog('BLEparseStatus');
179
180
  // CurrentPosition
180
- this.WindowCovering.CurrentPosition = 100 - Number(serviceData.position);
181
+ this.WindowCovering.CurrentPosition = 100 - Number(serviceData.tilt);
181
182
  await this.setMinMax();
182
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition ${this.WindowCovering.CurrentPosition}`);
183
+ await this.debugLog(`CurrentPosition ${this.WindowCovering.CurrentPosition}`);
183
184
  if (this.setNewTarget) {
184
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Checking Status ...`);
185
+ await this.infoLog('Checking Status ...');
185
186
  }
186
187
  if (this.setNewTarget && serviceData.inMotion) {
187
188
  await this.setMinMax();
188
189
  if (Number(this.WindowCovering.TargetPosition) > this.WindowCovering.CurrentPosition) {
189
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
190
+ await this.debugLog(`Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
190
191
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
191
192
  this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
192
- this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} INCREASING`
193
- + ` PositionState: ${this.WindowCovering.PositionState}`);
193
+ await this.debugLog(`Increasing, PositionState: ${this.WindowCovering.PositionState}`);
194
194
  }
195
195
  else if (Number(this.WindowCovering.TargetPosition) < this.WindowCovering.CurrentPosition) {
196
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
196
+ await this.debugLog(`Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
197
197
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
198
198
  this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
199
- this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} DECREASING`
200
- + ` PositionState: ${this.WindowCovering.PositionState}`);
199
+ await this.debugLog(`Decreasing, PositionState: ${this.WindowCovering.PositionState}`);
201
200
  }
202
201
  else {
203
- this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} Standby2,`
204
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
202
+ await this.debugLog(`Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
205
203
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
206
204
  this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
207
- this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} STOPPED`
208
- + ` PositionState: ${this.WindowCovering.PositionState}`);
205
+ await this.debugLog('Stopped, PositionState', this.WindowCovering.PositionState);
209
206
  }
210
207
  }
211
208
  else {
212
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
209
+ await this.debugLog(`Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
213
210
  this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition;
214
211
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
215
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Stopped`);
212
+ await this.debugLog(`Stopped, PositionState: ${this.WindowCovering.PositionState}`);
216
213
  }
217
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition},`
218
- + ` TargetPosition: ${this.WindowCovering.TargetPosition}, PositionState: ${this.WindowCovering.PositionState},`);
214
+ await this.debugLog(`CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition: ${this.WindowCovering.TargetPosition},`
215
+ + ` PositionState: ${this.WindowCovering.PositionState}`);
216
+ // CurrentAmbientLightLevel
219
217
  if (!this.device.blindTilt?.hide_lightsensor && this.LightSensor?.Service) {
220
- if (this.LightSensor?.CurrentAmbientLightLevel === 0) {
221
- this.LightSensor.CurrentAmbientLightLevel = 0.0001;
222
- }
223
218
  const set_minLux = this.device.blindTilt?.set_minLux ?? 1;
224
219
  const set_maxLux = this.device.blindTilt?.set_maxLux ?? 6001;
225
220
  const spaceBetweenLevels = 9;
226
- // Brightness
227
- switch (serviceData.lightLevel) {
228
- case 1:
229
- this.LightSensor.CurrentAmbientLightLevel = set_minLux;
230
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
231
- break;
232
- case 2:
233
- this.LightSensor.CurrentAmbientLightLevel = (set_maxLux - set_minLux) / spaceBetweenLevels;
234
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel},`
235
- + ` Calculation: ${(set_maxLux - set_minLux) / spaceBetweenLevels}`);
236
- break;
237
- case 3:
238
- this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 2;
239
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
240
- break;
241
- case 4:
242
- this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 3;
243
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
244
- break;
245
- case 5:
246
- this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 4;
247
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
248
- break;
249
- case 6:
250
- this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 5;
251
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
252
- break;
253
- case 7:
254
- this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 6;
255
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
256
- break;
257
- case 8:
258
- this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 7;
259
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
260
- break;
261
- case 9:
262
- this.LightSensor.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 8;
263
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
264
- break;
265
- case 10:
266
- default:
267
- this.LightSensor.CurrentAmbientLightLevel = set_maxLux;
268
- this.debugLog();
269
- }
270
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel},`
271
- + ` CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`);
221
+ await this.getLightLevel(serviceData.lightLevel, set_minLux, set_maxLux, spaceBetweenLevels);
222
+ await this.debugLog(`LightLevel: ${serviceData.lightLevel}, CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`);
272
223
  }
273
- // Battery
224
+ // BatteryLevel
274
225
  this.Battery.BatteryLevel = Number(serviceData.battery);
275
- if (this.Battery.BatteryLevel < 10) {
276
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
277
- }
278
- else {
279
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
280
- }
281
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
282
- + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
226
+ await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
227
+ // StatusLowBattery
228
+ this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
229
+ ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
230
+ await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`);
283
231
  }
232
+ ;
284
233
  /**
285
234
  * Parse the device status from the SwitchBot OpenAPI
286
235
  */
287
236
  async openAPIparseStatus(deviceStatus) {
288
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
289
- const [homekitPosition, homekitTiltAngle] = this.mapDeviceValuesToHomekitValues(Number(deviceStatus.body.slidePosition), String(deviceStatus.body.direction));
290
- this.debugLog(` device: ${deviceStatus.body.slidePosition} => HK: ${homekitPosition}`);
291
- this.WindowCovering.CurrentPosition = homekitPosition;
237
+ await this.debugLog('openAPIparseStatus');
292
238
  // CurrentPosition
293
- await this.setMinMax();
294
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
295
- if (homekitTiltAngle) {
296
- this.WindowCovering.CurrentHorizontalTiltAngle = homekitTiltAngle;
297
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
298
- + ` CurrentHorizontalTiltAngle: ${this.WindowCovering.CurrentHorizontalTiltAngle}`);
299
- }
300
- if (this.setNewTarget) {
301
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Checking Status ...`);
239
+ await this.getCurrentPosttionDirection(deviceStatus.direction, deviceStatus.slidePosition);
240
+ if (!this.device.blindTilt?.hide_lightsensor && this.LightSensor?.Service) {
241
+ const set_minLux = this.device.blindTilt?.set_minLux ?? 1;
242
+ const set_maxLux = this.device.blindTilt?.set_maxLux ?? 6001;
243
+ const lightLevel = deviceStatus.lightLevel === 'bright' ? set_maxLux : set_minLux;
244
+ this.LightSensor.CurrentAmbientLightLevel = await this.getLightLevel(lightLevel, set_minLux, set_maxLux, 2);
245
+ await this.debugLog(`LightLevel: ${deviceStatus.lightLevel}, CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`);
302
246
  }
303
- if (this.setNewTarget && deviceStatus.body.moving) {
304
- await this.setMinMax();
305
- if (this.WindowCovering.TargetPosition > this.WindowCovering.CurrentPosition
306
- || (homekitTiltAngle && this.WindowCovering.TargetHorizontalTiltAngle !== this.WindowCovering.CurrentHorizontalTiltAngle)) {
307
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition} `);
308
- this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
309
- this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
310
- this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} INCREASING`
311
- + ` PositionState: ${this.WindowCovering.PositionState}`);
312
- }
313
- else if (this.WindowCovering.TargetPosition < this.WindowCovering.CurrentPosition) {
314
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition} `);
315
- this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
316
- this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
317
- this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} DECREASING`
318
- + ` PositionState: ${this.WindowCovering.PositionState}`);
247
+ // BatteryLevel
248
+ this.Battery.BatteryLevel = Number(deviceStatus.battery);
249
+ await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
250
+ // StatusLowBattery
251
+ this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
252
+ ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
253
+ await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`);
254
+ // Firmware Version
255
+ const version = deviceStatus.version.toString();
256
+ await this.debugLog(`Firmware Version: ${version.replace(/^V|-.*$/g, '')}`);
257
+ if (deviceStatus.version) {
258
+ let deviceVersion;
259
+ if (version?.includes('.') === false) {
260
+ const replace = version?.replace(/^V|-.*$/g, '');
261
+ const match = replace?.match(/.{1,1}/g);
262
+ const blindTiltVersion = match?.join('.') ?? '0.0.0';
263
+ deviceVersion = blindTiltVersion;
319
264
  }
320
265
  else {
321
- this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} Standby because reached position,`
322
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
323
- this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
324
- this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
325
- this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} STOPPED`
326
- + ` PositionState: ${this.WindowCovering.PositionState}`);
327
- }
328
- }
329
- else {
330
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby because device not moving,`
331
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
332
- this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition;
333
- if (homekitTiltAngle) {
334
- this.WindowCovering.TargetHorizontalTiltAngle = this.WindowCovering.CurrentHorizontalTiltAngle;
266
+ deviceVersion = version.replace(/^V|-.*$/g, '') ?? '0.0.0';
335
267
  }
336
- this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
337
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Stopped`);
338
- }
339
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition},`
340
- + ` TargetPosition: ${this.WindowCovering.TargetPosition}, PositionState: ${this.WindowCovering.PositionState},`);
341
- if (!this.device.blindTilt?.hide_lightsensor) {
342
- const set_minLux = this.device.blindTilt?.set_minLux ?? 1;
343
- const set_maxLux = this.device.blindTilt?.set_maxLux ?? 6001;
344
- // Brightness
345
- switch (deviceStatus.body.brightness) {
346
- case 'dim':
347
- this.LightSensor.CurrentAmbientLightLevel = set_minLux;
348
- break;
349
- case 'bright':
350
- default:
351
- this.LightSensor.CurrentAmbientLightLevel = set_maxLux;
352
- }
353
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
354
- + ` CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`);
268
+ this.accessory
269
+ .getService(this.hap.Service.AccessoryInformation)
270
+ .setCharacteristic(this.hap.Characteristic.HardwareRevision, deviceVersion)
271
+ .setCharacteristic(this.hap.Characteristic.FirmwareRevision, deviceVersion)
272
+ .getCharacteristic(this.hap.Characteristic.FirmwareRevision)
273
+ .updateValue(deviceVersion);
274
+ this.accessory.context.deviceVersion = deviceVersion;
275
+ await this.debugLog(`deviceVersion: ${this.accessory.context.deviceVersion}`);
355
276
  }
277
+ }
278
+ async parseStatusWebhook(context) {
279
+ await this.debugLog('parseStatusWebhook');
280
+ await this.debugLog(`(slidePosition, battery, version) = Webhook:(${context.direction}, ${context.slidePosition}, ${context.battery},`
281
+ + `${context.version}, current:(${this.WindowCovering.CurrentHorizontalTiltAngle}, ${this.WindowCovering.CurrentPosition},`
282
+ + ` ${this.Battery.BatteryLevel}, ${this.accessory.context.deviceVersion})`);
283
+ // CurrentPosition and CurrentHorizontalTiltAngle
284
+ await this.getCurrentPosttionDirection(context.direction, context.slidePosition);
356
285
  // BatteryLevel
357
- this.Battery.BatteryLevel = Number(deviceStatus.body.battery);
358
- if (this.Battery.BatteryLevel < 10) {
359
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
360
- }
361
- else {
362
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
363
- }
364
- if (Number.isNaN(this.Battery.BatteryLevel)) {
365
- this.Battery.BatteryLevel = 100;
366
- }
367
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
368
- + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
286
+ this.Battery.BatteryLevel = context.battery;
287
+ await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
288
+ // StatusLowBattery
289
+ this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
290
+ ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
291
+ await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`);
369
292
  // Firmware Version
370
- const version = deviceStatus.body.version?.toString();
371
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Firmware Version: ${version?.replace(/^V|-.*$/g, '')}`);
372
- let deviceVersion;
373
- if (version?.includes('.') === false) {
374
- const replace = version?.replace(/^V|-.*$/g, '');
375
- const match = replace?.match(/.{1,1}/g);
376
- const blindTiltVersion = match?.join('.') ?? '0.0.0';
377
- deviceVersion = blindTiltVersion;
378
- }
379
- else {
380
- deviceVersion = version?.replace(/^V|-.*$/g, '') ?? '0.0.0';
381
- }
293
+ const deviceVersion = context.version.replace(/^V|-.*$/g, '') ?? '0.0.0';
382
294
  this.accessory
383
295
  .getService(this.hap.Service.AccessoryInformation)
384
296
  .setCharacteristic(this.hap.Characteristic.HardwareRevision, deviceVersion)
@@ -386,11 +298,14 @@ export class BlindTilt extends deviceBase {
386
298
  .getCharacteristic(this.hap.Characteristic.FirmwareRevision)
387
299
  .updateValue(deviceVersion);
388
300
  this.accessory.context.deviceVersion = deviceVersion;
389
- this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceVersion: ${this.accessory.context.deviceVersion}`);
301
+ await this.debugSuccessLog(`deviceVersion: ${this.accessory.context.deviceVersion}`);
390
302
  }
303
+ /**
304
+ * Asks the SwitchBot API for the latest device information
305
+ */
391
306
  async refreshStatus() {
392
307
  if (!this.device.enableCloudService && this.OpenAPI) {
393
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} refreshStatus enableCloudService: ${this.device.enableCloudService}`);
308
+ await this.errorLog(`refreshStatus enableCloudService: ${this.device.enableCloudService}`);
394
309
  }
395
310
  else if (this.BLE) {
396
311
  await this.BLERefreshStatus();
@@ -400,12 +315,11 @@ export class BlindTilt extends deviceBase {
400
315
  }
401
316
  else {
402
317
  await this.offlineOff();
403
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
404
- + ` ${this.device.connectionType}, refreshStatus will not happen.`);
318
+ await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, refreshStatus will not happen.`);
405
319
  }
406
320
  }
407
321
  async BLERefreshStatus() {
408
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
322
+ await this.debugLog('BLERefreshStatus');
409
323
  const switchbot = await this.switchbotBLE();
410
324
  if (switchbot === undefined) {
411
325
  await this.BLERefreshConnection(switchbot);
@@ -416,69 +330,60 @@ export class BlindTilt extends deviceBase {
416
330
  // Start to monitor advertisement packets
417
331
  const serviceData = await this.monitorAdvertisementPackets(switchbot);
418
332
  // Update HomeKit
419
- if (serviceData.model !== '' && serviceData.modelName !== '') {
333
+ if (serviceData.model === SwitchBotBLEModel.BlindTilt && serviceData.modelName === SwitchBotBLEModelName.BlindTilt) {
420
334
  await this.BLEparseStatus(serviceData);
421
335
  await this.updateHomeKitCharacteristics();
422
336
  }
423
337
  else {
424
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
338
+ await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
425
339
  await this.BLERefreshConnection(switchbot);
426
340
  }
427
341
  })();
428
342
  }
429
343
  }
430
344
  async openAPIRefreshStatus() {
431
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
345
+ await this.debugLog('openAPIRefreshStatus');
432
346
  try {
433
347
  const { body, statusCode } = await this.deviceRefreshStatus();
434
348
  const deviceStatus = await body.json();
435
- await this.refreshStatusCodes(statusCode, deviceStatus);
349
+ await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
436
350
  ;
437
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
438
- await this.successfulRefreshStatus(statusCode, deviceStatus);
439
- await this.openAPIparseStatus(deviceStatus);
351
+ if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
352
+ await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
353
+ await this.openAPIparseStatus(deviceStatus.body);
440
354
  await this.updateHomeKitCharacteristics();
441
355
  }
442
356
  else {
443
- await this.statusCodes(statusCode, deviceStatus);
357
+ await this.debugWarnLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
358
+ await this.debugWarnLog(statusCode, deviceStatus);
444
359
  }
445
360
  }
446
361
  catch (e) {
447
362
  await this.apiError(e);
448
- await this.openAPIRefreshError(e);
363
+ await this.errorLog(`failed openAPIRefreshStatus with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
449
364
  }
450
365
  }
451
- async registerWebhook(accessory, device) {
452
- if (device.webhook) {
453
- this.debugLog(`${device.deviceType}: ${accessory.displayName} is listening webhook.`);
366
+ async registerWebhook() {
367
+ if (this.device.webhook) {
368
+ await this.debugLog('is listening webhook.');
454
369
  this.platform.webhookEventHandler[this.device.deviceId] = async (context) => {
455
370
  try {
456
- this.debugLog(`${device.deviceType}: ${accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
457
- const { slidePosition, battery, lightLevel } = context;
458
- const { CurrentPosition } = this.WindowCovering;
459
- const { BatteryLevel } = this.Battery;
460
- const { CurrentAmbientLightLevel } = this.LightSensor ?? {};
461
- this.debugLog(`${device.deviceType}: ${accessory.displayName} (slidePosition, battery, lightLevel) = Webhook:(${slidePosition}, ${battery},`
462
- + ` ${lightLevel}), current:(${CurrentPosition}, ${BatteryLevel}, ${CurrentAmbientLightLevel})`);
463
- this.WindowCovering.CurrentPosition = slidePosition;
464
- this.Battery.BatteryLevel = battery;
465
- if (!device.blindTilt?.hide_lightsensor) {
466
- this.LightSensor.CurrentAmbientLightLevel = lightLevel;
467
- }
371
+ await this.debugLog(`received Webhook: ${JSON.stringify(context)}`);
372
+ await this.parseStatusWebhook(context);
468
373
  await this.updateHomeKitCharacteristics();
469
374
  }
470
375
  catch (e) {
471
- this.errorLog(`${device.deviceType}: ${accessory.displayName} failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
376
+ await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
472
377
  }
473
378
  };
474
379
  }
475
380
  else {
476
- this.debugLog(`${device.deviceType}: ${accessory.displayName} is not listening webhook.`);
381
+ await this.debugLog('is not listening webhook.');
477
382
  }
478
383
  }
479
384
  async pushChanges() {
480
385
  if (!this.device.enableCloudService && this.OpenAPI) {
481
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} pushChanges enableCloudService: ${this.device.enableCloudService}`);
386
+ await this.errorLog(`pushChanges enableCloudService: ${this.device.enableCloudService}`);
482
387
  }
483
388
  else if (this.BLE) {
484
389
  await this.BLEpushChanges();
@@ -488,7 +393,7 @@ export class BlindTilt extends deviceBase {
488
393
  }
489
394
  else {
490
395
  await this.offlineOff();
491
- await this.pushChangeDisabled();
396
+ await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, pushChanges will not happen.`);
492
397
  }
493
398
  // Refresh the status from the API
494
399
  interval(15000)
@@ -499,18 +404,17 @@ export class BlindTilt extends deviceBase {
499
404
  });
500
405
  }
501
406
  async BLEpushChanges() {
502
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
407
+ await this.debugLog('BLEpushChanges');
503
408
  if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition) {
504
- const switchbot = await this.platform.connectBLE();
505
- // Convert to BLE Address
409
+ await this.debugLog(`BLEpushChanges On: ${this.WindowCovering.TargetPosition} OnCached: ${this.WindowCovering.CurrentPosition}`);
410
+ const switchbot = await this.platform.connectBLE(this.accessory, this.device);
506
411
  await this.convertBLEAddress();
507
412
  const { setPositionMode, Mode } = await this.setPerformance();
508
- this.debugLog(`${this.accessory.displayName} Mode: ${Mode}`);
413
+ await this.debugLog(`Mode: ${Mode}, setPositionMode: ${setPositionMode}`);
509
414
  if (switchbot !== false) {
510
415
  switchbot
511
416
  .discover({ model: this.device.bleModel, quick: true, id: this.device.bleMac })
512
417
  .then(async (device_list) => {
513
- this.infoLog(`${this.accessory.displayName} Target Position: ${this.WindowCovering.TargetPosition}`);
514
418
  return await this.retryBLE({
515
419
  max: await this.maxRetryBLE(),
516
420
  fn: async () => {
@@ -518,39 +422,37 @@ export class BlindTilt extends deviceBase {
518
422
  },
519
423
  });
520
424
  })
521
- .then(() => {
522
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
523
- this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
524
- + `Target Position: ${this.WindowCovering.TargetPosition} sent over BLE, sent successfully`);
425
+ .then(async () => {
426
+ await this.successLog(`TargetPostion: ${this.WindowCovering.TargetPosition} sent over SwitchBot BLE, sent successfully`);
427
+ await this.updateHomeKitCharacteristics();
525
428
  })
526
429
  .catch(async (e) => {
527
430
  await this.apiError(e);
528
- await this.failedBLEChanges(e);
431
+ await this.errorLog(`failed BLEpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
529
432
  await this.BLEPushConnection();
530
433
  });
531
434
  }
532
435
  else {
533
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection,`);
436
+ await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
534
437
  await this.BLEPushConnection();
535
438
  }
536
439
  }
537
440
  else {
538
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges, CurrentPosition & TargetPosition Are the Same.`
539
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition ${this.WindowCovering.TargetPosition}`);
441
+ await this.debugLog(`No changes (BLEpushChanges), TargetPosition: ${this.WindowCovering.TargetPosition},`
442
+ + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
540
443
  }
541
444
  }
542
445
  async openAPIpushChanges() {
543
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
446
+ await this.debugLog('openAPIpushChanges');
544
447
  const hasDifferentAndRelevantHorizontalTiltAngle = this.mappingMode === BlindTiltMappingMode.UseTiltForDirection
545
448
  && this.WindowCovering.TargetHorizontalTiltAngle !== this.WindowCovering.CurrentHorizontalTiltAngle;
546
449
  if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition
547
450
  || hasDifferentAndRelevantHorizontalTiltAngle || this.device.disableCaching) {
548
451
  const [direction, position] = this.mapHomekitValuesToDeviceValues(Number(this.WindowCovering.TargetPosition), Number(this.WindowCovering.TargetHorizontalTiltAngle));
549
- const { Mode } = await this.setPerformance();
550
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
551
- + ` Pushing ${this.WindowCovering.TargetPosition} (device = ${direction};${position})`);
552
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Mode: ${Mode}`);
553
- let bodyChange = '';
452
+ const { Mode, setPositionMode } = await this.setPerformance();
453
+ await this.debugLog(`Pushing ${this.WindowCovering.TargetPosition} (device = ${direction};${position})`);
454
+ await this.debugLog(`Mode: ${Mode}, setPositionMode: ${setPositionMode}`);
455
+ let bodyChange;
554
456
  if (position === 100) {
555
457
  bodyChange = JSON.stringify({
556
458
  command: 'fullyOpen',
@@ -572,13 +474,13 @@ export class BlindTilt extends deviceBase {
572
474
  commandType: 'command',
573
475
  });
574
476
  }
575
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
477
+ await this.debugLog(`SwitchBot OpenAPI bodyChange: ${JSON.stringify(bodyChange)}`);
576
478
  try {
577
479
  const { body, statusCode } = await this.pushChangeRequest(bodyChange);
578
480
  const deviceStatus = await body.json();
579
- await this.pushStatusCodes(statusCode, deviceStatus);
580
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
581
- await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
481
+ await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
482
+ if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
483
+ await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
582
484
  await this.updateHomeKitCharacteristics();
583
485
  }
584
486
  else {
@@ -587,16 +489,15 @@ export class BlindTilt extends deviceBase {
587
489
  }
588
490
  }
589
491
  catch (e) {
590
- this.apiError(e);
591
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
592
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
492
+ await this.apiError(e);
493
+ await this.errorLog(`failed openAPIpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
593
494
  }
594
495
  }
595
496
  else {
596
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No OpenAPI Changes, CurrentPosition & TargetPosition Are the Same.`
597
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition ${this.WindowCovering.TargetPosition}`
598
- + ` CurrentHorizontalTiltAngle: ${this.WindowCovering.CurrentHorizontalTiltAngle},`
599
- + ` TargetPosition ${this.WindowCovering.TargetHorizontalTiltAngle}`);
497
+ await this.debugLog(`No changes (openAPIpushChanges), TargetPosition: ${this.WindowCovering.TargetPosition},`
498
+ + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
499
+ await this.debugLog(`No changes (openAPIpushChanges), TargetHorizontalTiltAngle: ${this.WindowCovering.TargetHorizontalTiltAngle},`
500
+ + ` CurrentHorizontalTiltAngle: ${this.WindowCovering.CurrentHorizontalTiltAngle}`);
600
501
  }
601
502
  }
602
503
  /**
@@ -604,10 +505,10 @@ export class BlindTilt extends deviceBase {
604
505
  */
605
506
  async TargetHorizontalTiltAngleSet(value) {
606
507
  if (this.WindowCovering.TargetHorizontalTiltAngle !== this.accessory.context.TargetHorizontalTiltAngle) {
607
- await this.changeSet(value, 'TargetHorizontalTiltAngle');
508
+ await this.debugLog(`Set TargetHorizontalTiltAngle: ${value}`);
608
509
  }
609
510
  else {
610
- await this.noChangeSet(value, 'TargetHorizontalTiltAngle');
511
+ await this.debugLog(`No changes, TargetHorizontalTiltAngle: ${value}`);
611
512
  }
612
513
  //value = value < 0 ? -90 : 90;
613
514
  this.WindowCovering.TargetHorizontalTiltAngle = value;
@@ -619,10 +520,10 @@ export class BlindTilt extends deviceBase {
619
520
  */
620
521
  async TargetPositionSet(value) {
621
522
  if (this.WindowCovering.TargetPosition !== this.accessory.context.TargetPosition) {
622
- await this.changeSet(value, 'TargetPosition');
523
+ await this.debugLog(`Set TargetPosition: ${value}`);
623
524
  }
624
525
  else {
625
- await this.noChangeSet(value, 'TargetPosition');
526
+ await this.debugLog(`No changes, TargetPosition: ${value}`);
626
527
  }
627
528
  this.WindowCovering.TargetPosition = value;
628
529
  await this.mqtt('TargetPosition', this.WindowCovering.TargetPosition);
@@ -630,25 +531,22 @@ export class BlindTilt extends deviceBase {
630
531
  }
631
532
  async startUpdatingBlindTiltIfNeeded() {
632
533
  await this.setMinMax();
633
- this.debugLog('setMinMax');
534
+ await this.debugLog('setMinMax');
634
535
  if (this.WindowCovering.TargetPosition > this.WindowCovering.CurrentPosition
635
536
  || this.WindowCovering.TargetHorizontalTiltAngle !== this.WindowCovering.CurrentHorizontalTiltAngle) {
636
537
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
637
538
  this.setNewTarget = true;
638
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.WindowCovering.CurrentPosition},`
639
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
539
+ await this.debugLog(`value: ${this.WindowCovering.CurrentPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
640
540
  }
641
541
  else if (this.WindowCovering.TargetPosition < this.WindowCovering.CurrentPosition) {
642
542
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
643
543
  this.setNewTarget = true;
644
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.WindowCovering.CurrentPosition},`
645
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
544
+ await this.debugLog(`value: ${this.WindowCovering.CurrentPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
646
545
  }
647
546
  else {
648
547
  this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
649
548
  this.setNewTarget = false;
650
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.WindowCovering.CurrentPosition},`
651
- + ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
549
+ await this.debugLog(`value: ${this.WindowCovering.CurrentPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
652
550
  }
653
551
  this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.WindowCovering.PositionState);
654
552
  this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
@@ -657,10 +555,10 @@ export class BlindTilt extends deviceBase {
657
555
  * The minimum time depends on the network control latency.
658
556
  */
659
557
  clearTimeout(this.setNewTargetTimer);
660
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateRate: ${this.deviceUpdateRate}`);
558
+ await this.debugLog(`deviceUpdateRate: ${this.deviceUpdateRate}`);
661
559
  if (this.setNewTarget) {
662
- this.setNewTargetTimer = setTimeout(() => {
663
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} setNewTarget ${this.setNewTarget} timeout`);
560
+ this.setNewTargetTimer = setTimeout(async () => {
561
+ await this.debugLog(`setNewTarget ${this.setNewTarget} timeout`);
664
562
  this.setNewTarget = false;
665
563
  }, this.deviceUpdateRate * 1000);
666
564
  }
@@ -692,15 +590,14 @@ export class BlindTilt extends deviceBase {
692
590
  }
693
591
  async BLEPushConnection() {
694
592
  if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
695
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Push Changes`);
593
+ await this.warnLog('Using OpenAPI Connection to Push Changes');
696
594
  await this.openAPIpushChanges();
697
595
  }
698
596
  }
699
597
  async BLERefreshConnection(switchbot) {
700
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot:`
701
- + ` ${JSON.stringify(switchbot)}`);
598
+ await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${JSON.stringify(switchbot)}`);
702
599
  if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
703
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Refresh Status`);
600
+ await this.warnLog('Using OpenAPI Connection to Refresh Status');
704
601
  await this.openAPIRefreshStatus();
705
602
  }
706
603
  }
@@ -748,6 +645,11 @@ export class BlindTilt extends deviceBase {
748
645
  this.WindowCovering.CurrentPosition = 100;
749
646
  }
750
647
  }
648
+ if (this.device.history) {
649
+ const motion = this.accessory.getService(this.hap.Service.MotionSensor);
650
+ const state = Number(this.WindowCovering.CurrentPosition) > 0 ? 1 : 0;
651
+ motion?.updateCharacteristic(this.hap.Characteristic.MotionDetected, state);
652
+ }
751
653
  if (this.mappingMode === BlindTiltMappingMode.UseTiltForDirection) {
752
654
  this.WindowCovering.CurrentHorizontalTiltAngle = Number(this.WindowCovering.CurrentHorizontalTiltAngle) < 0 ? -90 : 90;
753
655
  }
@@ -770,11 +672,57 @@ export class BlindTilt extends deviceBase {
770
672
  this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
771
673
  this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
772
674
  this.Battery.Service.updateCharacteristic(this.hap.Characteristic.ChargingState, e);
773
- if (!this.device.blindTilt?.hide_lightsensor) {
675
+ if (!this.device.blindTilt?.hide_lightsensor && this.LightSensor?.Service) {
774
676
  this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e);
775
677
  this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.StatusActive, e);
776
678
  }
777
679
  }
680
+ async getCurrentPosttionDirection(direction, slidePosition) {
681
+ const [homekitPosition, homekitTiltAngle] = this.mapDeviceValuesToHomekitValues(Number(slidePosition), String(direction));
682
+ await this.debugLog(`Slide Position: ${slidePosition}`);
683
+ await this.debugLog(`Homekit Position: ${homekitPosition}`);
684
+ this.WindowCovering.CurrentPosition = homekitPosition;
685
+ await this.setMinMax();
686
+ await this.debugLog(`CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
687
+ if (homekitTiltAngle) {
688
+ this.WindowCovering.CurrentHorizontalTiltAngle = homekitTiltAngle;
689
+ await this.debugLog(`CurrentHorizontalTiltAngle: ${this.WindowCovering.CurrentHorizontalTiltAngle}`);
690
+ }
691
+ if (this.setNewTarget) {
692
+ await this.infoLog('Checking Status ...');
693
+ await this.setMinMax();
694
+ if (this.WindowCovering.TargetPosition > this.WindowCovering.CurrentPosition
695
+ || (homekitTiltAngle && this.WindowCovering.TargetHorizontalTiltAngle !== this.WindowCovering.CurrentHorizontalTiltAngle)) {
696
+ await this.debugLog(`Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
697
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
698
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
699
+ await this.debugLog(`Increasing, PositionState: ${this.WindowCovering.PositionState}`);
700
+ }
701
+ else if (this.WindowCovering.TargetPosition < this.WindowCovering.CurrentPosition) {
702
+ await this.debugLog(`Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
703
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
704
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
705
+ await this.debugLog(`Decreasing, PositionState: ${this.WindowCovering.PositionState}`);
706
+ }
707
+ else {
708
+ await this.debugLog(`Standby because reached position, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
709
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
710
+ this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
711
+ await this.debugLog(`Stopped, PositionState: ${this.WindowCovering.PositionState}`);
712
+ }
713
+ }
714
+ else {
715
+ await this.debugLog(`Standby because device not moving, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
716
+ this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition;
717
+ if (homekitTiltAngle) {
718
+ this.WindowCovering.TargetHorizontalTiltAngle = this.WindowCovering.CurrentHorizontalTiltAngle;
719
+ }
720
+ this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
721
+ await this.debugLog(`Stopped, PositionState: ${this.WindowCovering.PositionState}`);
722
+ }
723
+ await this.debugLog(`CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition: ${this.WindowCovering.TargetPosition},`
724
+ + ` PositionState: ${this.WindowCovering.PositionState}`);
725
+ }
778
726
  /**
779
727
  * Maps device values to homekit values
780
728
  *