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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/dist/device/blindtilt.d.ts +15 -6
  2. package/dist/device/blindtilt.d.ts.map +1 -1
  3. package/dist/device/blindtilt.js +203 -255
  4. package/dist/device/blindtilt.js.map +1 -1
  5. package/dist/device/bot.d.ts +9 -4
  6. package/dist/device/bot.d.ts.map +1 -1
  7. package/dist/device/bot.js +196 -218
  8. package/dist/device/bot.js.map +1 -1
  9. package/dist/device/ceilinglight.d.ts +9 -4
  10. package/dist/device/ceilinglight.d.ts.map +1 -1
  11. package/dist/device/ceilinglight.js +202 -247
  12. package/dist/device/ceilinglight.js.map +1 -1
  13. package/dist/device/colorbulb.d.ts +10 -5
  14. package/dist/device/colorbulb.d.ts.map +1 -1
  15. package/dist/device/colorbulb.js +329 -378
  16. package/dist/device/colorbulb.js.map +1 -1
  17. package/dist/device/contact.d.ts +9 -4
  18. package/dist/device/contact.d.ts.map +1 -1
  19. package/dist/device/contact.js +99 -142
  20. package/dist/device/contact.js.map +1 -1
  21. package/dist/device/curtain.d.ts +19 -7
  22. package/dist/device/curtain.d.ts.map +1 -1
  23. package/dist/device/curtain.js +203 -264
  24. package/dist/device/curtain.js.map +1 -1
  25. package/dist/device/device.d.ts +28 -32
  26. package/dist/device/device.d.ts.map +1 -1
  27. package/dist/device/device.js +186 -225
  28. package/dist/device/device.js.map +1 -1
  29. package/dist/device/fan.d.ts +9 -4
  30. package/dist/device/fan.d.ts.map +1 -1
  31. package/dist/device/fan.js +198 -227
  32. package/dist/device/fan.js.map +1 -1
  33. package/dist/device/hub.d.ts +9 -5
  34. package/dist/device/hub.d.ts.map +1 -1
  35. package/dist/device/hub.js +106 -231
  36. package/dist/device/hub.js.map +1 -1
  37. package/dist/device/humidifier.d.ts +12 -4
  38. package/dist/device/humidifier.d.ts.map +1 -1
  39. package/dist/device/humidifier.js +192 -232
  40. package/dist/device/humidifier.js.map +1 -1
  41. package/dist/device/iosensor.d.ts +9 -4
  42. package/dist/device/iosensor.d.ts.map +1 -1
  43. package/dist/device/iosensor.js +91 -157
  44. package/dist/device/iosensor.js.map +1 -1
  45. package/dist/device/lightstrip.d.ts +10 -5
  46. package/dist/device/lightstrip.d.ts.map +1 -1
  47. package/dist/device/lightstrip.js +287 -367
  48. package/dist/device/lightstrip.js.map +1 -1
  49. package/dist/device/lock.d.ts +10 -5
  50. package/dist/device/lock.d.ts.map +1 -1
  51. package/dist/device/lock.js +171 -216
  52. package/dist/device/lock.js.map +1 -1
  53. package/dist/device/meter.d.ts +9 -4
  54. package/dist/device/meter.d.ts.map +1 -1
  55. package/dist/device/meter.js +93 -158
  56. package/dist/device/meter.js.map +1 -1
  57. package/dist/device/meterplus.d.ts +9 -4
  58. package/dist/device/meterplus.d.ts.map +1 -1
  59. package/dist/device/meterplus.js +94 -155
  60. package/dist/device/meterplus.js.map +1 -1
  61. package/dist/device/motion.d.ts +9 -4
  62. package/dist/device/motion.d.ts.map +1 -1
  63. package/dist/device/motion.js +84 -142
  64. package/dist/device/motion.js.map +1 -1
  65. package/dist/device/plug.d.ts +9 -4
  66. package/dist/device/plug.d.ts.map +1 -1
  67. package/dist/device/plug.js +99 -124
  68. package/dist/device/plug.js.map +1 -1
  69. package/dist/device/robotvacuumcleaner.d.ts +9 -6
  70. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  71. package/dist/device/robotvacuumcleaner.js +170 -253
  72. package/dist/device/robotvacuumcleaner.js.map +1 -1
  73. package/dist/device/waterdetector.d.ts +12 -4
  74. package/dist/device/waterdetector.d.ts.map +1 -1
  75. package/dist/device/waterdetector.js +102 -128
  76. package/dist/device/waterdetector.js.map +1 -1
  77. package/dist/irdevice/airconditioner.d.ts +2 -1
  78. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  79. package/dist/irdevice/airconditioner.js.map +1 -1
  80. package/dist/irdevice/airpurifier.d.ts +2 -1
  81. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  82. package/dist/irdevice/airpurifier.js.map +1 -1
  83. package/dist/irdevice/camera.d.ts +2 -1
  84. package/dist/irdevice/camera.d.ts.map +1 -1
  85. package/dist/irdevice/camera.js.map +1 -1
  86. package/dist/irdevice/fan.d.ts +2 -1
  87. package/dist/irdevice/fan.d.ts.map +1 -1
  88. package/dist/irdevice/fan.js.map +1 -1
  89. package/dist/irdevice/irdevice.d.ts +2 -1
  90. package/dist/irdevice/irdevice.d.ts.map +1 -1
  91. package/dist/irdevice/irdevice.js +1 -1
  92. package/dist/irdevice/irdevice.js.map +1 -1
  93. package/dist/irdevice/light.d.ts +2 -1
  94. package/dist/irdevice/light.d.ts.map +1 -1
  95. package/dist/irdevice/light.js.map +1 -1
  96. package/dist/irdevice/other.d.ts +2 -1
  97. package/dist/irdevice/other.d.ts.map +1 -1
  98. package/dist/irdevice/other.js.map +1 -1
  99. package/dist/irdevice/tv.d.ts +2 -1
  100. package/dist/irdevice/tv.d.ts.map +1 -1
  101. package/dist/irdevice/tv.js.map +1 -1
  102. package/dist/irdevice/vacuumcleaner.d.ts +2 -1
  103. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  104. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  105. package/dist/irdevice/waterheater.d.ts +2 -1
  106. package/dist/irdevice/waterheater.d.ts.map +1 -1
  107. package/dist/irdevice/waterheater.js.map +1 -1
  108. package/dist/platform.d.ts +5 -7
  109. package/dist/platform.d.ts.map +1 -1
  110. package/dist/platform.js +51 -34
  111. package/dist/platform.js.map +1 -1
  112. package/dist/settings.d.ts +49 -191
  113. package/dist/settings.d.ts.map +1 -1
  114. package/dist/settings.js +19 -0
  115. package/dist/settings.js.map +1 -1
  116. package/dist/types/bledevicestatus.d.ts +279 -0
  117. package/dist/types/bledevicestatus.d.ts.map +1 -0
  118. package/dist/types/bledevicestatus.js +2 -0
  119. package/dist/types/bledevicestatus.js.map +1 -0
  120. package/dist/types/devicelist.d.ts +89 -0
  121. package/dist/types/devicelist.d.ts.map +1 -0
  122. package/dist/types/devicelist.js +6 -0
  123. package/dist/types/devicelist.js.map +1 -0
  124. package/dist/types/deviceresponse.d.ts +13 -0
  125. package/dist/types/deviceresponse.d.ts.map +1 -0
  126. package/dist/types/deviceresponse.js +2 -0
  127. package/dist/types/deviceresponse.js.map +1 -0
  128. package/dist/types/devicestatus.d.ts +149 -0
  129. package/dist/types/devicestatus.d.ts.map +1 -0
  130. package/dist/types/devicestatus.js +3 -0
  131. package/dist/types/devicestatus.js.map +1 -0
  132. package/dist/types/devicewebhookstatus.d.ts +156 -0
  133. package/dist/types/devicewebhookstatus.d.ts.map +1 -0
  134. package/dist/types/devicewebhookstatus.js +2 -0
  135. package/dist/types/devicewebhookstatus.js.map +1 -0
  136. package/dist/types/irdevicelist.d.ts +10 -0
  137. package/dist/types/irdevicelist.d.ts.map +1 -0
  138. package/dist/types/irdevicelist.js +2 -0
  139. package/dist/types/irdevicelist.js.map +1 -0
  140. package/dist/types/pushbody.d.ts +6 -0
  141. package/dist/types/pushbody.d.ts.map +1 -0
  142. package/dist/types/pushbody.js +2 -0
  143. package/dist/types/pushbody.js.map +1 -0
  144. package/dist/utils.d.ts +25 -0
  145. package/dist/utils.d.ts.map +1 -1
  146. package/dist/utils.js +28 -0
  147. package/dist/utils.js.map +1 -1
  148. package/package.json +10 -10
  149. package/src/device/blindtilt.ts +223 -263
  150. package/src/device/bot.ts +208 -221
  151. package/src/device/ceilinglight.ts +210 -257
  152. package/src/device/colorbulb.ts +334 -397
  153. package/src/device/contact.ts +111 -146
  154. package/src/device/curtain.ts +220 -283
  155. package/src/device/device.ts +194 -245
  156. package/src/device/fan.ts +214 -230
  157. package/src/device/hub.ts +126 -246
  158. package/src/device/humidifier.ts +216 -243
  159. package/src/device/iosensor.ts +114 -166
  160. package/src/device/lightstrip.ts +302 -377
  161. package/src/device/lock.ts +187 -221
  162. package/src/device/meter.ts +116 -177
  163. package/src/device/meterplus.ts +117 -174
  164. package/src/device/motion.ts +99 -144
  165. package/src/device/plug.ts +110 -128
  166. package/src/device/robotvacuumcleaner.ts +189 -252
  167. package/src/device/waterdetector.ts +120 -138
  168. package/src/irdevice/airconditioner.ts +2 -1
  169. package/src/irdevice/airpurifier.ts +2 -1
  170. package/src/irdevice/camera.ts +2 -1
  171. package/src/irdevice/fan.ts +2 -1
  172. package/src/irdevice/irdevice.ts +3 -2
  173. package/src/irdevice/light.ts +2 -1
  174. package/src/irdevice/other.ts +2 -1
  175. package/src/irdevice/tv.ts +2 -1
  176. package/src/irdevice/vacuumcleaner.ts +2 -1
  177. package/src/irdevice/waterheater.ts +2 -1
  178. package/src/platform.ts +52 -34
  179. package/src/settings.ts +30 -239
  180. package/src/types/bledevicestatus.ts +305 -0
  181. package/src/types/devicelist.ts +124 -0
  182. package/src/types/deviceresponse.ts +15 -0
  183. package/src/types/devicestatus.ts +178 -0
  184. package/src/types/devicewebhookstatus.ts +196 -0
  185. package/src/types/irdevicelist.ts +15 -0
  186. package/src/types/pushbody.ts +9 -0
  187. package/src/utils.ts +33 -0
@@ -3,12 +3,20 @@
3
3
  * robotvacuumcleaner.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
5
  import { deviceBase } from './device.js';
6
- import { Subject, interval, skipWhile } from 'rxjs';
7
- import { debounceTime, take, tap } from 'rxjs/operators';
6
+ import { SwitchBotBLEModel, SwitchBotBLEModelName } from 'node-switchbot';
7
+ import { Subject, debounceTime, interval, skipWhile, take, tap } from 'rxjs';
8
8
 
9
+ import type { devicesConfig } from '../settings.js';
10
+ import type { device } from '../types/devicelist.js';
9
11
  import type { SwitchBotPlatform } from '../platform.js';
12
+ import type { robotVacuumCleanerServiceData } from '../types/bledevicestatus.js';
10
13
  import type { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
11
- import type { device, devicesConfig, serviceData, deviceStatus } from '../settings.js';
14
+ import type { robotVacuumCleanerS1Status, robotVacuumCleanerS1PlusStatus, floorCleaningRobotS10Status } from '../types/devicestatus.js';
15
+ import type {
16
+ floorCleaningRobotS10WebhookContext,
17
+ robotVacuumCleanerS1PlusWebhookContext,
18
+ robotVacuumCleanerS1WebhookContext,
19
+ } from '../types/devicewebhookstatus.js';
12
20
 
13
21
  export class RobotVacuumCleaner extends deviceBase {
14
22
  // Services
@@ -108,9 +116,13 @@ export class RobotVacuumCleaner extends deviceBase {
108
116
 
109
117
  // Retrieve initial values and updateHomekit
110
118
  this.refreshStatus();
119
+
111
120
  // Update Homekit
112
121
  this.updateHomeKitCharacteristics();
113
122
 
123
+ //regisiter webhook event handler
124
+ this.registerWebhook();
125
+
114
126
  // Start an update interval
115
127
  interval(this.deviceRefreshRate * 1000)
116
128
  .pipe(skipWhile(() => this.robotVacuumCleanerUpdateInProgress))
@@ -118,9 +130,6 @@ export class RobotVacuumCleaner extends deviceBase {
118
130
  await this.refreshStatus();
119
131
  });
120
132
 
121
- //regisiter webhook event handler
122
- this.registerWebhook(accessory, device);
123
-
124
133
  // Watch for Plug change events
125
134
  // We put in a debounce of 100ms so we don't make duplicate calls
126
135
  this.doRobotVacuumCleanerUpdate
@@ -134,71 +143,48 @@ export class RobotVacuumCleaner extends deviceBase {
134
143
  try {
135
144
  await this.pushChanges();
136
145
  } catch (e: any) {
137
- this.apiError(e);
138
- this.errorLog(`${device.deviceType}: ${accessory.displayName} failed pushChanges with ${device.connectionType} Connection,`
139
- + ` Error Message: ${JSON.stringify(e.message)}`);
146
+ await this.apiError(e);
147
+ await this.errorLog(`failed pushChanges with ${device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
140
148
  }
141
149
  this.robotVacuumCleanerUpdateInProgress = false;
142
150
  });
143
151
  }
144
152
 
145
- async BLEparseStatus(serviceData: serviceData): Promise<void> {
146
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
147
-
148
- // Battery
153
+ async BLEparseStatus(serviceData: robotVacuumCleanerServiceData): Promise<void> {
154
+ await this.debugLog('BLEparseStatus');
155
+ // On
156
+ this.LightBulb.On = serviceData.state === 'on' ? true : false;
157
+ await this.debugLog(`On: ${this.LightBulb.On}`);
158
+ // BatteryLevel
149
159
  this.Battery.BatteryLevel = Number(serviceData.battery);
150
- if (this.Battery.BatteryLevel < 10) {
151
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
152
- } else {
153
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
154
- }
155
- this.debugLog(`${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}, StatusLowBattery: ${this.Battery.StatusLowBattery}`);
156
-
157
- // State
158
- switch (serviceData.state) {
159
- case 'on':
160
- this.LightBulb.On = true;
161
- break;
162
- default:
163
- this.LightBulb.On = false;
164
- }
165
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.LightBulb.On}`);
160
+ await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
161
+ // StatusLowBattery
162
+ this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
163
+ ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
164
+ await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`);
166
165
  }
167
166
 
168
- async openAPIparseStatus(deviceStatus: deviceStatus) {
169
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
170
- switch (deviceStatus.body.power) {
171
- case 'on':
172
- this.LightBulb.On = true;
173
- break;
174
- default:
175
- this.LightBulb.On = false;
176
- }
177
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.LightBulb.On}`);
178
-
167
+ async openAPIparseStatus(deviceStatus: robotVacuumCleanerS1Status | robotVacuumCleanerS1PlusStatus | floorCleaningRobotS10Status) {
168
+ await this.debugLog('openAPIparseStatus');
169
+ // On
170
+ this.LightBulb.On = deviceStatus.onlineStatus === 'online' ? true : false;
171
+ await this.debugLog(`On: ${this.LightBulb.On}`);
179
172
  // BatteryLevel
180
- this.Battery.BatteryLevel = Number(deviceStatus.body.battery);
181
-
173
+ this.Battery.BatteryLevel = Number(deviceStatus.battery);
174
+ await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
182
175
  // StatusLowBattery
183
- if (this.Battery.BatteryLevel < 10) {
184
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
185
- } else {
186
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
187
- }
188
- if (Number.isNaN(this.Battery.BatteryLevel)) {
189
- this.Battery.BatteryLevel = 100;
190
- }
176
+ this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
177
+ ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
178
+ await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`);
191
179
  // ChargingState
192
- this.Battery.ChargingState = deviceStatus.body.workingStatus === 'Charging'
180
+ this.Battery.ChargingState = deviceStatus.workingStatus === 'Charging'
193
181
  ? this.hap.Characteristic.ChargingState.CHARGING : this.hap.Characteristic.ChargingState.NOT_CHARGING;
194
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
195
- + ` StatusLowBattery: ${this.Battery.StatusLowBattery}, ChargingState: ${this.Battery.ChargingState}`);
196
-
182
+ await this.debugLog(`ChargingState: ${this.Battery.ChargingState}`);
197
183
  // Firmware Version
198
- const version = deviceStatus.body.version?.toString();
199
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Firmware Version: ${version?.replace(/^V|-.*$/g, '')}`);
200
- if (deviceStatus.body.version) {
201
- const deviceVersion = version?.replace(/^V|-.*$/g, '') ?? '0.0.0';
184
+ if (deviceStatus.version) {
185
+ const version = deviceStatus.version.toString();
186
+ await this.debugLog(`Firmware Version: ${version.replace(/^V|-.*$/g, '')}`);
187
+ const deviceVersion = version.replace(/^V|-.*$/g, '') ?? '0.0.0';
202
188
  this.accessory
203
189
  .getService(this.hap.Service.AccessoryInformation)!
204
190
  .setCharacteristic(this.hap.Characteristic.HardwareRevision, deviceVersion)
@@ -206,29 +192,49 @@ export class RobotVacuumCleaner extends deviceBase {
206
192
  .getCharacteristic(this.hap.Characteristic.FirmwareRevision)
207
193
  .updateValue(deviceVersion);
208
194
  this.accessory.context.deviceVersion = deviceVersion;
209
- this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceVersion: ${this.accessory.context.deviceVersion}`);
195
+ await this.debugSuccessLog(`deviceVersion: ${this.accessory.context.deviceVersion}`);
210
196
  }
211
197
  }
212
198
 
199
+ async parseStatusWebhook(context: robotVacuumCleanerS1WebhookContext | robotVacuumCleanerS1PlusWebhookContext
200
+ | floorCleaningRobotS10WebhookContext): Promise<void> {
201
+ await this.debugLog('parseStatusWebhook');
202
+ await this.debugLog(`(onlineStatus, battery, workingStatus) = Webhook: (${context.onlineStatus}, ${context.battery}, ${context.workingStatus}),`
203
+ + ` current: (${this.LightBulb.On}, ${this.Battery.BatteryLevel}, ${this.Battery.ChargingState})`);
204
+ // On
205
+ this.LightBulb.On = context.onlineStatus === 'online' ? true : false;
206
+ await this.debugLog(`On: ${this.LightBulb.On}`);
207
+ // BatteryLevel
208
+ this.Battery.BatteryLevel = Number(context.battery);
209
+ await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
210
+ // StatusLowBattery
211
+ this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
212
+ ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
213
+ await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`);
214
+ // ChargingState
215
+ this.Battery.ChargingState = context.workingStatus === 'Charging'
216
+ ? this.hap.Characteristic.ChargingState.CHARGING : this.hap.Characteristic.ChargingState.NOT_CHARGING;
217
+ await this.debugLog(`ChargingState: ${this.Battery.ChargingState}`);
218
+ }
219
+
213
220
  /**
214
221
  * Asks the SwitchBot API for the latest device information
215
222
  */
216
223
  async refreshStatus(): Promise<void> {
217
224
  if (!this.device.enableCloudService && this.OpenAPI) {
218
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} refreshStatus enableCloudService: ${this.device.enableCloudService}`);
225
+ await this.errorLog(`refreshStatus enableCloudService: ${this.device.enableCloudService}`);
219
226
  } else if (this.BLE) {
220
227
  await this.BLERefreshStatus();
221
228
  } else if (this.OpenAPI && this.platform.config.credentials?.token) {
222
229
  await this.openAPIRefreshStatus();
223
230
  } else {
224
231
  await this.offlineOff();
225
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
226
- + ` ${this.device.connectionType}, refreshStatus will not happen.`);
232
+ await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, refreshStatus will not happen.`);
227
233
  }
228
234
  }
229
235
 
230
236
  async BLERefreshStatus(): Promise<void> {
231
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
237
+ await this.debugLog('BLERefreshStatus');
232
238
  const switchbot = await this.switchbotBLE();
233
239
 
234
240
  if (switchbot === undefined) {
@@ -237,13 +243,13 @@ export class RobotVacuumCleaner extends deviceBase {
237
243
  // Start to monitor advertisement packets
238
244
  (async () => {
239
245
  // Start to monitor advertisement packets
240
- const serviceData: serviceData = await this.monitorAdvertisementPackets(switchbot);
246
+ const serviceData = await this.monitorAdvertisementPackets(switchbot) as unknown as robotVacuumCleanerServiceData;
241
247
  // Update HomeKit
242
- if (serviceData.model !== '' && serviceData.modelName !== '') {
248
+ if (serviceData.model === SwitchBotBLEModel.Unknown && serviceData.modelName === SwitchBotBLEModelName.Unknown) {
243
249
  await this.BLEparseStatus(serviceData);
244
250
  await this.updateHomeKitCharacteristics();
245
251
  } else {
246
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
252
+ await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
247
253
  await this.BLERefreshConnection(switchbot);
248
254
  }
249
255
  })();
@@ -251,46 +257,40 @@ export class RobotVacuumCleaner extends deviceBase {
251
257
  }
252
258
 
253
259
  async openAPIRefreshStatus(): Promise<void> {
254
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
260
+ await this.debugLog('openAPIRefreshStatus');
255
261
  try {
256
262
  const { body, statusCode } = await this.deviceRefreshStatus();
257
263
  const deviceStatus: any = await body.json();
258
- await this.refreshStatusCodes(statusCode, deviceStatus);;
259
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
260
- await this.successfulRefreshStatus(statusCode, deviceStatus);
261
- await this.openAPIparseStatus(deviceStatus);
264
+ await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);;
265
+ if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
266
+ await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
267
+ await this.openAPIparseStatus(deviceStatus.body);
262
268
  await this.updateHomeKitCharacteristics();
263
269
  } else {
264
- await this.statusCodes(statusCode, deviceStatus);
270
+ await this.debugWarnLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
271
+ await this.debugWarnLog(statusCode, deviceStatus);
265
272
  }
266
273
  } catch (e: any) {
267
274
  await this.apiError(e);
268
- await this.openAPIRefreshError(e);
275
+ await this.errorLog(`failed openAPIRefreshStatus with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
269
276
  }
270
277
  }
271
278
 
272
- async registerWebhook(accessory: PlatformAccessory, device: device & devicesConfig) {
273
- if (device.webhook) {
274
- this.debugLog(`${device.deviceType}: ${accessory.displayName} is listening webhook.`);
275
- this.platform.webhookEventHandler[device.deviceId] = async (context) => {
279
+ async registerWebhook() {
280
+ if (this.device.webhook) {
281
+ await this.debugLog('is listening webhook.');
282
+ this.platform.webhookEventHandler[this.device.deviceId] = async (context: robotVacuumCleanerS1WebhookContext
283
+ | robotVacuumCleanerS1PlusWebhookContext | floorCleaningRobotS10WebhookContext) => {
276
284
  try {
277
- this.debugLog(`${device.deviceType}: ${accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
278
- const { onlineStatus, battery, workingStatus } = context;
279
- const { On } = this.LightBulb;
280
- const { BatteryLevel, ChargingState } = this.Battery;
281
- this.debugLog(`${device.deviceType}: ${accessory.displayName} (onlineStatus, battery, workingStatus) = `
282
- + `Webhook: (${onlineStatus}, ${battery}, ${workingStatus}), current: (${On}, ${BatteryLevel}, ${ChargingState})`);
283
- this.LightBulb.On = onlineStatus === 'online' ? true : false;
284
- this.Battery.ChargingState = workingStatus === 'Charging'
285
- ? this.hap.Characteristic.ChargingState.CHARGING : this.hap.Characteristic.ChargingState.NOT_CHARGING;
286
- this.Battery.BatteryLevel = battery;
287
- this.updateHomeKitCharacteristics();
285
+ await this.debugLog(`received Webhook: ${JSON.stringify(context)}`);
286
+ await this.parseStatusWebhook(context);
287
+ await this.updateHomeKitCharacteristics();
288
288
  } catch (e: any) {
289
- this.errorLog(`${device.deviceType}: ${accessory.displayName} failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
289
+ await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
290
290
  }
291
291
  };
292
292
  } else {
293
- this.debugLog(`${device.deviceType}: ${accessory.displayName} is not listening webhook.`);
293
+ await this.debugLog('is not listening webhook.');
294
294
  }
295
295
  }
296
296
 
@@ -302,17 +302,16 @@ export class RobotVacuumCleaner extends deviceBase {
302
302
  * Robot Vacuum Cleaner S1 "command" "dock" "default" = return to charging dock
303
303
  * Robot Vacuum Cleaner S1 "command" "PowLevel" "{0-3}" = set suction power level: 0 (Quiet), 1 (Standard), 2 (Strong), 3 (MAX)
304
304
  */
305
-
306
305
  async pushChanges(): Promise<void> {
307
306
  if (!this.device.enableCloudService && this.OpenAPI) {
308
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} pushChanges enableCloudService: ${this.device.enableCloudService}`);
307
+ await this.errorLog(`pushChanges enableCloudService: ${this.device.enableCloudService}`);
309
308
  } else if (this.BLE) {
310
309
  await this.BLEpushChanges();
311
310
  } else if (this.OpenAPI && this.platform.config.credentials?.token) {
312
311
  await this.openAPIpushChanges();
313
312
  } else {
314
313
  await this.offlineOff();
315
- await this.pushChangeDisabled();
314
+ await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, pushChanges will not happen.`);
316
315
  }
317
316
  // Refresh the status from the API
318
317
  interval(15000)
@@ -324,151 +323,115 @@ export class RobotVacuumCleaner extends deviceBase {
324
323
  }
325
324
 
326
325
  async BLEpushChanges(): Promise<void> {
327
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
326
+ await this.debugLog('BLEpushChanges');
328
327
  if (this.LightBulb.On !== this.accessory.context.On) {
329
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`
330
- + ` On: ${this.LightBulb.On} OnCached: ${this.accessory.context.On}`);
331
- const switchbot = await this.platform.connectBLE();
332
- // Convert to BLE Address
328
+ const switchbot = await this.platform.connectBLE(this.accessory, this.device);
333
329
  await this.convertBLEAddress();
334
- switchbot
335
- .discover({
336
- model: '?',
337
- id: this.device.bleMac,
338
- })
339
- .then(async (device_list: any) => {
340
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.LightBulb.On}`);
341
- return await this.retryBLE({
342
- max: await this.maxRetryBLE(),
343
- fn: async () => {
344
- if (this.LightBulb.On) {
345
- return await device_list[0].turnOn({ id: this.device.bleMac });
346
- } else {
347
- return await device_list[0].turnOff({ id: this.device.bleMac });
348
- }
349
- },
330
+ if (switchbot !== false) {
331
+ switchbot
332
+ .discover({ model: this.device.bleModel, id: this.device.bleMac })
333
+ .then(async (device_list: any) => {
334
+ await this.infoLog(`On: ${this.LightBulb.On}`);
335
+ return await this.retryBLE({
336
+ max: await this.maxRetryBLE(),
337
+ fn: async () => {
338
+ if (this.LightBulb.On) {
339
+ return await device_list[0].turnOn({ id: this.device.bleMac });
340
+ } else {
341
+ return await device_list[0].turnOff({ id: this.device.bleMac });
342
+ }
343
+ },
344
+ });
345
+ })
346
+ .then(async () => {
347
+ await this.successLog(`On: ${this.LightBulb.On} sent over SwitchBot BLE, sent successfully`);
348
+ await this.updateHomeKitCharacteristics();
349
+ })
350
+ .catch(async (e: any) => {
351
+ await this.apiError(e);
352
+ await this.errorLog(`failed BLEpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
353
+ await this.BLEPushConnection();
350
354
  });
351
- })
352
- .then(() => {
353
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
354
- this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
355
- + `On: ${this.LightBulb.On} sent over BLE, sent successfully`);
356
- this.LightBulb.On = false;
357
- })
358
- .catch(async (e: any) => {
359
- this.apiError(e);
360
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
361
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
362
- await this.BLEPushConnection();
363
- });
355
+ } else {
356
+ await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
357
+ await this.BLEPushConnection();
358
+ }
364
359
  } else {
365
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges,`
366
- + ` On: ${this.LightBulb.On}, OnCached: ${this.accessory.context.On}`);
360
+ await this.debugLog(`No changes (BLEpushChanges), On: ${this.LightBulb.On}, OnCached: ${this.accessory.context.On}`);
367
361
  }
368
362
  }
369
363
 
370
364
  async openAPIpushChanges() {
371
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
365
+ await this.debugLog('openAPIpushChanges');
372
366
  if (this.LightBulb.On !== this.accessory.context.On) {
373
- const bodyChange = await this.commands();
374
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
367
+ const command = this.LightBulb.On ? 'start' : 'dock';
368
+ const bodyChange = JSON.stringify({
369
+ command: `${command}`,
370
+ parameter: 'default',
371
+ commandType: 'command',
372
+ });
373
+ await this.debugLog(`SwitchBot OpenAPI bodyChange: ${JSON.stringify(bodyChange)}`);
375
374
  try {
376
375
  const { body, statusCode } = await this.pushChangeRequest(bodyChange);
377
376
  const deviceStatus: any = await body.json();
378
- await this.pushStatusCodes(statusCode, deviceStatus);
379
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
380
- this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
381
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
382
- this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
383
- + `request to SwitchBot API, body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
377
+ await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
378
+ if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
379
+ await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
380
+ await this.updateHomeKitCharacteristics();
384
381
  } else {
385
- this.statusCode(statusCode);
386
- this.statusCode(deviceStatus.statusCode);
382
+ await this.statusCode(statusCode);
383
+ await this.statusCode(deviceStatus.statusCode);
387
384
  }
388
385
  } catch (e: any) {
389
386
  await this.apiError(e);
390
- await this.pushChangeError('openAPIpushChanges', e);
387
+ await this.errorLog(`failed openAPIpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
391
388
  }
392
389
  } else {
393
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges, On: ${this.LightBulb.On}, `
394
- + `OnCached: ${this.accessory.context.On}`);
390
+ await this.debugLog(`No changes (openAPIpushChanges), On: ${this.LightBulb.On}, OnCached: ${this.accessory.context.On}`);
395
391
  }
396
392
  }
397
393
 
398
394
  async openAPIpushBrightnessChanges() {
399
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushBrightnessChanges`);
400
- const bodyChange = await this.brightnessCommands();
401
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
402
- try {
403
- const { body, statusCode } = await this.pushChangeRequest(bodyChange);
404
- const deviceStatus: any = await body.json();
405
- await this.refreshStatusCodes(statusCode, deviceStatus);;
406
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
407
- await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
408
- await this.updateHomeKitCharacteristics();
409
- } else {
410
- await this.statusCode(statusCode);
411
- await this.statusCode(deviceStatus.statusCode);
395
+ await this.debugLog('openAPIpushBrightnessChanges');
396
+ if (this.LightBulb.Brightness !== this.accessory.context.Brightness) {
397
+ const command = this.LightBulb.Brightness === 0 ? 'dock' : 'PowLevel';
398
+ const parameter = this.LightBulb.Brightness === 25 ? '0' : this.LightBulb.Brightness === 50 ? '1' : this.LightBulb.Brightness === 75
399
+ ? '2' : this.LightBulb.Brightness === 100 ? '3' : 'default';
400
+ const bodyChange = JSON.stringify({
401
+ command: `${command}`,
402
+ parameter: `${parameter}`,
403
+ commandType: 'command',
404
+ });
405
+ await this.debugLog(`SwitchBot OpenAPI bodyChange: ${JSON.stringify(bodyChange)}`);
406
+ try {
407
+ const { body, statusCode } = await this.pushChangeRequest(bodyChange);
408
+ const deviceStatus: any = await body.json();
409
+ await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
410
+ if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
411
+ await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
412
+ await this.updateHomeKitCharacteristics();
413
+ } else {
414
+ await this.statusCode(statusCode);
415
+ await this.statusCode(deviceStatus.statusCode);
416
+ }
417
+ } catch (e: any) {
418
+ await this.apiError(e);
419
+ await this.errorLog(`failed openAPIpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
412
420
  }
413
- } catch (e: any) {
414
- await this.apiError(e);
415
- await this.pushChangeError('openAPIpushBrightnessChanges', e);
416
- }
417
- }
418
-
419
- async commands() {
420
- let command: string;
421
- let parameter: string;
422
- if (this.LightBulb.On) {
423
- command = 'start';
424
- parameter = 'default';
425
421
  } else {
426
- command = 'dock';
427
- parameter = 'default';
422
+ await this.debugLog(`No changes (openAPIpushBrightnessChanges), Brightness: ${this.LightBulb.Brightness},`
423
+ + ` BrightnessCached: ${this.accessory.context.Brightness}`);
428
424
  }
429
- const body = JSON.stringify({
430
- command: `${command}`,
431
- parameter: `${parameter}`,
432
- commandType: 'command',
433
- });
434
- return body;
435
- }
436
-
437
- async brightnessCommands(): Promise<string> {
438
- let command: string;
439
- let parameter: string;
440
- if (this.LightBulb.Brightness === 25) {
441
- command = 'PowLevel';
442
- parameter = '0';
443
- } else if (this.LightBulb.Brightness === 50) {
444
- command = 'PowLevel';
445
- parameter = '1';
446
- } else if (this.LightBulb.Brightness === 75) {
447
- command = 'PowLevel';
448
- parameter = '2';
449
- } else if (this.LightBulb.Brightness === 100) {
450
- command = 'PowLevel';
451
- parameter = '3';
452
- } else {
453
- command = 'dock';
454
- parameter = 'default';
455
- }
456
- const bodyChange = JSON.stringify({
457
- command: `${command}`,
458
- parameter: `${parameter}`,
459
- commandType: 'command',
460
- });
461
- return bodyChange;
462
425
  }
463
426
 
464
427
  /**
465
428
  * Handle requests to set the value of the "On" characteristic
466
429
  */
467
430
  async OnSet(value: CharacteristicValue): Promise<void> {
468
- if (this.LightBulb.On === this.accessory.context.On) {
469
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set On: ${value}`);
431
+ if (this.LightBulb.On !== this.accessory.context.On) {
432
+ this.infoLog(`Set On: ${value}`);
470
433
  } else {
471
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set On: ${value}`);
434
+ this.debugLog(`No Changes, On: ${value}`);
472
435
  }
473
436
 
474
437
  this.LightBulb.On = value;
@@ -479,12 +442,14 @@ export class RobotVacuumCleaner extends deviceBase {
479
442
  * Handle requests to set the value of the "Brightness" characteristic
480
443
  */
481
444
  async BrightnessSet(value: CharacteristicValue): Promise<void> {
482
- if (this.LightBulb.Brightness === this.accessory.context.Brightness) {
483
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set Brightness: ${value}`);
484
- } else if (this.LightBulb.On) {
485
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Brightness: ${value}`);
445
+ if (this.LightBulb.On && (this.LightBulb.Brightness !== this.accessory.context.Brightness)) {
446
+ await this.infoLog(`Set Brightness: ${value}`);
486
447
  } else {
487
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Brightness: ${value}`);
448
+ if (this.LightBulb.On) {
449
+ this.debugLog(`No Changes, Brightness: ${value}`);
450
+ } else {
451
+ this.debugLog(`Brightness: ${value}, On: ${this.LightBulb.On}`);
452
+ }
488
453
  }
489
454
 
490
455
  this.LightBulb.Brightness = value;
@@ -493,61 +458,33 @@ export class RobotVacuumCleaner extends deviceBase {
493
458
 
494
459
  async updateHomeKitCharacteristics(): Promise<void> {
495
460
  // On
496
- if (this.LightBulb.On === undefined) {
497
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.LightBulb.On}`);
498
- } else {
499
- this.accessory.context.On = this.LightBulb.On;
500
- this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.On, this.LightBulb.On);
501
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.LightBulb.On}`);
502
- }
461
+ await this.updateCharacteristic(this.LightBulb.Service, this.hap.Characteristic.On,
462
+ this.LightBulb.On, 'On');
503
463
  // Brightness
504
- if (this.LightBulb.Brightness === undefined) {
505
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Brightness: ${this.LightBulb.Brightness}`);
506
- } else {
507
- this.accessory.context.Brightness = this.LightBulb.Brightness;
508
- this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.Brightness, this.LightBulb.Brightness);
509
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Brightness: ${this.LightBulb.Brightness}`);
510
- }
464
+ await this.updateCharacteristic(this.LightBulb.Service, this.hap.Characteristic.Brightness,
465
+ this.LightBulb.Brightness, 'Brightness');
511
466
  // BatteryLevel
512
- if (this.Battery.BatteryLevel === undefined) {
513
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
514
- } else {
515
- this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
516
- this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
517
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.Battery.BatteryLevel}`);
518
- }
467
+ await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.BatteryLevel,
468
+ this.Battery.BatteryLevel, 'BatteryLevel');
519
469
  // StatusLowBattery
520
- if (this.Battery.StatusLowBattery === undefined) {
521
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
522
- } else {
523
- this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
524
- this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
525
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
526
- + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
527
- }
470
+ await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.StatusLowBattery,
471
+ this.Battery.StatusLowBattery, 'StatusLowBattery');
528
472
  // ChargingState
529
- if (this.Battery.ChargingState === undefined) {
530
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ChargingState: ${this.Battery.ChargingState}`);
531
- } else {
532
- this.accessory.context.ChargingState = this.Battery.ChargingState;
533
- this.Battery.Service.updateCharacteristic(this.hap.Characteristic.ChargingState, this.Battery.ChargingState);
534
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
535
- + ` ChargingState: ${this.Battery.ChargingState}`);
536
- }
473
+ await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.ChargingState,
474
+ this.Battery.ChargingState, 'ChargingState');
537
475
  }
538
476
 
539
477
  async BLEPushConnection() {
540
478
  if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
541
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Push Changes`);
479
+ await this.warnLog('Using OpenAPI Connection to Push Changes');
542
480
  await this.openAPIpushChanges();
543
481
  }
544
482
  }
545
483
 
546
484
  async BLERefreshConnection(switchbot: any): Promise<void> {
547
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot:`
548
- + ` ${JSON.stringify(switchbot)}`);
485
+ await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${JSON.stringify(switchbot)}`);
549
486
  if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
550
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Refresh Status`);
487
+ await this.warnLog('Using OpenAPI Connection to Refresh Status');
551
488
  await this.openAPIRefreshStatus();
552
489
  }
553
490
  }