@switchbot/homebridge-switchbot 0.1.2-beta.0 → 0.1.2-beta.12

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 (90) hide show
  1. package/.github/ISSUE_TEMPLATE/bug-report.yml +1 -1
  2. package/.github/ISSUE_TEMPLATE/config.yml +6 -6
  3. package/.github/ISSUE_TEMPLATE/support-request.yml +1 -1
  4. package/.github/PULL_REQUEST_TEMPLATE/pull_requests.md +26 -6
  5. package/.github/dependabot.yml +2 -0
  6. package/.github/workflows/codeql-analysis.yml +71 -0
  7. package/.github/workflows/issue-validate.yml +3 -3
  8. package/.github/workflows/nodejs-beta.yml +4 -4
  9. package/.github/workflows/nodejs.yml +4 -4
  10. package/CHANGELOG.md +5 -1
  11. package/config.schema.json +18 -15
  12. package/dist/devices/bots.d.ts +1 -0
  13. package/dist/devices/bots.d.ts.map +1 -1
  14. package/dist/devices/bots.js +72 -24
  15. package/dist/devices/bots.js.map +1 -1
  16. package/dist/devices/bulb.d.ts +10 -1
  17. package/dist/devices/bulb.d.ts.map +1 -1
  18. package/dist/devices/bulb.js +13 -2
  19. package/dist/devices/bulb.js.map +1 -1
  20. package/dist/devices/contact.d.ts +13 -3
  21. package/dist/devices/contact.d.ts.map +1 -1
  22. package/dist/devices/contact.js +78 -3
  23. package/dist/devices/contact.js.map +1 -1
  24. package/dist/devices/curtains.d.ts +19 -8
  25. package/dist/devices/curtains.d.ts.map +1 -1
  26. package/dist/devices/curtains.js +98 -21
  27. package/dist/devices/curtains.js.map +1 -1
  28. package/dist/devices/humidifiers.d.ts.map +1 -1
  29. package/dist/devices/humidifiers.js +4 -4
  30. package/dist/devices/humidifiers.js.map +1 -1
  31. package/dist/devices/indoorcam.d.ts +42 -0
  32. package/dist/devices/indoorcam.d.ts.map +1 -0
  33. package/dist/devices/indoorcam.js +235 -0
  34. package/dist/devices/indoorcam.js.map +1 -0
  35. package/dist/devices/meters.d.ts +13 -4
  36. package/dist/devices/meters.d.ts.map +1 -1
  37. package/dist/devices/meters.js +36 -17
  38. package/dist/devices/meters.js.map +1 -1
  39. package/dist/devices/motion.d.ts +11 -3
  40. package/dist/devices/motion.d.ts.map +1 -1
  41. package/dist/devices/motion.js +70 -8
  42. package/dist/devices/motion.js.map +1 -1
  43. package/dist/devices/plugs.d.ts +11 -1
  44. package/dist/devices/plugs.d.ts.map +1 -1
  45. package/dist/devices/plugs.js +67 -1
  46. package/dist/devices/plugs.js.map +1 -1
  47. package/dist/irdevices/airconditioners.js +2 -2
  48. package/dist/irdevices/airconditioners.js.map +1 -1
  49. package/dist/irdevices/airpurifiers.js +2 -2
  50. package/dist/irdevices/airpurifiers.js.map +1 -1
  51. package/dist/irdevices/cameras.js +1 -1
  52. package/dist/irdevices/cameras.js.map +1 -1
  53. package/dist/irdevices/fans.js +1 -1
  54. package/dist/irdevices/fans.js.map +1 -1
  55. package/dist/irdevices/lights.js +3 -3
  56. package/dist/irdevices/lights.js.map +1 -1
  57. package/dist/irdevices/others.js +1 -1
  58. package/dist/irdevices/others.js.map +1 -1
  59. package/dist/irdevices/tvs.d.ts.map +1 -1
  60. package/dist/irdevices/tvs.js +2 -3
  61. package/dist/irdevices/tvs.js.map +1 -1
  62. package/dist/irdevices/vacuumcleaners.js +1 -1
  63. package/dist/irdevices/vacuumcleaners.js.map +1 -1
  64. package/dist/platform.d.ts +1 -0
  65. package/dist/platform.d.ts.map +1 -1
  66. package/dist/platform.js +104 -93
  67. package/dist/platform.js.map +1 -1
  68. package/dist/settings.d.ts +1 -2
  69. package/dist/settings.d.ts.map +1 -1
  70. package/package.json +9 -9
  71. package/src/devices/bots.ts +87 -37
  72. package/src/devices/bulb.ts +33 -3
  73. package/src/devices/contact.ts +102 -10
  74. package/src/devices/curtains.ts +137 -37
  75. package/src/devices/humidifiers.ts +9 -4
  76. package/src/devices/indoorcam.ts +304 -0
  77. package/src/devices/meters.ts +58 -22
  78. package/src/devices/motion.ts +93 -13
  79. package/src/devices/plugs.ts +89 -4
  80. package/src/irdevices/airconditioners.ts +2 -2
  81. package/src/irdevices/airpurifiers.ts +2 -2
  82. package/src/irdevices/cameras.ts +1 -1
  83. package/src/irdevices/fans.ts +1 -1
  84. package/src/irdevices/lights.ts +3 -3
  85. package/src/irdevices/others.ts +1 -1
  86. package/src/irdevices/tvs.ts +2 -4
  87. package/src/irdevices/vacuumcleaners.ts +1 -1
  88. package/src/platform.ts +120 -95
  89. package/src/settings.ts +1 -2
  90. package/.github/ISSUE_TEMPLATE.md +0 -48
@@ -1,4 +1,4 @@
1
- import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
1
+ import { Service, PlatformAccessory, CharacteristicValue, MacAddress } from 'homebridge';
2
2
  import { SwitchBotPlatform } from '../platform';
3
3
  import { interval, Subject } from 'rxjs';
4
4
  import { skipWhile } from 'rxjs/operators';
@@ -10,13 +10,32 @@ import { DeviceURL, device, deviceStatusResponse } from '../settings';
10
10
  * Each accessory may expose multiple services of different service types.
11
11
  */
12
12
  export class Contact {
13
+ // Services
13
14
  private service: Service;
14
- temperatureservice?: Service;
15
- humidityservice?: Service;
15
+ motionService: Service;
16
16
 
17
+ // Characteristic Values
17
18
  ContactSensorState!: CharacteristicValue;
18
- deviceStatus!: deviceStatusResponse;
19
+ MotionDetected!: CharacteristicValue;
19
20
 
21
+ // Others
22
+ deviceStatus!: deviceStatusResponse;
23
+ switchbot!: {
24
+ discover: (
25
+ arg0:
26
+ {
27
+ duration: any;
28
+ model: string;
29
+ quick: boolean;
30
+ id: MacAddress;
31
+ }
32
+ ) => Promise<any>;
33
+ wait: (
34
+ arg0: number
35
+ ) => any;
36
+ };
37
+
38
+ // Updates
20
39
  contactUbpdateInProgress!: boolean;
21
40
  doContactUpdate;
22
41
 
@@ -27,7 +46,17 @@ export class Contact {
27
46
  ) {
28
47
  // default placeholders
29
48
  this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
30
-
49
+ if (this.platform.config.options?.ble?.includes(this.device.deviceId!)) {
50
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
51
+ const SwitchBot = require('node-switchbot');
52
+ this.switchbot = new SwitchBot();
53
+ const colon = device.deviceId!.match(/.{1,2}/g);
54
+ const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
55
+ this.device.bleMac = bleMac.toLowerCase();
56
+ if (this.platform.config.options.debug === 'device') {
57
+ this.platform.debug(this.device.bleMac.toLowerCase());
58
+ }
59
+ }
31
60
  // this is subject we use to track when we need to POST changes to the SwitchBot API
32
61
  this.doContactUpdate = new Subject();
33
62
  this.contactUbpdateInProgress = false;
@@ -39,14 +68,14 @@ export class Contact {
39
68
  accessory
40
69
  .getService(this.platform.Service.AccessoryInformation)!
41
70
  .setCharacteristic(this.platform.Characteristic.Manufacturer, 'SwitchBot')
42
- .setCharacteristic(this.platform.Characteristic.Model, 'SWITCHBOT-CONTACT-')
71
+ .setCharacteristic(this.platform.Characteristic.Model, 'SWITCHBOT-CONTACT-W1201500')
43
72
  .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId);
44
73
 
45
74
  // get the Battery service if it exists, otherwise create a new Contact service
46
75
  // you can create multiple services for each accessory
47
76
  (this.service =
48
77
  accessory.getService(this.platform.Service.ContactSensor) ||
49
- accessory.addService(this.platform.Service.ContactSensor)), '%s %s', device.deviceName, device.deviceType;
78
+ accessory.addService(this.platform.Service.ContactSensor)), `${device.deviceName} ${device.deviceType}`;
50
79
 
51
80
  // To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
52
81
  // when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
@@ -57,7 +86,10 @@ export class Contact {
57
86
  this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
58
87
 
59
88
  // each service must implement at-minimum the "required characteristics" for the given service type
60
- // see https://developers.homebridge.io/#/service/ContactSensor
89
+ // see https://developers.homebridge.io/#/service/MotionSensor
90
+ (this.motionService =
91
+ accessory.getService(this.platform.Service.MotionSensor) ||
92
+ accessory.addService(this.platform.Service.MotionSensor)), `${device.deviceName} ${device.deviceType}`;
61
93
 
62
94
  // create handlers for required characteristics
63
95
  //this.service.setCharacteristic(this.platform.Characteristic.ChargingState, 2);
@@ -83,12 +115,69 @@ export class Contact {
83
115
  } else {
84
116
  this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
85
117
  }
118
+ this.MotionDetected = Boolean(this.deviceStatus.body.moveDetected);
119
+ this.platform.debug(`${this.accessory.displayName}
120
+ , ContactSensorState: ${this.ContactSensorState}, MotionDetected: ${this.MotionDetected}`);
86
121
  }
87
122
 
88
123
  /**
89
124
  * Asks the SwitchBot API for the latest device information
90
125
  */
91
126
  async refreshStatus() {
127
+ if (this.platform.config.options?.ble?.includes(this.device.deviceId!)) {
128
+ this.platform.debug('Contact BLE Device RefreshStatus');
129
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
130
+ const Switchbot = require('node-switchbot');
131
+ const switchbot = new Switchbot();
132
+ const colon = this.device.deviceId!.match(/.{1,2}/g);
133
+ const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
134
+ this.device.bleMac = bleMac.toLowerCase();
135
+ if (this.platform.config.options.debug === 'device') {
136
+ this.platform.debug(this.device.bleMac!);
137
+ }
138
+ switchbot.onadvertisement = (ad: any) => {
139
+ this.platform.log.info(JSON.stringify(ad, null, ' '));
140
+ this.platform.log.warn('ad:', JSON.stringify(ad));
141
+ };
142
+ switchbot
143
+ .startScan({
144
+ id: this.device.bleMac,
145
+ })
146
+ .then(() => {
147
+ return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
148
+ })
149
+ .then(() => {
150
+ switchbot.stopScan();
151
+ })
152
+ .catch(async (error: any) => {
153
+ this.platform.log.error(error);
154
+ await this.openAPIRefreshStatus();
155
+ });
156
+ setInterval(() => {
157
+ this.platform.log.info('Start scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
158
+ switchbot
159
+ .startScan({
160
+ mode: 'D',
161
+ id: bleMac,
162
+ })
163
+ .then(() => {
164
+ return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
165
+ })
166
+ .then(() => {
167
+ switchbot.stopScan();
168
+ this.platform.log.info('Stop scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
169
+ })
170
+ .catch(async (error: any) => {
171
+ this.platform.log.error(error);
172
+ await this.openAPIRefreshStatus();
173
+ });
174
+ }, this.platform.config.options!.refreshRate! * 60000);
175
+ } else {
176
+ await this.openAPIRefreshStatus();
177
+ }
178
+ }
179
+
180
+ private async openAPIRefreshStatus() {
92
181
  try {
93
182
  const deviceStatus: deviceStatusResponse = (
94
183
  await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)
@@ -105,8 +194,7 @@ export class Contact {
105
194
  'Contact - Failed to update status of',
106
195
  this.device.deviceName,
107
196
  JSON.stringify(e.message),
108
- this.platform.debug(`Contact ${this.accessory.displayName} - ${JSON.stringify(e)}`),
109
- );
197
+ this.platform.debug(`Contact ${this.accessory.displayName} - ${JSON.stringify(e)}`));
110
198
  this.apiError(e);
111
199
  }
112
200
  }
@@ -118,9 +206,13 @@ export class Contact {
118
206
  if (this.ContactSensorState !== undefined) {
119
207
  this.service.updateCharacteristic(this.platform.Characteristic.ContactSensorState, this.ContactSensorState);
120
208
  }
209
+ if (this.MotionDetected !== undefined) {
210
+ this.motionService.updateCharacteristic(this.platform.Characteristic.MotionDetected, this.MotionDetected);
211
+ }
121
212
  }
122
213
 
123
214
  public apiError(e: any) {
124
215
  this.service.updateCharacteristic(this.platform.Characteristic.ContactSensorState, e);
216
+ this.motionService.updateCharacteristic(this.platform.Characteristic.MotionDetected, e);
125
217
  }
126
218
  }
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable @typescript-eslint/no-var-requires */
2
- import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
2
+ import { Service, PlatformAccessory, CharacteristicValue, MacAddress } from 'homebridge';
3
3
  import { SwitchBotPlatform } from '../platform';
4
4
  import { interval, Subject } from 'rxjs';
5
5
  import { debounceTime, skipWhile, tap } from 'rxjs/operators';
@@ -7,31 +7,51 @@ import { DeviceURL, device, deviceStatusResponse } from '../settings';
7
7
  import { AxiosResponse } from 'axios';
8
8
 
9
9
  export class Curtain {
10
+ // Services
10
11
  private service: Service;
12
+ private lightSensorService: Service;
11
13
 
14
+ // Characteristic Values
12
15
  CurrentPosition!: CharacteristicValue;
13
16
  PositionState!: CharacteristicValue;
14
17
  TargetPosition!: CharacteristicValue;
15
- deviceStatus!: deviceStatusResponse;
16
- setNewTarget!: boolean;
17
- setNewTargetTimer!: NodeJS.Timeout;
18
+ CurrentAmbientLightLevel!: CharacteristicValue;
18
19
 
19
- curtainUpdateInProgress!: boolean;
20
- doCurtainUpdate;
21
- switchbot;
20
+ // Others
21
+ deviceStatus!: deviceStatusResponse;
22
22
  moveTimer!: NodeJS.Timeout;
23
+ ScanIntervalId!: NodeJS.Timeout;
24
+ setNewTargetTimer!: NodeJS.Timeout;
25
+ AutoDisableFastScanTimeoutId!: NodeJS.Timeout;
26
+ setNewTarget!: boolean;
23
27
  moveTime!: number;
24
28
  ScanDuration: any;
25
29
  ReverseDir: any;
26
30
  FastScanEnabled!: boolean;
27
- ScanIntervalId!: NodeJS.Timeout;
28
31
  FastScanInterval!: number;
29
32
  SlowScanInterval!: number;
30
33
  OpenCloseThreshold: any;
31
34
  PreviousPosition: any;
32
35
  Position: any;
33
- AutoDisableFastScanTimeoutId;
34
36
  FastScanDuration: number | undefined;
37
+ switchbot!: {
38
+ discover: (
39
+ arg0:
40
+ {
41
+ duration: any;
42
+ model: string;
43
+ quick: boolean;
44
+ id: MacAddress;
45
+ }
46
+ ) => Promise<any>;
47
+ wait: (
48
+ arg0: number
49
+ ) => any;
50
+ };
51
+
52
+ // Updates
53
+ curtainUpdateInProgress!: boolean;
54
+ doCurtainUpdate;
35
55
 
36
56
  constructor(
37
57
  private readonly platform: SwitchBotPlatform,
@@ -51,8 +71,8 @@ export class Curtain {
51
71
  const colon = device.deviceId!.match(/.{1,2}/g);
52
72
  const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
53
73
  this.device.bleMac = bleMac.toLowerCase();
54
- if (this.platform.config.options.debug) {
55
- this.platform.log.warn(this.device.bleMac.toLowerCase());
74
+ if (this.platform.config.options.debug === 'device') {
75
+ this.platform.debug(this.device.bleMac.toLowerCase());
56
76
  }
57
77
  }
58
78
 
@@ -75,7 +95,7 @@ export class Curtain {
75
95
  // you can create multiple services for each accessory
76
96
  (this.service =
77
97
  accessory.getService(this.platform.Service.WindowCovering) ||
78
- accessory.addService(this.platform.Service.WindowCovering)), '%s %s', device.deviceName, device.deviceType;
98
+ accessory.addService(this.platform.Service.WindowCovering)), `${device.deviceName} ${device.deviceType}`;
79
99
 
80
100
  // To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
81
101
  // when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
@@ -111,6 +131,21 @@ export class Curtain {
111
131
  })
112
132
  .onSet(this.TargetPositionSet.bind(this));
113
133
 
134
+ //set up brightness level from the builtin sensor as light sensor accessory
135
+ (this.lightSensorService =
136
+ 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);
139
+ // handle on / off events using the On characteristic
140
+ this.lightSensorService.getCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel).onGet(() => {
141
+ if (this.CurrentAmbientLightLevel === 'bright') {
142
+ return 100000;
143
+ } else {
144
+ return 0.0001;
145
+ }
146
+ });
147
+
148
+
114
149
  // Update Homekit
115
150
  this.updateHomeKitCharacteristics();
116
151
 
@@ -187,35 +222,94 @@ export class Curtain {
187
222
  }
188
223
  }
189
224
  }
225
+ // Brightness
226
+ switch (this.deviceStatus.body.brightness) {
227
+ case 'dim':
228
+ this.CurrentAmbientLightLevel = 0.0001;
229
+ break;
230
+ default:
231
+ this.CurrentAmbientLightLevel = 100000;
232
+ }
190
233
  this.platform.debug(
191
- `Curtain ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},
192
- TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState}`);
234
+ `Curtain ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}
235
+ , TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState}
236
+ , CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
193
237
  }
194
238
 
195
239
  async refreshStatus() {
196
240
  if (this.platform.config.options?.ble?.includes(this.device.deviceId!)) {
197
- this.platform.log.warn('BLE DEVICE-1');
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 === 'device') {
249
+ this.platform.debug(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
+ };
255
+ switchbot
256
+ .startScan({
257
+ id: this.device.bleMac,
258
+ })
259
+ .then(() => {
260
+ return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
261
+ })
262
+ .then(() => {
263
+ switchbot.stopScan();
264
+ })
265
+ .catch(async (error: any) => {
266
+ this.platform.log.error(error);
267
+ await this.openAPIRefreshStatus();
268
+ });
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);
198
288
  } else {
199
- try {
200
- this.platform.debug('Curtain - Reading', `${DeviceURL}/${this.device.deviceId}/status`);
201
- const deviceStatus: deviceStatusResponse = (
202
- await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)
203
- ).data;
204
- if (deviceStatus.message === 'success') {
205
- this.deviceStatus = deviceStatus;
206
- this.platform.debug(`Curtain ${this.accessory.displayName} refreshStatus - ${JSON.stringify(this.deviceStatus)}`);
207
- this.setMinMax();
208
- this.parseStatus();
209
- this.updateHomeKitCharacteristics();
210
- }
211
- } catch (e: any) {
212
- this.platform.log.error(
213
- `Curtain - Failed to refresh status of ${this.device.deviceName}`,
214
- JSON.stringify(e.message),
215
- this.platform.debug(`Curtain ${this.accessory.displayName} - ${JSON.stringify(e)}`),
216
- );
217
- this.apiError(e);
289
+ await this.openAPIRefreshStatus();
290
+ }
291
+ }
292
+
293
+ private async openAPIRefreshStatus() {
294
+ 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();
218
305
  }
306
+ } 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
+ );
312
+ this.apiError(e);
219
313
  }
220
314
  }
221
315
 
@@ -258,7 +352,9 @@ export class Curtain {
258
352
  CurrentPosition: this.CurrentPosition,
259
353
  PositionState: this.PositionState,
260
354
  TargetPosition: this.TargetPosition,
261
- })}`);
355
+ CurrentAmbientLightLevel: this.CurrentAmbientLightLevel,
356
+ })}`,
357
+ );
262
358
  this.setMinMax();
263
359
  if (this.CurrentPosition !== undefined) {
264
360
  this.service.updateCharacteristic(this.platform.Characteristic.CurrentPosition, this.CurrentPosition);
@@ -269,12 +365,16 @@ export class Curtain {
269
365
  if (this.TargetPosition !== undefined) {
270
366
  this.service.updateCharacteristic(this.platform.Characteristic.TargetPosition, this.TargetPosition);
271
367
  }
368
+ if (this.CurrentAmbientLightLevel !== undefined) {
369
+ this.lightSensorService.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
370
+ }
272
371
  }
273
372
 
274
373
  public apiError(e: any) {
275
374
  this.service.updateCharacteristic(this.platform.Characteristic.CurrentPosition, e);
276
375
  this.service.updateCharacteristic(this.platform.Characteristic.PositionState, e);
277
376
  this.service.updateCharacteristic(this.platform.Characteristic.TargetPosition, e);
377
+ this.service.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, e);
278
378
  }
279
379
 
280
380
 
@@ -406,7 +506,7 @@ export class Curtain {
406
506
  * Ask the device to start moving to the given position (which must be a device value and not an HomeKit value).
407
507
  * Returns a Promise that's resolved as soon as the command was sent to the device.
408
508
  */
409
- public runToPosition(pos: number): Promise<void> {
509
+ public async runToPosition(pos: number): Promise<void> {
410
510
  const SwitchBot = require('node-switchbot');
411
511
  const switchbot = new SwitchBot();
412
512
 
@@ -533,4 +633,4 @@ export class Curtain {
533
633
  }
534
634
  }
535
635
  }
536
- }
636
+ }
@@ -11,9 +11,11 @@ import { AxiosResponse } from 'axios';
11
11
  * Each accessory may expose multiple services of different service types.
12
12
  */
13
13
  export class Humidifier {
14
+ // Services
14
15
  private service: Service;
15
16
  temperatureservice?: Service;
16
17
 
18
+ // Characteristic Values
17
19
  CurrentRelativeHumidity!: CharacteristicValue;
18
20
  CurrentTemperature!: CharacteristicValue;
19
21
  TargetHumidifierDehumidifierState!: CharacteristicValue;
@@ -21,8 +23,11 @@ export class Humidifier {
21
23
  RelativeHumidityHumidifierThreshold!: CharacteristicValue;
22
24
  Active!: CharacteristicValue;
23
25
  WaterLevel!: CharacteristicValue;
26
+
27
+ // Others
24
28
  deviceStatus!: deviceStatusResponse;
25
29
 
30
+ // Updates
26
31
  humidifierUpdateInProgress!: boolean;
27
32
  doHumidifierUpdate;
28
33
 
@@ -58,7 +63,7 @@ export class Humidifier {
58
63
  // you can create multiple services for each accessory
59
64
  (this.service =
60
65
  accessory.getService(this.platform.Service.HumidifierDehumidifier) ||
61
- accessory.addService(this.platform.Service.HumidifierDehumidifier)), '%s %s', device.deviceName, device.deviceType;
66
+ accessory.addService(this.platform.Service.HumidifierDehumidifier)), `${device.deviceName} ${device.deviceType}`;
62
67
 
63
68
  // To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
64
69
  // when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
@@ -102,18 +107,18 @@ export class Humidifier {
102
107
  // create a new Temperature Sensor service
103
108
  // Temperature Sensor Service
104
109
  if (this.platform.config.options?.humidifier?.hide_temperature) {
105
- if (this.platform.config.options.debug) {
110
+ if (this.platform.config.options.debug === 'device') {
106
111
  this.platform.log.error('Removing service');
107
112
  }
108
113
  this.temperatureservice = this.accessory.getService(this.platform.Service.TemperatureSensor);
109
114
  accessory.removeService(this.temperatureservice!);
110
115
  } else if (!this.temperatureservice) {
111
- if (this.platform.config.options?.debug) {
116
+ if (this.platform.config.options?.debug === 'device') {
112
117
  this.platform.log.warn('Adding service');
113
118
  }
114
119
  (this.temperatureservice =
115
120
  this.accessory.getService(this.platform.Service.TemperatureSensor) ||
116
- this.accessory.addService(this.platform.Service.TemperatureSensor)), '%s %s TemperatureSensor', device.deviceName, device.deviceType;
121
+ this.accessory.addService(this.platform.Service.TemperatureSensor)), `${device.deviceName} ${device.deviceType} TemperatureSensor`;
117
122
 
118
123
  this.temperatureservice
119
124
  .getCharacteristic(this.platform.Characteristic.CurrentTemperature)