@switchbot/homebridge-switchbot 3.5.0-beta.5 → 3.5.0-beta.51

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 (169) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/config.schema.json +120 -17
  3. package/dist/device/blindtilt.d.ts +21 -94
  4. package/dist/device/blindtilt.d.ts.map +1 -1
  5. package/dist/device/blindtilt.js +352 -757
  6. package/dist/device/blindtilt.js.map +1 -1
  7. package/dist/device/bot.d.ts +25 -71
  8. package/dist/device/bot.d.ts.map +1 -1
  9. package/dist/device/bot.js +588 -761
  10. package/dist/device/bot.js.map +1 -1
  11. package/dist/device/ceilinglight.d.ts +13 -67
  12. package/dist/device/ceilinglight.d.ts.map +1 -1
  13. package/dist/device/ceilinglight.js +214 -588
  14. package/dist/device/ceilinglight.js.map +1 -1
  15. package/dist/device/colorbulb.d.ts +13 -74
  16. package/dist/device/colorbulb.d.ts.map +1 -1
  17. package/dist/device/colorbulb.js +256 -634
  18. package/dist/device/colorbulb.js.map +1 -1
  19. package/dist/device/contact.d.ts +14 -65
  20. package/dist/device/contact.d.ts.map +1 -1
  21. package/dist/device/contact.js +209 -532
  22. package/dist/device/contact.js.map +1 -1
  23. package/dist/device/curtain.d.ts +17 -86
  24. package/dist/device/curtain.d.ts.map +1 -1
  25. package/dist/device/curtain.js +340 -787
  26. package/dist/device/curtain.js.map +1 -1
  27. package/dist/device/device.d.ts +59 -0
  28. package/dist/device/device.d.ts.map +1 -0
  29. package/dist/device/device.js +682 -0
  30. package/dist/device/device.js.map +1 -0
  31. package/dist/device/fan.d.ts +51 -0
  32. package/dist/device/fan.d.ts.map +1 -0
  33. package/dist/device/fan.js +505 -0
  34. package/dist/device/fan.js.map +1 -0
  35. package/dist/device/hub.d.ts +15 -59
  36. package/dist/device/hub.d.ts.map +1 -1
  37. package/dist/device/hub.js +247 -597
  38. package/dist/device/hub.js.map +1 -1
  39. package/dist/device/humidifier.d.ts +10 -65
  40. package/dist/device/humidifier.d.ts.map +1 -1
  41. package/dist/device/humidifier.js +218 -579
  42. package/dist/device/humidifier.js.map +1 -1
  43. package/dist/device/iosensor.d.ts +11 -64
  44. package/dist/device/iosensor.d.ts.map +1 -1
  45. package/dist/device/iosensor.js +179 -585
  46. package/dist/device/iosensor.js.map +1 -1
  47. package/dist/device/lightstrip.d.ts +10 -68
  48. package/dist/device/lightstrip.d.ts.map +1 -1
  49. package/dist/device/lightstrip.js +257 -569
  50. package/dist/device/lightstrip.js.map +1 -1
  51. package/dist/device/lock.d.ts +15 -62
  52. package/dist/device/lock.d.ts.map +1 -1
  53. package/dist/device/lock.js +215 -543
  54. package/dist/device/lock.js.map +1 -1
  55. package/dist/device/meter.d.ts +13 -63
  56. package/dist/device/meter.d.ts.map +1 -1
  57. package/dist/device/meter.js +175 -578
  58. package/dist/device/meter.js.map +1 -1
  59. package/dist/device/meterplus.d.ts +13 -64
  60. package/dist/device/meterplus.d.ts.map +1 -1
  61. package/dist/device/meterplus.js +164 -578
  62. package/dist/device/meterplus.js.map +1 -1
  63. package/dist/device/motion.d.ts +13 -69
  64. package/dist/device/motion.d.ts.map +1 -1
  65. package/dist/device/motion.js +142 -520
  66. package/dist/device/motion.js.map +1 -1
  67. package/dist/device/plug.d.ts +9 -57
  68. package/dist/device/plug.d.ts.map +1 -1
  69. package/dist/device/plug.js +87 -453
  70. package/dist/device/plug.js.map +1 -1
  71. package/dist/device/robotvacuumcleaner.d.ts +11 -62
  72. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  73. package/dist/device/robotvacuumcleaner.js +145 -452
  74. package/dist/device/robotvacuumcleaner.js.map +1 -1
  75. package/dist/device/waterdetector.d.ts +9 -70
  76. package/dist/device/waterdetector.d.ts.map +1 -1
  77. package/dist/device/waterdetector.js +126 -665
  78. package/dist/device/waterdetector.js.map +1 -1
  79. package/dist/homebridge-ui/public/index.html +2 -2
  80. package/dist/index.js +1 -1
  81. package/dist/irdevice/airconditioner.d.ts +8 -48
  82. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  83. package/dist/irdevice/airconditioner.js +309 -419
  84. package/dist/irdevice/airconditioner.js.map +1 -1
  85. package/dist/irdevice/airpurifier.d.ts +7 -38
  86. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  87. package/dist/irdevice/airpurifier.js +72 -304
  88. package/dist/irdevice/airpurifier.js.map +1 -1
  89. package/dist/irdevice/camera.d.ts +6 -35
  90. package/dist/irdevice/camera.d.ts.map +1 -1
  91. package/dist/irdevice/camera.js +34 -278
  92. package/dist/irdevice/camera.js.map +1 -1
  93. package/dist/irdevice/fan.d.ts +6 -39
  94. package/dist/irdevice/fan.d.ts.map +1 -1
  95. package/dist/irdevice/fan.js +67 -311
  96. package/dist/irdevice/fan.js.map +1 -1
  97. package/dist/irdevice/irdevice.d.ts +40 -0
  98. package/dist/irdevice/irdevice.d.ts.map +1 -0
  99. package/dist/irdevice/irdevice.js +512 -0
  100. package/dist/irdevice/irdevice.js.map +1 -0
  101. package/dist/irdevice/light.d.ts +6 -34
  102. package/dist/irdevice/light.d.ts.map +1 -1
  103. package/dist/irdevice/light.js +23 -272
  104. package/dist/irdevice/light.js.map +1 -1
  105. package/dist/irdevice/other.d.ts +18 -47
  106. package/dist/irdevice/other.d.ts.map +1 -1
  107. package/dist/irdevice/other.js +352 -546
  108. package/dist/irdevice/other.js.map +1 -1
  109. package/dist/irdevice/tv.d.ts +7 -39
  110. package/dist/irdevice/tv.d.ts.map +1 -1
  111. package/dist/irdevice/tv.js +82 -321
  112. package/dist/irdevice/tv.js.map +1 -1
  113. package/dist/irdevice/vacuumcleaner.d.ts +6 -35
  114. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  115. package/dist/irdevice/vacuumcleaner.js +41 -284
  116. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  117. package/dist/irdevice/waterheater.d.ts +6 -35
  118. package/dist/irdevice/waterheater.d.ts.map +1 -1
  119. package/dist/irdevice/waterheater.js +42 -287
  120. package/dist/irdevice/waterheater.js.map +1 -1
  121. package/dist/platform.d.ts +14 -1
  122. package/dist/platform.d.ts.map +1 -1
  123. package/dist/platform.js +291 -147
  124. package/dist/platform.js.map +1 -1
  125. package/dist/settings.d.ts +41 -11
  126. package/dist/settings.d.ts.map +1 -1
  127. package/dist/settings.js +0 -552
  128. package/dist/settings.js.map +1 -1
  129. package/dist/utils.d.ts +77 -0
  130. package/dist/utils.d.ts.map +1 -1
  131. package/dist/utils.js +638 -1
  132. package/dist/utils.js.map +1 -1
  133. package/eslint.config.js +87 -0
  134. package/package.json +16 -15
  135. package/src/custom.d.ts +2 -1
  136. package/src/device/blindtilt.ts +378 -783
  137. package/src/device/bot.ts +621 -845
  138. package/src/device/ceilinglight.ts +227 -608
  139. package/src/device/colorbulb.ts +269 -657
  140. package/src/device/contact.ts +235 -555
  141. package/src/device/curtain.ts +360 -811
  142. package/src/device/device.ts +710 -0
  143. package/src/device/fan.ts +554 -0
  144. package/src/device/hub.ts +274 -625
  145. package/src/device/humidifier.ts +246 -624
  146. package/src/device/iosensor.ts +205 -611
  147. package/src/device/lightstrip.ts +278 -597
  148. package/src/device/lock.ts +252 -583
  149. package/src/device/meter.ts +200 -601
  150. package/src/device/meterplus.ts +189 -603
  151. package/src/device/motion.ts +161 -542
  152. package/src/device/plug.ts +97 -481
  153. package/src/device/robotvacuumcleaner.ts +166 -478
  154. package/src/device/waterdetector.ts +143 -689
  155. package/src/homebridge-ui/public/index.html +2 -2
  156. package/src/index.ts +1 -1
  157. package/src/irdevice/airconditioner.ts +330 -446
  158. package/src/irdevice/airpurifier.ts +89 -321
  159. package/src/irdevice/camera.ts +42 -293
  160. package/src/irdevice/fan.ts +78 -327
  161. package/src/irdevice/irdevice.ts +528 -0
  162. package/src/irdevice/light.ts +32 -287
  163. package/src/irdevice/other.ts +396 -615
  164. package/src/irdevice/tv.ts +100 -339
  165. package/src/irdevice/vacuumcleaner.ts +49 -305
  166. package/src/irdevice/waterheater.ts +50 -310
  167. package/src/platform.ts +301 -155
  168. package/src/settings.ts +57 -566
  169. package/src/utils.ts +642 -1
@@ -1,103 +1,75 @@
1
+ /* Copyright(C) 2021-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved.
2
+ *
3
+ * robotvacuumcleaner.ts: @switchbot/homebridge-switchbot.
4
+ */
1
5
  import { request } from 'undici';
2
- import { sleep } from '../utils.js';
3
- import { interval, Subject } from 'rxjs';
6
+ import { Subject, interval, skipWhile } from 'rxjs';
7
+ import { deviceBase } from './device.js';
4
8
  import { SwitchBotPlatform } from '../platform.js';
5
- import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
6
- import { Service, PlatformAccessory, CharacteristicValue, API, Logging, HAP } from 'homebridge';
7
- import { device, devicesConfig, deviceStatus, serviceData, Devices, SwitchBotPlatformConfig } from '../settings.js';
8
-
9
- export class RobotVacuumCleaner {
10
- public readonly api: API;
11
- public readonly log: Logging;
12
- public readonly config!: SwitchBotPlatformConfig;
13
- protected readonly hap: HAP;
14
- // Services
15
- batteryService: Service;
16
- robotVacuumCleanerService: Service;
17
-
18
- // Characteristic Values
19
- On!: CharacteristicValue;
20
- Brightness!: CharacteristicValue;
21
- BatteryLevel!: CharacteristicValue;
22
- StatusLowBattery!: CharacteristicValue;
23
- FirmwareRevision!: CharacteristicValue;
24
-
25
- // OpenAPI Status
26
- OpenAPI_On: deviceStatus['power'];
27
- OpenAPI_BatteryLevel: deviceStatus['battery'];
28
- OpenAPI_FirmwareRevision: deviceStatus['version'];
29
-
30
- // BLE Status
31
- BLE_On: serviceData['state'];
32
-
33
- // BLE Others
34
- BLE_IsConnected?: boolean;
9
+ import { debounceTime, take, tap } from 'rxjs/operators';
10
+ import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
11
+ import { device, devicesConfig, deviceStatus, serviceData, Devices } from '../settings.js';
35
12
 
36
- // Config
37
- scanDuration!: number;
38
- deviceLogging!: string;
39
- deviceRefreshRate!: number;
13
+ export class RobotVacuumCleaner extends deviceBase {
14
+ // Services
15
+ private LightBulb: {
16
+ Service: Service;
17
+ On: CharacteristicValue;
18
+ Brightness: CharacteristicValue;
19
+ };
20
+
21
+ private Battery: {
22
+ Service: Service;
23
+ BatteryLevel: CharacteristicValue;
24
+ StatusLowBattery: CharacteristicValue;
25
+ };
40
26
 
41
27
  // Updates
42
28
  robotVacuumCleanerUpdateInProgress!: boolean;
43
29
  doRobotVacuumCleanerUpdate!: Subject<void>;
44
30
 
45
- // Connection
46
- private readonly OpenAPI: boolean;
47
- private readonly BLE: boolean;
48
-
49
31
  constructor(
50
- private readonly platform: SwitchBotPlatform,
51
- private accessory: PlatformAccessory,
52
- public device: device & devicesConfig,
32
+ readonly platform: SwitchBotPlatform,
33
+ accessory: PlatformAccessory,
34
+ device: device & devicesConfig,
53
35
  ) {
54
- this.api = this.platform.api;
55
- this.log = this.platform.log;
56
- this.config = this.platform.config;
57
- this.hap = this.api.hap;
58
- // Connection
59
- this.BLE = this.device.connectionType === 'BLE' || this.device.connectionType === 'BLE/OpenAPI';
60
- this.OpenAPI = this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'BLE/OpenAPI';
61
- // default placeholders
62
- this.deviceLogs(device);
63
- this.scan(device);
64
- this.refreshRate(device);
65
- this.deviceContext();
66
- this.deviceConfig(device);
67
-
36
+ super(platform, accessory, device);
68
37
  // this is subject we use to track when we need to POST changes to the SwitchBot API
69
38
  this.doRobotVacuumCleanerUpdate = new Subject();
70
39
  this.robotVacuumCleanerUpdateInProgress = false;
71
40
 
41
+ // Initialize Lightbulb property
42
+ this.LightBulb = {
43
+ Service: accessory.getService(this.hap.Service.Lightbulb)!,
44
+ On: accessory.context.On || false,
45
+ Brightness: accessory.context.Brightness || 0,
46
+ };
47
+
48
+ // Initialize Battery property
49
+ this.Battery = {
50
+ Service: accessory.getService(this.hap.Service.Battery)!,
51
+ BatteryLevel: accessory.context.BatteryLevel || 100,
52
+ StatusLowBattery: accessory.context.StatusLowBattery || this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
53
+ };
54
+
72
55
  // Retrieve initial values and updateHomekit
73
56
  this.refreshStatus();
74
57
 
75
- // set accessory information
76
- accessory
77
- .getService(this.hap.Service.AccessoryInformation)!
78
- .setCharacteristic(this.hap.Characteristic.Manufacturer, 'SwitchBot')
79
- .setCharacteristic(this.hap.Characteristic.Model, this.model(device))
80
- .setCharacteristic(this.hap.Characteristic.SerialNumber, device.deviceId)
81
- .setCharacteristic(this.hap.Characteristic.FirmwareRevision, accessory.context.FirmwareRevision);
82
-
83
58
  // get the Lightbulb service if it exists, otherwise create a new Lightbulb service
84
59
  // you can create multiple services for each accessory
85
- const robotVacuumCleanerService = `${accessory.displayName} ${device.deviceType}`;
86
- (this.robotVacuumCleanerService = accessory.getService(this.hap.Service.Lightbulb)
87
- || accessory.addService(this.hap.Service.Lightbulb)), robotVacuumCleanerService;
60
+ const LightBulbService = `${accessory.displayName} ${device.deviceType}`;
61
+ (this.LightBulb.Service = accessory.getService(this.hap.Service.Lightbulb)
62
+ || accessory.addService(this.hap.Service.Lightbulb)), LightBulbService;
88
63
 
89
- this.robotVacuumCleanerService.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
90
- if (!this.robotVacuumCleanerService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
91
- this.robotVacuumCleanerService.addCharacteristic(this.hap.Characteristic.ConfiguredName, accessory.displayName);
92
- }
64
+ this.LightBulb.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
93
65
  // each service must implement at-minimum the "required characteristics" for the given service type
94
66
  // see https://developers.homebridge.io/#/service/Lightbulb
95
67
 
96
68
  // create handlers for required characteristics
97
- this.robotVacuumCleanerService.getCharacteristic(this.hap.Characteristic.On).onSet(this.OnSet.bind(this));
69
+ this.LightBulb.Service.getCharacteristic(this.hap.Characteristic.On).onSet(this.OnSet.bind(this));
98
70
 
99
71
  // handle Brightness events using the Brightness characteristic
100
- this.robotVacuumCleanerService
72
+ this.LightBulb.Service
101
73
  .getCharacteristic(this.hap.Characteristic.Brightness)
102
74
  .setProps({
103
75
  minStep: 25,
@@ -107,19 +79,16 @@ export class RobotVacuumCleaner {
107
79
  validValueRanges: [0, 100],
108
80
  })
109
81
  .onGet(() => {
110
- return this.Brightness;
82
+ return this.LightBulb.Brightness;
111
83
  })
112
84
  .onSet(this.BrightnessSet.bind(this));
113
85
 
114
86
  // Battery Service
115
- const batteryService = `${accessory.displayName} Battery`;
116
- (this.batteryService = this.accessory.getService(this.hap.Service.Battery)
117
- || accessory.addService(this.hap.Service.Battery)), batteryService;
87
+ const BatteryService = `${accessory.displayName} Battery`;
88
+ (this.Battery.Service = this.accessory.getService(this.hap.Service.Battery)
89
+ || accessory.addService(this.hap.Service.Battery)), BatteryService;
118
90
 
119
- this.batteryService.setCharacteristic(this.hap.Characteristic.Name, `${accessory.displayName} Battery`);
120
- if (!this.batteryService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
121
- this.batteryService.addCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Battery`);
122
- }
91
+ this.Battery.Service.setCharacteristic(this.hap.Characteristic.Name, BatteryService);
123
92
 
124
93
  // Update Homekit
125
94
  this.updateHomeKitCharacteristics();
@@ -132,19 +101,20 @@ export class RobotVacuumCleaner {
132
101
  });
133
102
 
134
103
  //regisiter webhook event handler
135
- if (this.device.webhook) {
136
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} is listening webhook.`);
104
+ if (device.webhook) {
105
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} is listening webhook.`);
137
106
  this.platform.webhookEventHandler[this.device.deviceId] = async (context) => {
138
107
  try {
139
108
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
140
109
  const { onlineStatus, battery } = context;
141
- const { On, BatteryLevel } = this;
110
+ const { On } = this.LightBulb;
111
+ const { BatteryLevel } = this.Battery;
142
112
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ` +
143
113
  '(onlineStatus, battery) = ' +
144
114
  `Webhook:(${onlineStatus}, ${battery}), ` +
145
115
  `current:(${On}, ${BatteryLevel})`);
146
- this.On = onlineStatus === 'online' ? true : false;
147
- this.BatteryLevel = battery;
116
+ this.LightBulb.On = onlineStatus === 'online' ? true : false;
117
+ this.Battery.BatteryLevel = battery;
148
118
  this.updateHomeKitCharacteristics();
149
119
  } catch (e: any) {
150
120
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
@@ -164,10 +134,10 @@ export class RobotVacuumCleaner {
164
134
  )
165
135
  .subscribe(async () => {
166
136
  try {
167
- if (this.On !== this.accessory.context.On) {
137
+ if (this.LightBulb.On !== this.accessory.context.On) {
168
138
  await this.pushChanges();
169
139
  }
170
- if (this.On && this.Brightness !== this.accessory.context.Brightness) {
140
+ if (this.LightBulb.On && this.LightBulb.Brightness !== this.accessory.context.Brightness) {
171
141
  await this.openAPIpushBrightnessChanges();
172
142
  }
173
143
  } catch (e: any) {
@@ -181,60 +151,64 @@ export class RobotVacuumCleaner {
181
151
  });
182
152
  }
183
153
 
184
- /**
185
- * Parse the device status from the SwitchBot api
186
- */
187
- async parseStatus(): Promise<void> {
188
- if (!this.device.enableCloudService && this.OpenAPI) {
189
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} parseStatus enableCloudService: ${this.device.enableCloudService}`);
190
- /*} else if (this.BLE) {
191
- await this.BLEparseStatus();*/
192
- } else if (this.OpenAPI && this.platform.config.credentials?.token) {
193
- await this.openAPIparseStatus();
154
+ async BLEparseStatus(serviceData: serviceData): Promise<void> {
155
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
156
+
157
+ // Battery
158
+ this.Battery.BatteryLevel = Number(serviceData.battery);
159
+ if (this.Battery.BatteryLevel < 10) {
160
+ this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
194
161
  } else {
195
- await this.offlineOff();
196
- this.debugWarnLog(
197
- `${this.device.deviceType}: ${this.accessory.displayName} Connection Type:` + ` ${this.device.connectionType}, parseStatus will not happen.`,
198
- );
162
+ this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
199
163
  }
200
- }
164
+ this.debugLog(`${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}, StatusLowBattery: ${this.Battery.StatusLowBattery}`);
201
165
 
202
- async BLEparseStatus(): Promise<void> {
203
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
204
166
  // State
205
- switch (this.BLE_On) {
167
+ switch (serviceData.state) {
206
168
  case 'on':
207
- this.On = true;
169
+ this.LightBulb.On = true;
208
170
  break;
209
171
  default:
210
- this.On = false;
172
+ this.LightBulb.On = false;
211
173
  }
212
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
174
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.LightBulb.On}`);
213
175
  }
214
176
 
215
- async openAPIparseStatus() {
177
+ async openAPIparseStatus(deviceStatus: deviceStatus) {
216
178
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
217
- switch (this.OpenAPI_On) {
179
+ switch (deviceStatus.body.power) {
218
180
  case 'on':
219
- this.On = true;
181
+ this.LightBulb.On = true;
220
182
  break;
221
183
  default:
222
- this.On = false;
184
+ this.LightBulb.On = false;
223
185
  }
224
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
186
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.LightBulb.On}`);
225
187
 
226
- // Battery
227
- this.BatteryLevel = Number(this.OpenAPI_BatteryLevel);
228
- if (this.BatteryLevel < 15) {
229
- this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
188
+ // BatteryLevel
189
+ this.Battery.BatteryLevel = Number(deviceStatus.body.battery);
190
+ if (this.Battery.BatteryLevel < 10) {
191
+ this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
230
192
  } else {
231
- this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
193
+ this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
194
+ }
195
+ if (Number.isNaN(this.Battery.BatteryLevel)) {
196
+ this.Battery.BatteryLevel = 100;
232
197
  }
233
- this.debugLog(`${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
198
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
199
+ + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
234
200
 
235
- // FirmwareRevision
236
- this.FirmwareRevision = this.OpenAPI_FirmwareRevision!;
237
- this.accessory.context.FirmwareRevision = this.FirmwareRevision;
201
+ // Firmware Version
202
+ const version = deviceStatus.body.version?.toString();
203
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Firmware Version: ${version?.replace(/^V|-.*$/g, '')}`);
204
+ if (deviceStatus.body.version) {
205
+ this.accessory.context.version = version?.replace(/^V|-.*$/g, '');
206
+ this.accessory
207
+ .getService(this.hap.Service.AccessoryInformation)!
208
+ .setCharacteristic(this.hap.Characteristic.FirmwareRevision, this.accessory.context.version)
209
+ .getCharacteristic(this.hap.Characteristic.FirmwareRevision)
210
+ .updateValue(this.accessory.context.version);
211
+ }
238
212
  }
239
213
 
240
214
  /**
@@ -278,7 +252,6 @@ export class RobotVacuumCleaner {
278
252
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.serviceData.model}`);
279
253
  if (this.device.bleMac === ad.address && ad.serviceData.model === '?') {
280
254
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
281
- this.BLE_On = ad.serviceData.state;
282
255
  } else {
283
256
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
284
257
  }
@@ -288,7 +261,7 @@ export class RobotVacuumCleaner {
288
261
  // Stop to monitor
289
262
  await switchbot.stopScan();
290
263
  // Update HomeKit
291
- await this.BLEparseStatus();
264
+ await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
292
265
  await this.updateHomeKitCharacteristics();
293
266
  })();
294
267
  /*if (switchbot !== false) {
@@ -304,7 +277,7 @@ export class RobotVacuumCleaner {
304
277
  `${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},` +
305
278
  ` BLE Address Found: ${ad.address}`,
306
279
  );
307
- this.BLE_On = ad.serviceData.state;
280
+ serviceData.state = ad.serviceData.state;
308
281
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
309
282
  this.debugLog(
310
283
  `${this.device.deviceType}: ${this.accessory.displayName} state: ${ad.serviceData.state}, ` +
@@ -344,20 +317,18 @@ export class RobotVacuumCleaner {
344
317
  async openAPIRefreshStatus() {
345
318
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
346
319
  try {
347
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
348
- headers: this.platform.generateHeaders(),
349
- });
320
+ const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
321
+ `${Devices}/${this.device.deviceId}/status`, {
322
+ headers: this.platform.generateHeaders(),
323
+ });
350
324
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
351
325
  const deviceStatus: any = await body.json();
352
326
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
353
327
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
354
328
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
355
- this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
329
+ this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
356
330
  + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
357
- this.OpenAPI_On = deviceStatus.body.power;
358
- this.OpenAPI_BatteryLevel = deviceStatus.body.battery;
359
- this.OpenAPI_FirmwareRevision = deviceStatus.body.version;
360
- this.openAPIparseStatus();
331
+ this.openAPIparseStatus(deviceStatus);
361
332
  this.updateHomeKitCharacteristics();
362
333
  } else {
363
334
  this.statusCode(statusCode);
@@ -405,8 +376,9 @@ export class RobotVacuumCleaner {
405
376
 
406
377
  async BLEpushChanges(): Promise<void> {
407
378
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
408
- if (this.On !== this.accessory.context.On) {
409
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges On: ${this.On} OnCached: ${this.accessory.context.On}`);
379
+ if (this.LightBulb.On !== this.accessory.context.On) {
380
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`
381
+ + ` On: ${this.LightBulb.On} OnCached: ${this.accessory.context.On}`);
410
382
  const switchbot = await this.platform.connectBLE();
411
383
  // Convert to BLE Address
412
384
  this.device.bleMac = this.device
@@ -420,11 +392,11 @@ export class RobotVacuumCleaner {
420
392
  id: this.device.bleMac,
421
393
  })
422
394
  .then(async (device_list: any) => {
423
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
424
- return await this.retry({
425
- max: this.maxRetry(),
395
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.LightBulb.On}`);
396
+ return await this.retryBLE({
397
+ max: await this.maxRetryBLE(),
426
398
  fn: async () => {
427
- if (this.On) {
399
+ if (this.LightBulb.On) {
428
400
  return await device_list[0].turnOn({ id: this.device.bleMac });
429
401
  } else {
430
402
  return await device_list[0].turnOff({ id: this.device.bleMac });
@@ -434,7 +406,9 @@ export class RobotVacuumCleaner {
434
406
  })
435
407
  .then(() => {
436
408
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
437
- this.On = false;
409
+ this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
410
+ + `On: ${this.LightBulb.On} sent over BLE, sent successfully`);
411
+ this.LightBulb.On = false;
438
412
  })
439
413
  .catch(async (e: any) => {
440
414
  this.apiError(e);
@@ -445,26 +419,15 @@ export class RobotVacuumCleaner {
445
419
  await this.BLEPushConnection();
446
420
  });
447
421
  } else {
448
- this.debugLog(
449
- `${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges.` + `On: ${this.On}, ` + `OnCached: ${this.accessory.context.On}`,
450
- );
422
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges,`
423
+ + ` On: ${this.LightBulb.On}, OnCached: ${this.accessory.context.On}`);
451
424
  }
452
425
  }
453
426
 
454
427
  async openAPIpushChanges() {
455
428
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
456
- if (this.On !== this.accessory.context.On) {
457
- let command = '';
458
- if (this.On) {
459
- command = 'turnOn';
460
- } else {
461
- command = 'turnOff';
462
- }
463
- const bodyChange = JSON.stringify({
464
- command: `${command}`,
465
- parameter: 'default',
466
- commandType: 'command',
467
- });
429
+ if (this.LightBulb.On !== this.accessory.context.On) {
430
+ const bodyChange = await this.commands();
468
431
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
469
432
  try {
470
433
  const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/commands`, {
@@ -480,6 +443,8 @@ export class RobotVacuumCleaner {
480
443
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
481
444
  this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
482
445
  + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
446
+ this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
447
+ + `request to SwitchBot API, body: ${JSON.stringify(bodyChange)} sent successfully`);
483
448
  } else {
484
449
  this.statusCode(statusCode);
485
450
  this.statusCode(deviceStatus.statusCode);
@@ -494,7 +459,7 @@ export class RobotVacuumCleaner {
494
459
  } else {
495
460
  this.debugLog(
496
461
  `${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges.` +
497
- `On: ${this.On}, ` +
462
+ `On: ${this.LightBulb.On}, ` +
498
463
  `OnCached: ${this.accessory.context.On}`,
499
464
  );
500
465
  }
@@ -502,10 +467,11 @@ export class RobotVacuumCleaner {
502
467
 
503
468
  async openAPIpushBrightnessChanges() {
504
469
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushBrightnessChanges`);
505
- const body = await this.brightnessCommands();
506
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${body},`);
470
+ const bodyChange = await this.brightnessCommands();
471
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
507
472
  try {
508
473
  const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/commands`, {
474
+ body: bodyChange,
509
475
  method: 'POST',
510
476
  headers: this.platform.generateHeaders(),
511
477
  });
@@ -514,8 +480,10 @@ export class RobotVacuumCleaner {
514
480
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
515
481
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
516
482
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
517
- this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
483
+ this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
518
484
  + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
485
+ this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
486
+ + `request to SwitchBot API, body: ${JSON.stringify(deviceStatus)} sent successfully`);
519
487
  } else {
520
488
  this.statusCode(statusCode);
521
489
  this.statusCode(deviceStatus.statusCode);
@@ -529,10 +497,10 @@ export class RobotVacuumCleaner {
529
497
  }
530
498
  }
531
499
 
532
- private commands() {
500
+ async commands() {
533
501
  let command: string;
534
502
  let parameter: string;
535
- if (this.On) {
503
+ if (this.LightBulb.On) {
536
504
  command = 'start';
537
505
  parameter = 'default';
538
506
  } else {
@@ -547,44 +515,44 @@ export class RobotVacuumCleaner {
547
515
  return body;
548
516
  }
549
517
 
550
- private brightnessCommands() {
518
+ async brightnessCommands(): Promise<string> {
551
519
  let command: string;
552
520
  let parameter: string;
553
- if (this.Brightness === 25) {
521
+ if (this.LightBulb.Brightness === 25) {
554
522
  command = 'PowLevel';
555
523
  parameter = '0';
556
- } else if (this.Brightness === 50) {
524
+ } else if (this.LightBulb.Brightness === 50) {
557
525
  command = 'PowLevel';
558
526
  parameter = '1';
559
- } else if (this.Brightness === 75) {
527
+ } else if (this.LightBulb.Brightness === 75) {
560
528
  command = 'PowLevel';
561
529
  parameter = '2';
562
- } else if (this.Brightness === 100) {
530
+ } else if (this.LightBulb.Brightness === 100) {
563
531
  command = 'PowLevel';
564
532
  parameter = '3';
565
533
  } else {
566
534
  command = 'dock';
567
535
  parameter = 'default';
568
536
  }
569
- const body = JSON.stringify({
537
+ const bodyChange = JSON.stringify({
570
538
  command: `${command}`,
571
539
  parameter: `${parameter}`,
572
540
  commandType: 'command',
573
541
  });
574
- return body;
542
+ return bodyChange;
575
543
  }
576
544
 
577
545
  /**
578
546
  * Handle requests to set the value of the "On" characteristic
579
547
  */
580
548
  async OnSet(value: CharacteristicValue): Promise<void> {
581
- if (this.On === this.accessory.context.On) {
549
+ if (this.LightBulb.On === this.accessory.context.On) {
582
550
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set On: ${value}`);
583
551
  } else {
584
552
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set On: ${value}`);
585
553
  }
586
554
 
587
- this.On = value;
555
+ this.LightBulb.On = value;
588
556
  this.doRobotVacuumCleanerUpdate.next();
589
557
  }
590
558
 
@@ -592,78 +560,51 @@ export class RobotVacuumCleaner {
592
560
  * Handle requests to set the value of the "Brightness" characteristic
593
561
  */
594
562
  async BrightnessSet(value: CharacteristicValue): Promise<void> {
595
- if (this.Brightness === this.accessory.context.Brightness) {
563
+ if (this.LightBulb.Brightness === this.accessory.context.Brightness) {
596
564
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set Brightness: ${value}`);
597
- } else if (this.On) {
565
+ } else if (this.LightBulb.On) {
598
566
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Brightness: ${value}`);
599
567
  } else {
600
568
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Brightness: ${value}`);
601
569
  }
602
570
 
603
- this.Brightness = value;
571
+ this.LightBulb.Brightness = value;
604
572
  this.doRobotVacuumCleanerUpdate.next();
605
573
  }
606
574
 
607
575
  async updateHomeKitCharacteristics(): Promise<void> {
608
576
  // On
609
- if (this.On === undefined) {
610
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
577
+ if (this.LightBulb.On === undefined) {
578
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.LightBulb.On}`);
611
579
  } else {
612
- this.accessory.context.On = this.On;
613
- this.robotVacuumCleanerService.updateCharacteristic(this.hap.Characteristic.On, this.On);
614
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
580
+ this.accessory.context.On = this.LightBulb.On;
581
+ this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.On, this.LightBulb.On);
582
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.LightBulb.On}`);
615
583
  }
616
584
  // Brightness
617
- if (this.Brightness === undefined) {
618
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Brightness: ${this.Brightness}`);
585
+ if (this.LightBulb.Brightness === undefined) {
586
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Brightness: ${this.LightBulb.Brightness}`);
619
587
  } else {
620
- this.accessory.context.Brightness = this.Brightness;
621
- this.robotVacuumCleanerService.updateCharacteristic(this.hap.Characteristic.Brightness, this.Brightness);
622
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Brightness: ${this.Brightness}`);
588
+ this.accessory.context.Brightness = this.LightBulb.Brightness;
589
+ this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.Brightness, this.LightBulb.Brightness);
590
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Brightness: ${this.LightBulb.Brightness}`);
623
591
  }
624
592
  // BatteryLevel
625
- if (this.BatteryLevel === undefined) {
626
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
593
+ if (this.Battery.BatteryLevel === undefined) {
594
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
627
595
  } else {
628
- this.accessory.context.BatteryLevel = this.BatteryLevel;
629
- this.batteryService?.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.BatteryLevel);
630
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
596
+ this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
597
+ this.Battery.Service?.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
598
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.Battery.BatteryLevel}`);
631
599
  }
632
600
  // StatusLowBattery
633
- if (this.StatusLowBattery === undefined) {
634
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
635
- } else {
636
- this.accessory.context.StatusLowBattery = this.StatusLowBattery;
637
- this.batteryService?.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.StatusLowBattery);
638
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
639
- }
640
- }
641
-
642
- async stopScanning(switchbot: any) {
643
- switchbot.stopScan();
644
- if (this.BLE_IsConnected) {
645
- await this.BLEparseStatus();
646
- await this.updateHomeKitCharacteristics();
601
+ if (this.Battery.StatusLowBattery === undefined) {
602
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
647
603
  } else {
648
- await this.BLERefreshConnection(switchbot);
649
- }
650
- }
651
-
652
- async getCustomBLEAddress(switchbot: any) {
653
- if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
654
- (async () => {
655
- // Start to monitor advertisement packets
656
- await switchbot.startScan({
657
- model: '?',
658
- });
659
- // Set an event handler
660
- switchbot.onadvertisement = (ad: any) => {
661
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
662
- };
663
- await sleep(10000);
664
- // Stop to monitor
665
- switchbot.stopScan();
666
- })();
604
+ this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
605
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
606
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
607
+ + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
667
608
  }
668
609
  }
669
610
 
@@ -683,266 +624,13 @@ export class RobotVacuumCleaner {
683
624
  }
684
625
  }
685
626
 
686
- async retry({ max, fn }: { max: number; fn: { (): any; (): Promise<any> } }): Promise<null> {
687
- return fn().catch(async (e: any) => {
688
- if (max === 0) {
689
- throw e;
690
- }
691
- this.infoLog(e);
692
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Retrying`);
693
- await sleep(1000);
694
- return this.retry({ max: max - 1, fn });
695
- });
696
- }
697
-
698
- maxRetry(): number {
699
- if (this.device.maxRetry) {
700
- return this.device.maxRetry;
701
- } else {
702
- return 5;
703
- }
704
- }
705
-
706
- model(device: device & devicesConfig): string {
707
- let model: string;
708
- if (device.deviceType === 'Robot Vacuum Cleaner S1 Plus') {
709
- model = 'W3011010';
710
- } else if (device.deviceType === 'Robot Vacuum Cleaner S1') {
711
- model = 'W3011000';
712
- } else {
713
- model = 'N/A';
714
- }
715
- return model;
716
- }
717
-
718
- async scan(device: device & devicesConfig): Promise<void> {
719
- if (device.scanDuration) {
720
- this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
721
- if (this.BLE) {
722
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
723
- }
724
- } else {
725
- this.scanDuration = this.accessory.context.scanDuration = 1;
726
- if (this.BLE) {
727
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
728
- }
729
- }
730
- }
731
-
732
- async statusCode(statusCode: number): Promise<void> {
733
- switch (statusCode) {
734
- case 151:
735
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
736
- break;
737
- case 152:
738
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
739
- break;
740
- case 160:
741
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
742
- break;
743
- case 161:
744
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
745
- this.offlineOff();
746
- break;
747
- case 171:
748
- this.errorLog(
749
- `${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. ` +
750
- `Hub: ${this.device.hubDeviceId}`,
751
- );
752
- this.offlineOff();
753
- break;
754
- case 190:
755
- this.errorLog(
756
- `${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
757
- ` Or command format is invalid, statusCode: ${statusCode}`,
758
- );
759
- break;
760
- case 100:
761
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
762
- break;
763
- case 200:
764
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
765
- break;
766
- case 400:
767
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Bad Request, The client has issued an invalid request. `
768
- + `This is commonly used to specify validation errors in a request payload, statusCode: ${statusCode}`);
769
- break;
770
- case 401:
771
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unauthorized, Authorization for the API is required, `
772
- + `but the request has not been authenticated, statusCode: ${statusCode}`);
773
- break;
774
- case 403:
775
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Forbidden, The request has been authenticated but does not `
776
- + `have appropriate permissions, or a requested resource is not found, statusCode: ${statusCode}`);
777
- break;
778
- case 404:
779
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Found, Specifies the requested path does not exist, `
780
- + `statusCode: ${statusCode}`);
781
- break;
782
- case 406:
783
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Acceptable, The client has requested a MIME type via `
784
- + `the Accept header for a value not supported by the server, statusCode: ${statusCode}`);
785
- break;
786
- case 415:
787
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unsupported Media Type, The client has defined a contentType `
788
- + `header that is not supported by the server, statusCode: ${statusCode}`);
789
- break;
790
- case 422:
791
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unprocessable Entity, The client has made a valid request, `
792
- + `but the server cannot process it. This is often used for APIs for which certain limits have been exceeded, statusCode: ${statusCode}`);
793
- break;
794
- case 429:
795
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Too Many Requests, The client has exceeded the number of `
796
- + `requests allowed for a given time window, statusCode: ${statusCode}`);
797
- break;
798
- case 500:
799
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Internal Server Error, An unexpected error on the SmartThings `
800
- + `servers has occurred. These errors should be rare, statusCode: ${statusCode}`);
801
- break;
802
- default:
803
- this.infoLog(
804
- `${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: ` +
805
- `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`,
806
- );
807
- }
808
- }
809
-
810
627
  async offlineOff(): Promise<void> {
811
628
  if (this.device.offline) {
812
- await this.deviceContext();
813
- await this.updateHomeKitCharacteristics();
629
+ this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.On, false);
814
630
  }
815
631
  }
816
632
 
817
633
  async apiError(e: any): Promise<void> {
818
- this.robotVacuumCleanerService.updateCharacteristic(this.hap.Characteristic.On, e);
819
- }
820
-
821
- async deviceContext() {
822
- if (this.On === undefined) {
823
- this.On = false;
824
- } else {
825
- this.On = this.accessory.context.On;
826
- }
827
- if (this.Brightness === undefined) {
828
- this.Brightness = 0;
829
- } else {
830
- this.Brightness = this.accessory.context.Brightness;
831
- }
832
- if (this.FirmwareRevision === undefined) {
833
- this.FirmwareRevision = this.platform.version;
834
- this.accessory.context.FirmwareRevision = this.FirmwareRevision;
835
- }
836
- }
837
-
838
- async refreshRate(device: device & devicesConfig): Promise<void> {
839
- if (device.refreshRate) {
840
- this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
841
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
842
- } else if (this.platform.config.options!.refreshRate) {
843
- this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
844
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
845
- }
846
- }
847
-
848
- async deviceConfig(device: device & devicesConfig): Promise<void> {
849
- let config = {};
850
- if (device.plug) {
851
- config = device.plug;
852
- }
853
- if (device.connectionType !== undefined) {
854
- config['connectionType'] = device.connectionType;
855
- }
856
- if (device.external !== undefined) {
857
- config['external'] = device.external;
858
- }
859
- if (device.logging !== undefined) {
860
- config['logging'] = device.logging;
861
- }
862
- if (device.refreshRate !== undefined) {
863
- config['refreshRate'] = device.refreshRate;
864
- }
865
- if (device.scanDuration !== undefined) {
866
- config['scanDuration'] = device.scanDuration;
867
- }
868
- if (device.offline !== undefined) {
869
- config['offline'] = device.offline;
870
- }
871
- if (device.maxRetry !== undefined) {
872
- config['maxRetry'] = device.maxRetry;
873
- }
874
- if (device.webhook !== undefined) {
875
- config['webhook'] = device.webhook;
876
- }
877
- if (Object.entries(config).length !== 0) {
878
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
879
- }
880
- }
881
-
882
- async deviceLogs(device: device & devicesConfig): Promise<void> {
883
- if (this.platform.debugMode) {
884
- this.deviceLogging = this.accessory.context.logging = 'debugMode';
885
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
886
- } else if (device.logging) {
887
- this.deviceLogging = this.accessory.context.logging = device.logging;
888
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
889
- } else if (this.platform.config.options?.logging) {
890
- this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
891
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
892
- } else {
893
- this.deviceLogging = this.accessory.context.logging = 'standard';
894
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
895
- }
896
- }
897
-
898
- /**
899
- * Logging for Device
900
- */
901
- infoLog(...log: any[]): void {
902
- if (this.enablingDeviceLogging()) {
903
- this.platform.log.info(String(...log));
904
- }
905
- }
906
-
907
- warnLog(...log: any[]): void {
908
- if (this.enablingDeviceLogging()) {
909
- this.platform.log.warn(String(...log));
910
- }
911
- }
912
-
913
- debugWarnLog(...log: any[]): void {
914
- if (this.enablingDeviceLogging()) {
915
- if (this.deviceLogging?.includes('debug')) {
916
- this.platform.log.warn('[DEBUG]', String(...log));
917
- }
918
- }
919
- }
920
-
921
- errorLog(...log: any[]): void {
922
- if (this.enablingDeviceLogging()) {
923
- this.platform.log.error(String(...log));
924
- }
925
- }
926
-
927
- debugErrorLog(...log: any[]): void {
928
- if (this.enablingDeviceLogging()) {
929
- if (this.deviceLogging?.includes('debug')) {
930
- this.platform.log.error('[DEBUG]', String(...log));
931
- }
932
- }
933
- }
934
-
935
- debugLog(...log: any[]): void {
936
- if (this.enablingDeviceLogging()) {
937
- if (this.deviceLogging === 'debug') {
938
- this.platform.log.info('[DEBUG]', String(...log));
939
- } else {
940
- this.platform.log.debug(String(...log));
941
- }
942
- }
943
- }
944
-
945
- enablingDeviceLogging(): boolean {
946
- return this.deviceLogging.includes('debug') || this.deviceLogging === 'standard';
634
+ this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.On, e);
947
635
  }
948
636
  }