@switchbot/homebridge-switchbot 0.1.2-beta.7 → 0.2.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/.github/ISSUE_TEMPLATE/feature-request.yml +1 -1
  2. package/.github/dependabot.yml +2 -0
  3. package/.github/workflows/codeql-analysis.yml +71 -0
  4. package/CHANGELOG.md +5 -1
  5. package/README.md +2 -1
  6. package/config.schema.json +420 -471
  7. package/dist/devices/bots.d.ts +19 -5
  8. package/dist/devices/bots.d.ts.map +1 -1
  9. package/dist/devices/bots.js +172 -148
  10. package/dist/devices/bots.js.map +1 -1
  11. package/dist/devices/bulb.d.ts +8 -6
  12. package/dist/devices/bulb.d.ts.map +1 -1
  13. package/dist/devices/bulb.js +45 -28
  14. package/dist/devices/bulb.js.map +1 -1
  15. package/dist/devices/contact.d.ts +10 -5
  16. package/dist/devices/contact.d.ts.map +1 -1
  17. package/dist/devices/contact.js +94 -63
  18. package/dist/devices/contact.js.map +1 -1
  19. package/dist/devices/curtains.d.ts +14 -5
  20. package/dist/devices/curtains.d.ts.map +1 -1
  21. package/dist/devices/curtains.js +174 -120
  22. package/dist/devices/curtains.js.map +1 -1
  23. package/dist/devices/humidifiers.d.ts +6 -6
  24. package/dist/devices/humidifiers.d.ts.map +1 -1
  25. package/dist/devices/humidifiers.js +78 -94
  26. package/dist/devices/humidifiers.js.map +1 -1
  27. package/dist/devices/indoorcam.d.ts +43 -0
  28. package/dist/devices/indoorcam.d.ts.map +1 -0
  29. package/dist/devices/indoorcam.js +241 -0
  30. package/dist/devices/indoorcam.js.map +1 -0
  31. package/dist/devices/meters.d.ts +8 -5
  32. package/dist/devices/meters.d.ts.map +1 -1
  33. package/dist/devices/meters.js +126 -92
  34. package/dist/devices/meters.js.map +1 -1
  35. package/dist/devices/motion.d.ts +9 -5
  36. package/dist/devices/motion.d.ts.map +1 -1
  37. package/dist/devices/motion.js +74 -59
  38. package/dist/devices/motion.js.map +1 -1
  39. package/dist/devices/plugs.d.ts +5 -4
  40. package/dist/devices/plugs.d.ts.map +1 -1
  41. package/dist/devices/plugs.js +65 -56
  42. package/dist/devices/plugs.js.map +1 -1
  43. package/dist/irdevices/airconditioners.d.ts +3 -3
  44. package/dist/irdevices/airconditioners.d.ts.map +1 -1
  45. package/dist/irdevices/airconditioners.js +12 -7
  46. package/dist/irdevices/airconditioners.js.map +1 -1
  47. package/dist/irdevices/airpurifiers.d.ts +3 -3
  48. package/dist/irdevices/airpurifiers.d.ts.map +1 -1
  49. package/dist/irdevices/airpurifiers.js +1 -1
  50. package/dist/irdevices/airpurifiers.js.map +1 -1
  51. package/dist/irdevices/cameras.d.ts +3 -3
  52. package/dist/irdevices/cameras.d.ts.map +1 -1
  53. package/dist/irdevices/cameras.js +1 -1
  54. package/dist/irdevices/cameras.js.map +1 -1
  55. package/dist/irdevices/fans.d.ts +3 -3
  56. package/dist/irdevices/fans.d.ts.map +1 -1
  57. package/dist/irdevices/fans.js +11 -12
  58. package/dist/irdevices/fans.js.map +1 -1
  59. package/dist/irdevices/lights.d.ts +3 -3
  60. package/dist/irdevices/lights.d.ts.map +1 -1
  61. package/dist/irdevices/lights.js +1 -1
  62. package/dist/irdevices/lights.js.map +1 -1
  63. package/dist/irdevices/others.d.ts +3 -3
  64. package/dist/irdevices/others.d.ts.map +1 -1
  65. package/dist/irdevices/others.js +8 -8
  66. package/dist/irdevices/others.js.map +1 -1
  67. package/dist/irdevices/tvs.d.ts +3 -3
  68. package/dist/irdevices/tvs.d.ts.map +1 -1
  69. package/dist/irdevices/tvs.js +16 -6
  70. package/dist/irdevices/tvs.js.map +1 -1
  71. package/dist/irdevices/vacuumcleaners.d.ts +3 -3
  72. package/dist/irdevices/vacuumcleaners.d.ts.map +1 -1
  73. package/dist/irdevices/vacuumcleaners.js +2 -3
  74. package/dist/irdevices/vacuumcleaners.js.map +1 -1
  75. package/dist/irdevices/waterheaters.d.ts +3 -3
  76. package/dist/irdevices/waterheaters.d.ts.map +1 -1
  77. package/dist/irdevices/waterheaters.js +2 -2
  78. package/dist/irdevices/waterheaters.js.map +1 -1
  79. package/dist/platform.d.ts +14 -5
  80. package/dist/platform.d.ts.map +1 -1
  81. package/dist/platform.js +420 -418
  82. package/dist/platform.js.map +1 -1
  83. package/dist/settings.d.ts +18 -15
  84. package/dist/settings.d.ts.map +1 -1
  85. package/package.json +65 -65
  86. package/src/devices/bots.ts +188 -165
  87. package/src/devices/bulb.ts +48 -40
  88. package/src/devices/contact.ts +100 -73
  89. package/src/devices/curtains.ts +192 -140
  90. package/src/devices/humidifiers.ts +82 -124
  91. package/src/devices/indoorcam.ts +303 -0
  92. package/src/devices/meters.ts +130 -110
  93. package/src/devices/motion.ts +80 -69
  94. package/src/devices/plugs.ts +67 -65
  95. package/src/irdevices/airconditioners.ts +14 -10
  96. package/src/irdevices/airpurifiers.ts +4 -4
  97. package/src/irdevices/cameras.ts +4 -4
  98. package/src/irdevices/fans.ts +14 -18
  99. package/src/irdevices/lights.ts +4 -4
  100. package/src/irdevices/others.ts +12 -14
  101. package/src/irdevices/tvs.ts +21 -10
  102. package/src/irdevices/vacuumcleaners.ts +5 -9
  103. package/src/irdevices/waterheaters.ts +5 -5
  104. package/src/platform.ts +455 -619
  105. package/src/settings.ts +19 -15
  106. package/.github/workflows/issue-validate.yml +0 -18
@@ -3,8 +3,7 @@ import { Service, PlatformAccessory, CharacteristicValue, MacAddress } from 'hom
3
3
  import { SwitchBotPlatform } from '../platform';
4
4
  import { interval, Subject } from 'rxjs';
5
5
  import { debounceTime, skipWhile, tap } from 'rxjs/operators';
6
- import { DeviceURL, device, deviceStatusResponse } from '../settings';
7
- import { AxiosResponse } from 'axios';
6
+ import { DeviceURL, device, devicesConfig } from '../settings';
8
7
 
9
8
  export class Curtain {
10
9
  // Services
@@ -18,7 +17,7 @@ export class Curtain {
18
17
  CurrentAmbientLightLevel!: CharacteristicValue;
19
18
 
20
19
  // Others
21
- deviceStatus!: deviceStatusResponse;
20
+ deviceStatus!: any;
22
21
  moveTimer!: NodeJS.Timeout;
23
22
  ScanIntervalId!: NodeJS.Timeout;
24
23
  setNewTargetTimer!: NodeJS.Timeout;
@@ -34,6 +33,8 @@ export class Curtain {
34
33
  PreviousPosition: any;
35
34
  Position: any;
36
35
  FastScanDuration: number | undefined;
36
+ set_minStep!: number;
37
+ refreshRate!: number;
37
38
  switchbot!: {
38
39
  discover: (
39
40
  arg0:
@@ -56,7 +57,7 @@ export class Curtain {
56
57
  constructor(
57
58
  private readonly platform: SwitchBotPlatform,
58
59
  private accessory: PlatformAccessory,
59
- public device: device,
60
+ public device: device & devicesConfig,
60
61
  ) {
61
62
  // default placeholders
62
63
  this.setMinMax();
@@ -64,16 +65,16 @@ export class Curtain {
64
65
  this.TargetPosition = 0;
65
66
  this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
66
67
  this.ScanDuration = this.platform.config.options!.refreshRate!;
67
- if (this.platform.config.options?.ble?.includes(this.device.deviceId!)) {
68
+
69
+ // BLE Connection
70
+ if (device.ble) {
68
71
  // eslint-disable-next-line @typescript-eslint/no-var-requires
69
72
  const SwitchBot = require('node-switchbot');
70
73
  this.switchbot = new SwitchBot();
71
74
  const colon = device.deviceId!.match(/.{1,2}/g);
72
75
  const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
73
76
  this.device.bleMac = bleMac.toLowerCase();
74
- if (this.platform.config.options.debug) {
75
- this.platform.log.warn(this.device.bleMac.toLowerCase());
76
- }
77
+ this.platform.device(this.device.bleMac.toLowerCase());
77
78
  }
78
79
 
79
80
  // this is subject we use to track when we need to POST changes to the SwitchBot API
@@ -88,7 +89,7 @@ export class Curtain {
88
89
  accessory
89
90
  .getService(this.platform.Service.AccessoryInformation)!
90
91
  .setCharacteristic(this.platform.Characteristic.Manufacturer, 'SwitchBot')
91
- .setCharacteristic(this.platform.Characteristic.Model, 'SWITCHBOT-CURTAIN-W0701600')
92
+ .setCharacteristic(this.platform.Characteristic.Model, 'SWITCHBOT-WOCURTAIN-W0701600')
92
93
  .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!);
93
94
 
94
95
  // get the WindowCovering service if it exists, otherwise create a new WindowCovering service
@@ -114,19 +115,19 @@ export class Curtain {
114
115
  this.service
115
116
  .getCharacteristic(this.platform.Characteristic.CurrentPosition)
116
117
  .setProps({
117
- minStep: this.platform.config.options?.curtain?.set_minStep || 1,
118
+ minStep: this.minStep(),
118
119
  minValue: 0,
119
120
  maxValue: 100,
120
121
  validValueRanges: [0, 100],
121
122
  })
122
123
  .onGet(() => {
123
- return this.CurrentPosition;
124
+ return Number.isNaN(this.CurrentPosition);
124
125
  });
125
126
 
126
127
  this.service
127
128
  .getCharacteristic(this.platform.Characteristic.TargetPosition)
128
129
  .setProps({
129
- minStep: this.platform.config.options?.curtain?.set_minStep || 1,
130
+ minStep: this.minStep(),
130
131
  validValueRanges: [0, 100],
131
132
  })
132
133
  .onSet(this.TargetPositionSet.bind(this));
@@ -134,8 +135,8 @@ export class Curtain {
134
135
  //set up brightness level from the builtin sensor as light sensor accessory
135
136
  (this.lightSensorService =
136
137
  accessory.getService(this.platform.Service.LightSensor) ||
137
- accessory.addService(this.platform.Service.LightSensor)), 'Builtin Lightsensor of %s %s', device.deviceName, device.deviceType;
138
- this.lightSensorService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
138
+ accessory.addService(this.platform.Service.LightSensor)), `${device.deviceName} Light Sensor`;
139
+ this.lightSensorService.setCharacteristic(this.platform.Characteristic.Name, `${device.deviceName} Light Sensor`);
139
140
  // handle on / off events using the On characteristic
140
141
  this.lightSensorService.getCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel).onGet(() => {
141
142
  if (this.CurrentAmbientLightLevel === 'bright') {
@@ -157,7 +158,7 @@ export class Curtain {
157
158
  });
158
159
 
159
160
  // update slide progress
160
- interval(this.platform.config.options!.curtain!.refreshRate! * 1000)
161
+ interval(this.curtainRefreshRate() * 1000)
161
162
  .pipe(skipWhile(() => this.curtainUpdateInProgress))
162
163
  .subscribe(() => {
163
164
  if (this.PositionState === this.platform.Characteristic.PositionState.STOPPED) {
@@ -189,39 +190,71 @@ export class Curtain {
189
190
  });
190
191
  }
191
192
 
192
- parseStatus() {
193
- if (this.platform.config.options?.ble?.includes(this.device.deviceId!)) {
194
- this.platform.log.warn('BLE DEVICE-3');
193
+ private curtainRefreshRate() {
194
+ if (this.device?.curtain?.refreshRate) {
195
+ this.refreshRate = this.device?.curtain?.refreshRate;
195
196
  } else {
196
- // CurrentPosition
197
- this.setMinMax();
198
- this.CurrentPosition = 100 - this.deviceStatus.body.slidePosition!;
199
- this.setMinMax();
200
- this.platform.debug(`Curtain ${this.accessory.displayName} CurrentPosition - Device is Currently: ${this.CurrentPosition}`);
201
- if (this.setNewTarget) {
202
- this.platform.log.info(`Checking ${this.accessory.displayName} Status ...`);
197
+ this.refreshRate = 5;
198
+ if (this.platform.config.options?.debug === 'device') {
199
+ this.platform.log.warn('Using Default Curtain Refresh Rate.');
203
200
  }
201
+ }
204
202
 
205
- if (this.deviceStatus.body.moving) {
206
- if (this.TargetPosition > this.CurrentPosition) {
207
- this.platform.debug(`Curtain ${this.accessory.displayName} - Current position: ${this.CurrentPosition} closing`);
208
- this.PositionState = this.platform.Characteristic.PositionState.INCREASING;
209
- } else if (this.TargetPosition < this.CurrentPosition) {
210
- this.platform.debug(`Curtain ${this.accessory.displayName} - Current position: ${this.CurrentPosition} opening`);
211
- this.PositionState = this.platform.Characteristic.PositionState.DECREASING;
212
- } else {
213
- this.platform.debug(`Curtain ${this.CurrentPosition} - standby`);
214
- this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
215
- }
203
+ return this.refreshRate;
204
+ }
205
+
206
+ private minStep(): number | undefined {
207
+ if (this.device.curtain?.set_minStep) {
208
+ this.set_minStep = this.device.curtain?.set_minStep;
209
+ } else {
210
+ this.set_minStep = 1;
211
+ }
212
+ return this.set_minStep;
213
+ }
214
+
215
+ async parseStatus() {
216
+ if (this.device.ble) {
217
+ this.platform.device('BLE');
218
+ await this.BLEparseStatus();
219
+ } else {
220
+ this.platform.device('OpenAPI');
221
+ await this.openAPIparseStatus();
222
+ }
223
+ }
224
+
225
+ private async BLEparseStatus() {
226
+ this.platform.device('Curtains BLE Device parseStatus');
227
+ }
228
+
229
+ private async openAPIparseStatus() {
230
+ this.setMinMax();
231
+ this.CurrentPosition = 100 - this.deviceStatus.body.slidePosition!;
232
+ this.setMinMax();
233
+ this.platform.debug(`Curtain ${this.accessory.displayName} CurrentPosition - Device is Currently: ${this.CurrentPosition}`);
234
+ if (this.setNewTarget) {
235
+ this.platform.log.info(`Checking ${this.accessory.displayName} Status ...`);
236
+ }
237
+
238
+ if (this.deviceStatus.body.moving) {
239
+ if (this.TargetPosition > this.CurrentPosition) {
240
+ this.platform.debug(`Curtain ${this.accessory.displayName} - Current position: ${this.CurrentPosition} closing`);
241
+ this.PositionState = this.platform.Characteristic.PositionState.INCREASING;
242
+ } else if (this.TargetPosition < this.CurrentPosition) {
243
+ this.platform.debug(`Curtain ${this.accessory.displayName} - Current position: ${this.CurrentPosition} opening`);
244
+ this.PositionState = this.platform.Characteristic.PositionState.DECREASING;
216
245
  } else {
217
- this.platform.debug(`Curtain ${this.accessory.displayName} - Current position: ${this.CurrentPosition} standby`);
218
- if (!this.setNewTarget) {
219
- /*If Curtain calibration distance is short, there will be an error between the current percentage and the target percentage.*/
220
- this.TargetPosition = this.CurrentPosition;
221
- this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
222
- }
246
+ this.platform.debug(`Curtain ${this.CurrentPosition} - standby`);
247
+ this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
248
+ }
249
+ } else {
250
+ this.platform.debug(`Curtain ${this.accessory.displayName} - Current position: ${this.CurrentPosition} standby`);
251
+ if (!this.setNewTarget) {
252
+ /*If Curtain calibration distance is short, there will be an error between the current percentage and the target percentage.*/
253
+ this.TargetPosition = this.CurrentPosition;
254
+ this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
223
255
  }
224
256
  }
257
+
225
258
  // Brightness
226
259
  switch (this.deviceStatus.body.brightness) {
227
260
  case 'dim':
@@ -237,136 +270,156 @@ export class Curtain {
237
270
  }
238
271
 
239
272
  async refreshStatus() {
240
- if (this.platform.config.options?.ble?.includes(this.device.deviceId!)) {
241
- this.platform.log.warn('BLE DEVICE-REFRESH-1');
242
- // eslint-disable-next-line @typescript-eslint/no-var-requires
243
- const Switchbot = require('node-switchbot');
244
- const switchbot = new Switchbot();
245
- const colon = this.device.deviceId!.match(/.{1,2}/g);
246
- const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
247
- this.device.bleMac = bleMac.toLowerCase();
248
- if (this.platform.config.options.debug) {
249
- this.platform.log.warn(this.device.bleMac!);
250
- }
251
- switchbot.onadvertisement = (ad: any) => {
252
- this.platform.log.info(JSON.stringify(ad, null, ' '));
253
- this.platform.log.warn('ad:', JSON.stringify(ad));
254
- };
273
+ if (this.device.ble) {
274
+ this.platform.device('BLE');
275
+ await this.BLErefreshStatus();
276
+ } else {
277
+ this.platform.device('OpenAPI');
278
+ await this.openAPIRefreshStatus();
279
+ }
280
+ }
281
+
282
+ private async BLErefreshStatus() {
283
+ this.platform.debug('Curtains BLE Device RefreshStatus');
284
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
285
+ const Switchbot = require('node-switchbot');
286
+ const switchbot = new Switchbot();
287
+ const colon = this.device.deviceId!.match(/.{1,2}/g);
288
+ const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
289
+ this.device.bleMac = bleMac.toLowerCase();
290
+ this.platform.debug(this.device.bleMac!);
291
+ switchbot.onadvertisement = (ad: any) => {
292
+ this.platform.debug(JSON.stringify(ad, null, ' '));
293
+ this.platform.device(`ad: ${JSON.stringify(ad)}`);
294
+ };
295
+ this.parseStatus();
296
+ this.updateHomeKitCharacteristics();
297
+ switchbot
298
+ .startScan({
299
+ id: this.device.bleMac,
300
+ })
301
+ .then(() => {
302
+ return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
303
+ })
304
+ .then(() => {
305
+ switchbot.stopScan();
306
+ })
307
+ .catch(async (error: any) => {
308
+ this.platform.log.error(error);
309
+ await this.openAPIRefreshStatus();
310
+ });
311
+ setInterval(() => {
312
+ this.platform.log.info('Start scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
255
313
  switchbot
256
314
  .startScan({
257
- id: this.device.bleMac,
315
+ mode: 'T',
316
+ id: bleMac,
258
317
  })
259
318
  .then(() => {
260
319
  return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
261
320
  })
262
321
  .then(() => {
263
322
  switchbot.stopScan();
323
+ this.platform.log.info('Stop scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
264
324
  })
265
325
  .catch(async (error: any) => {
266
326
  this.platform.log.error(error);
267
327
  await this.openAPIRefreshStatus();
268
328
  });
269
- setInterval(() => {
270
- this.platform.log.info('Start scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
271
- switchbot
272
- .startScan({
273
- mode: 'T',
274
- id: bleMac,
275
- })
276
- .then(() => {
277
- return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
278
- })
279
- .then(() => {
280
- switchbot.stopScan();
281
- this.platform.log.info('Stop scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
282
- })
283
- .catch(async (error: any) => {
284
- this.platform.log.error(error);
285
- await this.openAPIRefreshStatus();
286
- });
287
- }, this.platform.config.options!.refreshRate! * 60000);
288
- } else {
289
- await this.openAPIRefreshStatus();
290
- }
329
+ }, this.platform.config.options!.refreshRate! * 60000);
291
330
  }
292
331
 
293
332
  private async openAPIRefreshStatus() {
294
333
  try {
295
- this.platform.debug('Curtain - Reading', `${DeviceURL}/${this.device.deviceId}/status`);
296
- const deviceStatus: deviceStatusResponse = (
297
- await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)
298
- ).data;
299
- if (deviceStatus.message === 'success') {
300
- this.deviceStatus = deviceStatus;
301
- this.platform.debug(`Curtain ${this.accessory.displayName} refreshStatus - ${JSON.stringify(this.deviceStatus)}`);
302
- this.setMinMax();
303
- this.parseStatus();
304
- this.updateHomeKitCharacteristics();
305
- }
334
+ this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
335
+ this.platform.debug(`Curtain ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
336
+ this.setMinMax();
337
+ this.parseStatus();
338
+ this.updateHomeKitCharacteristics();
306
339
  } catch (e: any) {
307
- this.platform.log.error(
308
- `Curtain - Failed to refresh status of ${this.device.deviceName}`,
309
- JSON.stringify(e.message),
310
- this.platform.debug(`Curtain ${this.accessory.displayName} - ${JSON.stringify(e)}`),
311
- );
340
+ this.platform.log.error(`Curtain ${this.accessory.displayName} failed to refresh status, Eror Message ${JSON.stringify(e.message)}`);
341
+ this.platform.debug(`Curtain ${this.accessory.displayName}, Error: ${JSON.stringify(e)}`);
312
342
  this.apiError(e);
313
343
  }
314
344
  }
315
345
 
316
346
  async pushChanges() {
317
- if (this.platform.config.options?.ble?.includes(this.device.deviceId!)) {
318
- this.platform.log.warn('BLE DEVICE-2');
347
+ if (this.device.ble) {
348
+ this.platform.device('BLE');
349
+ await this.BLEpushChanges();
319
350
  } else {
320
- if (this.TargetPosition !== this.CurrentPosition) {
321
- this.platform.debug(`Pushing ${this.TargetPosition}`);
322
- const adjustedTargetPosition = 100 - Number(this.TargetPosition);
323
- const payload = {
324
- commandType: 'command',
325
- command: 'setPosition',
326
- parameter: `0,ff,${adjustedTargetPosition}`,
327
- } as any;
328
-
329
- this.platform.log.info(
330
- 'Sending request for',
331
- this.accessory.displayName,
332
- 'to SwitchBot API. command:',
333
- payload.command,
334
- 'parameter:',
335
- payload.parameter,
336
- 'commandType:',
337
- payload.commandType,
338
- );
339
- this.platform.debug(`Curtain ${this.accessory.displayName} pushChanges - ${JSON.stringify(payload)}`);
340
-
341
- // Make the API request
342
- const push = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
343
- this.platform.debug(`Curtain ${this.accessory.displayName} Changes pushed - ${push.data}`);
344
- this.statusCode(push);
345
- }
351
+ this.platform.device('OpenAPI');
352
+ await this.OpenAPIpushChanges();
353
+ }
354
+ }
355
+
356
+ private async BLEpushChanges() {
357
+ this.platform.device('Curtains BLE Device pushChanges');
358
+ }
359
+
360
+ private async OpenAPIpushChanges() {
361
+ if (this.TargetPosition !== this.CurrentPosition) {
362
+ this.platform.debug(`Pushing ${this.TargetPosition}`);
363
+ const adjustedTargetPosition = 100 - Number(this.TargetPosition);
364
+ const payload = {
365
+ commandType: 'command',
366
+ command: 'setPosition',
367
+ parameter: `0,ff,${adjustedTargetPosition}`,
368
+ } as any;
369
+
370
+ this.platform.log.info(
371
+ 'Sending request for',
372
+ this.accessory.displayName,
373
+ 'to SwitchBot API. command:',
374
+ payload.command,
375
+ 'parameter:',
376
+ payload.parameter,
377
+ 'commandType:',
378
+ payload.commandType,
379
+ );
380
+ this.platform.debug(`Curtain ${this.accessory.displayName} pushchanges: ${JSON.stringify(payload)}`);
381
+
382
+ // Make the API request
383
+ this.platform.log.error(this.device.deviceId!);
384
+ const push: any = (await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId!}/commands`, payload));
385
+ this.platform.debug(`Curtain ${this.accessory.displayName} Changes pushed: ${JSON.stringify(push.data)}`);
386
+ this.statusCode(push);
346
387
  }
347
388
  }
348
389
 
349
390
  updateHomeKitCharacteristics() {
350
391
  this.platform.debug(
351
392
  `Curtain ${this.accessory.displayName} updateHomeKitCharacteristics - ${JSON.stringify({
352
- CurrentPosition: this.CurrentPosition,
393
+ CurrentPosition: Number.isNaN(this.CurrentPosition),
353
394
  PositionState: this.PositionState,
354
- TargetPosition: this.TargetPosition,
395
+ TargetPosition: Number.isNaN(this.TargetPosition),
355
396
  CurrentAmbientLightLevel: this.CurrentAmbientLightLevel,
356
397
  })}`,
357
398
  );
358
399
  this.setMinMax();
359
- if (this.CurrentPosition !== undefined) {
360
- this.service.updateCharacteristic(this.platform.Characteristic.CurrentPosition, this.CurrentPosition);
400
+ if (this.CurrentPosition === undefined) {
401
+ this.platform.debug(`Curtain ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
402
+ } else {
403
+ this.service.updateCharacteristic(this.platform.Characteristic.CurrentPosition, Number.isNaN(this.CurrentPosition));
404
+ this.platform.device(`Curtain ${this.accessory.displayName} updateCharacteristic CurrentPosition: ${this.CurrentPosition}`);
361
405
  }
362
- if (this.PositionState !== undefined) {
406
+ if (this.PositionState === undefined) {
407
+ this.platform.debug(`Curtain ${this.accessory.displayName} PositionState: ${this.PositionState}`);
408
+ } else {
363
409
  this.service.updateCharacteristic(this.platform.Characteristic.PositionState, this.PositionState);
410
+ this.platform.device(`Curtain ${this.accessory.displayName} updateCharacteristic PositionState: ${this.PositionState}`);
364
411
  }
365
- if (this.TargetPosition !== undefined) {
366
- this.service.updateCharacteristic(this.platform.Characteristic.TargetPosition, this.TargetPosition);
412
+ if (this.TargetPosition === undefined) {
413
+ this.platform.debug(`Curtain ${this.accessory.displayName} TargetPosition: ${this.TargetPosition}`);
414
+ } else {
415
+ this.service.updateCharacteristic(this.platform.Characteristic.TargetPosition, Number.isNaN(this.TargetPosition));
416
+ this.platform.device(`Curtain ${this.accessory.displayName} updateCharacteristic TargetPosition: ${this.TargetPosition}`);
367
417
  }
368
- if (this.CurrentAmbientLightLevel !== undefined) {
418
+ if (this.CurrentAmbientLightLevel === undefined) {
419
+ this.platform.debug(`Curtain ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
420
+ } else {
369
421
  this.lightSensorService.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
422
+ this.platform.device(`Curtain ${this.accessory.displayName} updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
370
423
  }
371
424
  }
372
425
 
@@ -374,11 +427,10 @@ export class Curtain {
374
427
  this.service.updateCharacteristic(this.platform.Characteristic.CurrentPosition, e);
375
428
  this.service.updateCharacteristic(this.platform.Characteristic.PositionState, e);
376
429
  this.service.updateCharacteristic(this.platform.Characteristic.TargetPosition, e);
377
- this.service.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, e);
430
+ this.lightSensorService.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, e);
378
431
  }
379
432
 
380
-
381
- private statusCode(push: AxiosResponse<any>) {
433
+ private statusCode(push: { data: { statusCode: any; }; }) {
382
434
  switch (push.data.statusCode) {
383
435
  case 151:
384
436
  this.platform.log.error('Command not supported by this device type.');
@@ -410,7 +462,7 @@ export class Curtain {
410
462
  * Handle requests to set the value of the "Target Position" characteristic
411
463
  */
412
464
  TargetPositionSet(value: CharacteristicValue) {
413
- if (this.platform.config.options?.ble?.includes(this.device.deviceId!)) {
465
+ if (this.device.ble) {
414
466
  this.TargetPosition = value as number;
415
467
  this.platform.log.info('Target position of Curtain setting: ' + this.TargetPosition + '%');
416
468
  clearTimeout(this.moveTimer);
@@ -622,13 +674,13 @@ export class Curtain {
622
674
  }
623
675
 
624
676
  public setMinMax() {
625
- if (this.platform.config.options?.curtain?.set_min) {
626
- if (this.CurrentPosition <= this.platform.config.options?.curtain?.set_min) {
677
+ if (this.device.curtain?.set_min) {
678
+ if (this.CurrentPosition <= this.device.curtain?.set_min) {
627
679
  this.CurrentPosition = 0;
628
680
  }
629
681
  }
630
- if (this.platform.config.options?.curtain?.set_max) {
631
- if (this.CurrentPosition >= this.platform.config.options?.curtain?.set_max) {
682
+ if (this.device.curtain?.set_max) {
683
+ if (this.CurrentPosition >= this.device.curtain?.set_max) {
632
684
  this.CurrentPosition = 100;
633
685
  }
634
686
  }