@switchbot/homebridge-switchbot 0.2.0-alpha.2 → 1.0.1-beta.2

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 (99) hide show
  1. package/.github/workflows/nodejs-beta.yml +1 -1
  2. package/.github/workflows/nodejs.yml +1 -1
  3. package/.github/workflows/{prerelease.js → prerelease-beta.js} +0 -0
  4. package/CHANGELOG.md +1 -1
  5. package/README.md +9 -5
  6. package/config.schema.json +370 -142
  7. package/dist/devices/bots.d.ts +18 -34
  8. package/dist/devices/bots.d.ts.map +1 -1
  9. package/dist/devices/bots.js +166 -171
  10. package/dist/devices/bots.js.map +1 -1
  11. package/dist/devices/{bulb.d.ts → colorbulb.d.ts} +12 -19
  12. package/dist/devices/colorbulb.d.ts.map +1 -0
  13. package/dist/devices/{bulb.js → colorbulb.js} +34 -32
  14. package/dist/devices/colorbulb.js.map +1 -0
  15. package/dist/devices/contact.d.ts +18 -16
  16. package/dist/devices/contact.d.ts.map +1 -1
  17. package/dist/devices/contact.js +101 -44
  18. package/dist/devices/contact.js.map +1 -1
  19. package/dist/devices/curtains.d.ts +17 -51
  20. package/dist/devices/curtains.d.ts.map +1 -1
  21. package/dist/devices/curtains.js +170 -248
  22. package/dist/devices/curtains.js.map +1 -1
  23. package/dist/devices/humidifiers.d.ts +13 -4
  24. package/dist/devices/humidifiers.d.ts.map +1 -1
  25. package/dist/devices/humidifiers.js +81 -8
  26. package/dist/devices/humidifiers.js.map +1 -1
  27. package/dist/devices/indoorcam.d.ts +6 -13
  28. package/dist/devices/indoorcam.d.ts.map +1 -1
  29. package/dist/devices/indoorcam.js.map +1 -1
  30. package/dist/devices/meters.d.ts +12 -15
  31. package/dist/devices/meters.d.ts.map +1 -1
  32. package/dist/devices/meters.js +38 -44
  33. package/dist/devices/meters.js.map +1 -1
  34. package/dist/devices/motion.d.ts +17 -15
  35. package/dist/devices/motion.d.ts.map +1 -1
  36. package/dist/devices/motion.js +87 -40
  37. package/dist/devices/motion.js.map +1 -1
  38. package/dist/devices/plugs.d.ts +6 -13
  39. package/dist/devices/plugs.d.ts.map +1 -1
  40. package/dist/devices/plugs.js.map +1 -1
  41. package/dist/irdevices/airconditioners.d.ts +10 -10
  42. package/dist/irdevices/airconditioners.d.ts.map +1 -1
  43. package/dist/irdevices/airconditioners.js +29 -9
  44. package/dist/irdevices/airconditioners.js.map +1 -1
  45. package/dist/irdevices/airpurifiers.d.ts +11 -11
  46. package/dist/irdevices/airpurifiers.d.ts.map +1 -1
  47. package/dist/irdevices/airpurifiers.js.map +1 -1
  48. package/dist/irdevices/cameras.d.ts +3 -3
  49. package/dist/irdevices/cameras.d.ts.map +1 -1
  50. package/dist/irdevices/cameras.js.map +1 -1
  51. package/dist/irdevices/fans.d.ts +6 -6
  52. package/dist/irdevices/fans.d.ts.map +1 -1
  53. package/dist/irdevices/fans.js +10 -10
  54. package/dist/irdevices/fans.js.map +1 -1
  55. package/dist/irdevices/lights.d.ts +3 -3
  56. package/dist/irdevices/lights.d.ts.map +1 -1
  57. package/dist/irdevices/lights.js.map +1 -1
  58. package/dist/irdevices/others.d.ts +3 -3
  59. package/dist/irdevices/others.d.ts.map +1 -1
  60. package/dist/irdevices/others.js.map +1 -1
  61. package/dist/irdevices/tvs.d.ts +3 -3
  62. package/dist/irdevices/tvs.d.ts.map +1 -1
  63. package/dist/irdevices/tvs.js +7 -5
  64. package/dist/irdevices/tvs.js.map +1 -1
  65. package/dist/irdevices/vacuumcleaners.d.ts +3 -3
  66. package/dist/irdevices/vacuumcleaners.d.ts.map +1 -1
  67. package/dist/irdevices/vacuumcleaners.js.map +1 -1
  68. package/dist/irdevices/waterheaters.d.ts +3 -3
  69. package/dist/irdevices/waterheaters.d.ts.map +1 -1
  70. package/dist/irdevices/waterheaters.js.map +1 -1
  71. package/dist/platform.d.ts +3 -2
  72. package/dist/platform.d.ts.map +1 -1
  73. package/dist/platform.js +136 -46
  74. package/dist/platform.js.map +1 -1
  75. package/dist/settings.d.ts +51 -8
  76. package/dist/settings.d.ts.map +1 -1
  77. package/package.json +65 -65
  78. package/src/devices/bots.ts +188 -193
  79. package/src/devices/{bulb.ts → colorbulb.ts} +46 -51
  80. package/src/devices/contact.ts +124 -68
  81. package/src/devices/curtains.ts +192 -300
  82. package/src/devices/humidifiers.ts +97 -14
  83. package/src/devices/indoorcam.ts +10 -20
  84. package/src/devices/meters.ts +57 -69
  85. package/src/devices/motion.ts +108 -62
  86. package/src/devices/plugs.ts +8 -19
  87. package/src/irdevices/airconditioners.ts +43 -20
  88. package/src/irdevices/airpurifiers.ts +15 -11
  89. package/src/irdevices/cameras.ts +5 -3
  90. package/src/irdevices/fans.ts +22 -16
  91. package/src/irdevices/lights.ts +5 -3
  92. package/src/irdevices/others.ts +5 -3
  93. package/src/irdevices/tvs.ts +13 -7
  94. package/src/irdevices/vacuumcleaners.ts +5 -3
  95. package/src/irdevices/waterheaters.ts +5 -3
  96. package/src/platform.ts +148 -49
  97. package/src/settings.ts +80 -8
  98. package/dist/devices/bulb.d.ts.map +0 -1
  99. package/dist/devices/bulb.js.map +0 -1
@@ -1,8 +1,9 @@
1
- import { Service, PlatformAccessory, CharacteristicValue, MacAddress } from 'homebridge';
1
+ import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
2
2
  import { SwitchBotPlatform } from '../platform';
3
3
  import { interval, Subject } from 'rxjs';
4
4
  import { debounceTime, skipWhile, tap } from 'rxjs/operators';
5
- import { DeviceURL, device, devicesConfig } from '../settings';
5
+ import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceStatusResponse } from '../settings';
6
+ import { AxiosResponse } from 'axios';
6
7
 
7
8
  /**
8
9
  * Platform Accessory
@@ -10,53 +11,43 @@ import { DeviceURL, device, devicesConfig } from '../settings';
10
11
  * Each accessory may expose multiple services of different service types.
11
12
  */
12
13
  export class Bot {
13
- private service: Service;
14
+ // Services
15
+ private outletService?: Service;
16
+ private switchService?: Service;
17
+ private batteryService?: Service;
14
18
 
19
+ // Characteristic Values
15
20
  SwitchOn!: CharacteristicValue;
16
- OutletInUse!: CharacteristicValue;
17
- deviceStatus!: { statusCode: number; body: { deviceId: string; deviceType: string; hubDeviceId: string; power: string; }; message: string; };
18
- RunTimer!: NodeJS.Timeout;
19
- ScanDuration: number;
20
- TargetState;
21
- switchbot!: {
22
- discover: (
23
- arg0:
24
- {
25
- duration: any;
26
- model: string;
27
- quick: boolean;
28
- id: MacAddress;
29
- }
30
- ) => Promise<any>;
31
- wait: (
32
- arg0: number
33
- ) => any;
34
- };
21
+ BatteryLevel!: CharacteristicValue;
22
+ StatusLowBattery!: CharacteristicValue;
23
+
24
+ // OpenAPI Others
25
+ deviceStatus!: deviceStatusResponse;
26
+
27
+ // BLE Others
28
+ switchbot!: switchbot;
29
+ serviceData!: serviceData;
30
+ mode!: serviceData['mode'];
31
+ state!: serviceData['state'];
32
+ battery!: serviceData['battery'];
35
33
 
34
+ // Updates
36
35
  botUpdateInProgress!: boolean;
37
- doBotUpdate;
36
+ doBotUpdate!: Subject<void>;
38
37
 
39
38
  constructor(
40
39
  private readonly platform: SwitchBotPlatform,
41
40
  private accessory: PlatformAccessory,
42
41
  public device: device & devicesConfig,
43
42
  ) {
43
+ // Bot Config
44
+ this.platform.device(`[Bot Config] ble: ${device.ble}, mode: ${device.bot?.mode},`
45
+ + ` deviceType: ${device.bot?.deviceType}`);
46
+
44
47
  // default placeholders
45
48
  this.SwitchOn = false;
46
- this.ScanDuration = this.platform.config.options!.refreshRate!;
47
- if (device.bot?.mode !== 'switch') {
48
- this.OutletInUse = true;
49
- }
50
- if (device.ble) {
51
- this.SwitchOn = false;
52
- // eslint-disable-next-line @typescript-eslint/no-var-requires
53
- const SwitchBot = require('node-switchbot');
54
- this.switchbot = new SwitchBot();
55
- const colon = device.deviceId!.match(/.{1,2}/g);
56
- const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
57
- this.device.bleMac = bleMac.toLowerCase();
58
- this.platform.device(this.device.bleMac);
59
- }
49
+ this.BatteryLevel = 100;
50
+ this.StatusLowBattery = 1;
60
51
 
61
52
  // this is subject we use to track when we need to POST changes to the SwitchBot API
62
53
  this.doBotUpdate = new Subject();
@@ -74,30 +65,60 @@ export class Bot {
74
65
 
75
66
  // get the LightBulb service if it exists, otherwise create a new LightBulb service
76
67
  // you can create multiple services for each accessory
77
- if (device.bot?.mode === 'switch') {
78
- (this.service =
79
- accessory.getService(this.platform.Service.Switch) ||
80
- accessory.addService(this.platform.Service.Switch)), `${accessory.displayName} Switch`;
81
- } else {
82
- (this.service =
83
- accessory.getService(this.platform.Service.Outlet) ||
84
- accessory.addService(this.platform.Service.Outlet)), `${accessory.displayName} Outlet`;
68
+ switch (device.bot!.deviceType) {
69
+ case 'switch':
70
+ // If outletService still pressent, then remove first
71
+ if (this.outletService) {
72
+ this.platform.device('Removing Leftover outletService first');
73
+ }
74
+ this.outletService = this.accessory.getService(this.platform.Service.Outlet);
75
+ accessory.removeService(this.outletService!);
76
+
77
+ // Add switchService
78
+ (this.switchService =
79
+ accessory.getService(this.platform.Service.Switch) ||
80
+ accessory.addService(this.platform.Service.Switch)), `${accessory.displayName} Switch`;
81
+ this.platform.log.info('Displaying as Switch');
82
+
83
+ this.switchService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
84
+ break;
85
+ case 'outlet':
86
+ default:
87
+ // If switchService still pressent, then remove first
88
+ if (this.switchService) {
89
+ this.platform.device('Removing Leftover switchService first');
90
+ }
91
+ this.switchService = this.accessory.getService(this.platform.Service.Switch);
92
+ accessory.removeService(this.switchService!);
93
+
94
+ // Add outletService
95
+ (this.outletService =
96
+ accessory.getService(this.platform.Service.Outlet) ||
97
+ accessory.addService(this.platform.Service.Outlet)), `${accessory.displayName} Outlet`;
98
+ this.platform.log.info('Displaying as Outlet');
99
+
100
+ this.outletService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
85
101
  }
86
102
 
87
- // To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
88
- // when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
89
- // accessory.getService('NAME') ?? accessory.addService(this.platform.Service.Outlet, 'NAME', 'USER_DEFINED_SUBTYPE');
103
+ if (device.ble) {
104
+ (this.batteryService =
105
+ accessory.getService(this.platform.Service.Battery) ||
106
+ accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
90
107
 
91
- // set the service name, this is what is displayed as the default name on the Home app
92
- // in this example we are using the name we stored in the `accessory.context` in the `discoverDevices` method.
93
- this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
108
+ this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
109
+ }
94
110
 
95
111
  // each service must implement at-minimum the "required characteristics" for the given service type
96
112
  // see https://developers.homebridge.io/#/service/Outlet
97
113
 
98
- this.service.getCharacteristic(this.platform.Characteristic.On).onSet(this.handleOnSet.bind(this));
114
+ if (device.bot?.deviceType === 'switch') {
115
+ this.switchService!.getCharacteristic(this.platform.Characteristic.On).onSet(this.handleOnSet.bind(this));
116
+ } else {
117
+ this.outletService!.getCharacteristic(this.platform.Characteristic.On).onSet(this.handleOnSet.bind(this));
118
+ }
99
119
 
100
120
  // Retrieve initial values and updateHomekit
121
+ this.refreshStatus();
101
122
  this.updateHomeKitCharacteristics();
102
123
 
103
124
  // Start an update interval
@@ -142,18 +163,29 @@ export class Bot {
142
163
  }
143
164
 
144
165
  private async BLEparseStatus() {
145
- this.platform.debug('Bots BLE Device RefreshStatus');
166
+ this.platform.debug('Bots BLE Device parseStatus');
167
+ // BLEmode (true if Switch Mode) | (false if Press Mode)
168
+ if (this.mode) {
169
+ this.platform.device(`Switch Mode, mode: ${JSON.stringify(this.mode)}`);
170
+ }
171
+ this.SwitchOn = Boolean(this.state);
172
+ this.BatteryLevel = Number(this.battery);
173
+ if (this.BatteryLevel < 10) {
174
+ this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
175
+ } else {
176
+ this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
177
+ }
178
+ if (Number.isNaN(this.BatteryLevel)) {
179
+ this.BatteryLevel = 100;
180
+ }
181
+ this.platform.debug(`Bot ${this.accessory.displayName} On: ${this.SwitchOn}, BatteryLevel: ${this.BatteryLevel}`);
146
182
  }
147
183
 
148
184
  private async openAPIparseStatus() {
149
- if (this.device.bot?.mode !== 'switch') {
150
- this.OutletInUse = true;
151
- this.SwitchOn = false;
152
- this.platform.debug(`Bot ${this.accessory.displayName} OutletInUse: ${this.OutletInUse} On: ${this.SwitchOn}`);
153
- } else {
185
+ if (this.device.bot?.mode === 'press') {
154
186
  this.SwitchOn = false;
155
- this.platform.debug(`Bot ${this.accessory.displayName} On: ${this.SwitchOn}`);
156
187
  }
188
+ this.platform.debug(`Bot ${this.accessory.displayName} On: ${this.SwitchOn}`);
157
189
  }
158
190
 
159
191
  /**
@@ -162,15 +194,14 @@ export class Bot {
162
194
  async refreshStatus() {
163
195
  if (this.device.ble) {
164
196
  this.platform.device('BLE');
165
- await this.BLErefreshStatus();
197
+ await this.BLERefreshStatus();
166
198
  } else {
167
199
  this.platform.device('OpenAPI');
168
200
  await this.openAPIRefreshStatus();
169
201
  }
170
202
  }
171
203
 
172
- private async BLErefreshStatus() {
173
- this.platform.device('Bot BLE Device refreshStatus');
204
+ private connectBLE() {
174
205
  // eslint-disable-next-line @typescript-eslint/no-var-requires
175
206
  const Switchbot = require('node-switchbot');
176
207
  const switchbot = new Switchbot();
@@ -178,45 +209,40 @@ export class Bot {
178
209
  const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
179
210
  this.device.bleMac = bleMac.toLowerCase();
180
211
  this.platform.device(this.device.bleMac!);
181
- switchbot.onadvertisement = (ad: any) => {
182
- this.platform.debug(JSON.stringify(ad, null, ' '));
183
- this.platform.device(`ad: ${JSON.stringify(ad)}`);
184
- };
185
- switchbot
186
- .startScan({
187
- id: this.device.bleMac,
188
- })
189
- .then(() => {
190
- return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
191
- })
192
- .then(() => {
193
- switchbot.stopScan();
194
- })
195
- .catch(async (error: any) => {
196
- this.platform.log.error(error);
197
- this.openAPIRefreshStatus();
198
- });
199
- setInterval(() => {
200
- this.platform.log.info('Start scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
201
- switchbot
202
- .startScan({
203
- mode: 'T',
204
- id: bleMac,
205
- })
206
- .then(() => {
207
- return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
208
- })
209
- .then(() => {
210
- switchbot.stopScan();
211
- this.platform.log.info('Stop scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
212
- })
213
- .catch(async (error: any) => {
214
- this.platform.log.error(error);
215
- this.openAPIRefreshStatus();
216
- });
212
+ return switchbot;
213
+ }
214
+
215
+ private async BLERefreshStatus() {
216
+ this.platform.device('Bot BLE Device refreshStatus');
217
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
218
+ const switchbot = this.connectBLE();
219
+ // Start to monitor advertisement packets
220
+ switchbot.startScan({
221
+ model: 'H',
222
+ id: this.device.bleMac,
223
+ }).then(() => {
224
+ // Set an event hander
225
+ switchbot.onadvertisement = (ad: ad) => {
226
+ this.serviceData = ad.serviceData;
227
+ this.mode = ad.serviceData.mode;
228
+ this.state = ad.serviceData.state;
229
+ this.battery = ad.serviceData.battery;
230
+ this.platform.device(`${this.device.bleMac}: ${JSON.stringify(ad.serviceData)}`);
231
+ this.platform.device(`${this.accessory.displayName}, Model: ${ad.serviceData.model}, Model Name: ${ad.serviceData.modelName},`
232
+ + ` Mode: ${ad.serviceData.mode}, State: ${ad.serviceData.state}, Battery: ${ad.serviceData.battery}`);
233
+ };
234
+ // Wait 10 seconds
235
+ return switchbot.wait(10000);
236
+ }).then(() => {
237
+ // Stop to monitor
238
+ switchbot.stopScan();
217
239
  this.parseStatus();
218
240
  this.updateHomeKitCharacteristics();
219
- }, this.platform.config.options!.refreshRate! * 60000);
241
+ }).catch(async (e: any) => {
242
+ this.platform.log.error(`BLE Connection Failed: ${e.message}`);
243
+ this.platform.log.warn('Using OpenAPI Connection');
244
+ await this.openAPIRefreshStatus();
245
+ });
220
246
  }
221
247
 
222
248
  private async openAPIRefreshStatus() {
@@ -260,53 +286,38 @@ export class Bot {
260
286
 
261
287
  private async BLEpushChanges() {
262
288
  this.platform.device('Bot BLE Device pushChanges');
263
- // Target state has been changed.
264
- this.platform.log.info('Target state of Bot setting: ' + (this.TargetState ? 'ON' : 'OFF'));
265
- this.switchbot
266
- .discover({ duration: this.ScanDuration, model: 'H', quick: true, id: (this.device.bleMac!) })
267
- .then((device_list: any) => {
268
- this.platform.log.info('Scan done.');
269
- let targetDevice: any = null;
270
- for (const device of device_list) {
271
- // log.info(device.modelName, device.address);
272
- if (device.address === this.device.bleMac) {
273
- targetDevice = device;
274
- break;
275
- }
276
- }
277
- if (!targetDevice) {
278
- this.platform.log.info('No device was found during scan.');
279
- return new Promise((resolve, reject) => {
280
- reject(new Error('No device was found during scan.'));
281
- });
282
- } else {
283
- this.platform.log.info(targetDevice.modelName + ' (' + targetDevice.address + ') was found.');
284
- // Set event handers
285
- targetDevice.onconnect = () => {
286
- // log.info('Connected.');
287
- };
288
- targetDevice.ondisconnect = () => {
289
- // log.info('Disconnected.');
290
- };
291
- this.platform.log.info('Bot is running...');
292
- return this.setTargetDeviceState(targetDevice, this.TargetState);
293
- }
294
- })
295
- .then(() => {
296
- this.platform.log.info('Done.');
297
- this.SwitchOn = this.TargetState;
298
- this.RunTimer = setTimeout(() => {
299
- this.service?.getCharacteristic(this.platform.Characteristic.On).updateValue(this.SwitchOn);
300
- }, 500);
301
- this.platform.log.info('Bot state has been set to: ' + (this.SwitchOn ? 'ON' : 'OFF'));
302
- })
303
- .catch((error: any) => {
304
- this.platform.log.error(error);
305
- this.RunTimer = setTimeout(() => {
306
- this.service?.getCharacteristic(this.platform.Characteristic.On).updateValue(this.SwitchOn);
307
- }, 500);
308
- this.platform.log.info('Bot state failed to be set to: ' + (this.TargetState ? 'ON' : 'OFF'));
289
+ const switchbot = this.connectBLE();
290
+ if (this.device.bot?.mode === 'press') {
291
+ this.platform.device(`Press Mode: ${this.device.bot?.mode}`);
292
+ switchbot.discover({ model: 'H', quick: true, id: this.device.bleMac }).then((device_list) => {
293
+ this.platform.log.info(`${this.accessory.displayName}, On: ${this.SwitchOn}`);
294
+ return device_list[0].press({ id: this.device.bleMac });
295
+ }).then(() => {
296
+ this.platform.device('Done.');
297
+ }).catch((e: any) => {
298
+ this.platform.log.error(`BLE pushChanges Error Message: ${e.message}`);
299
+ });
300
+ } else if (this.device.bot?.mode === 'switch') {
301
+ this.platform.device(`Press Mode: ${this.device.bot?.mode}`);
302
+ switchbot.discover({ model: 'H', quick: true, id: this.device.bleMac }).then((device_list) => {
303
+ this.platform.log.info(`${this.accessory.displayName}, On: ${this.SwitchOn}`);
304
+ return this.turnOnOff(device_list);
305
+ }).then(() => {
306
+ this.platform.device('Done.');
307
+ }).catch((e: any) => {
308
+ this.platform.log.error(`BLE pushChanges Error Message: ${e.message}`);
309
309
  });
310
+ } else {
311
+ this.platform.log.error('Mode Not Set.');
312
+ }
313
+ }
314
+
315
+ private turnOnOff(device_list: any) {
316
+ if (this.SwitchOn) {
317
+ return device_list[0].turnOn({ id: this.device.bleMac });
318
+ } else {
319
+ return device_list[0].turnOff({ id: this.device.bleMac });
320
+ }
310
321
  }
311
322
 
312
323
  private async openAPIpushChanges() {
@@ -315,11 +326,11 @@ export class Bot {
315
326
  parameter: 'default',
316
327
  } as any;
317
328
 
318
- if (this.device.bot?.mode === 'switch' && (this.SwitchOn)) {
329
+ if (this.device.bot?.mode === 'switch' && this.SwitchOn) {
319
330
  payload.command = 'turnOn';
320
331
  this.SwitchOn = true;
321
332
  this.platform.debug(`Switch Mode, Turning ${this.SwitchOn}`);
322
- } else if (this.device.bot?.mode === 'switch' && (!this.SwitchOn)) {
333
+ } else if (this.device.bot?.mode === 'switch' && !this.SwitchOn) {
323
334
  payload.command = 'turnOff';
324
335
  this.SwitchOn = false;
325
336
  this.platform.debug(`Switch Mode, Turning ${this.SwitchOn}`);
@@ -356,26 +367,42 @@ export class Bot {
356
367
  if (this.SwitchOn === undefined) {
357
368
  this.platform.debug(`Bot ${this.accessory.displayName} On: ${this.SwitchOn}`);
358
369
  } else {
359
- this.service.updateCharacteristic(this.platform.Characteristic.On, this.SwitchOn);
370
+ if (this.device.bot?.deviceType === 'switch') {
371
+ this.switchService!.updateCharacteristic(this.platform.Characteristic.On, this.SwitchOn);
372
+ } else {
373
+ this.outletService!.updateCharacteristic(this.platform.Characteristic.On, this.SwitchOn);
374
+ }
360
375
  this.platform.device(`Bot ${this.accessory.displayName} updateCharacteristic On: ${this.SwitchOn}`);
361
376
  }
362
- if (this.OutletInUse === undefined || this.device.bot?.mode === 'switch') {
363
- this.platform.debug(`Bot ${this.accessory.displayName} On: ${this.OutletInUse}, Switch: ${this.device.bot?.mode}`);
364
- } else {
365
- this.service.updateCharacteristic(this.platform.Characteristic.OutletInUse, this.OutletInUse);
366
- this.platform.device(`Bot ${this.accessory.displayName} updateCharacteristic On: ${this.OutletInUse},`
367
- + ` Switch: ${this.device.bot?.mode}`);
377
+ if (this.device.ble) {
378
+ if (this.BatteryLevel === undefined) {
379
+ this.platform.debug(`Bot ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
380
+ } else {
381
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
382
+ this.platform.device(`Bot ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
383
+ }
384
+ if (this.StatusLowBattery === undefined) {
385
+ this.platform.debug(`Bot ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
386
+ } else {
387
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
388
+ this.platform.device(`Bot ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
389
+ }
368
390
  }
369
391
  }
370
392
 
371
393
  public apiError(e: any) {
372
- this.service.updateCharacteristic(this.platform.Characteristic.On, e);
373
- if (this.device.bot?.mode !== 'switch') {
374
- this.service.updateCharacteristic(this.platform.Characteristic.OutletInUse, e);
394
+ if (this.device.bot?.deviceType === 'switch') {
395
+ this.switchService!.updateCharacteristic(this.platform.Characteristic.On, e);
396
+ } else {
397
+ this.outletService!.updateCharacteristic(this.platform.Characteristic.On, e);
398
+ }
399
+ if (this.device.ble) {
400
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
401
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
375
402
  }
376
403
  }
377
404
 
378
- private statusCode(push: { data: { statusCode: any; }; }) {
405
+ private statusCode(push: AxiosResponse<{ statusCode: number; }>) {
379
406
  switch (push.data.statusCode) {
380
407
  case 151:
381
408
  this.platform.log.error('Command not supported by this device type.');
@@ -407,40 +434,8 @@ export class Bot {
407
434
  * Handle requests to set the "On" characteristic
408
435
  */
409
436
  private handleOnSet(value: CharacteristicValue) {
410
- if (this.device.ble) {
411
- this.TargetState = value as boolean;
412
- this.platform.device(`Bot BLE Device - ${this.TargetState}`);
413
- if (this.TargetState === this.SwitchOn) {
414
- this.platform.log.info('Target state of Bot has not changed: ' + (this.SwitchOn ? 'ON' : 'OFF'));
415
- this.service?.getCharacteristic(this.platform.Characteristic.On).updateValue(this.SwitchOn);
416
- }
417
- } else {
418
- this.platform.debug(`Bot ${this.accessory.displayName} - Set On: ${value}`);
419
- this.SwitchOn = value;
420
- this.doBotUpdate.next();
421
- }
422
- }
423
-
424
- async setTargetDeviceState(targetDevice: any, targetState: boolean): Promise<null> {
425
- return await this.retry(5, () => {
426
- if (targetState) {
427
- return targetDevice.turnOn();
428
- } else {
429
- return targetDevice.turnOff();
430
- }
431
- });
437
+ this.platform.debug(`Bot ${this.accessory.displayName} - Set On: ${value}`);
438
+ this.SwitchOn = value;
439
+ this.doBotUpdate.next();
432
440
  }
433
-
434
- async retry(max: number, fn: { (): any; (): Promise<any>; }): Promise<null> {
435
- return fn().catch(async (err: any) => {
436
- if (max === 0) {
437
- throw err;
438
- }
439
- this.platform.log.info(err);
440
- this.platform.log.info('Retrying');
441
- await this.switchbot.wait(1000);
442
- return this.retry(max - 1, fn);
443
- });
444
- }
445
-
446
441
  }