@switchbot/homebridge-switchbot 3.8.3 → 4.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/.github/npm-version-script.cjs +81 -0
  2. package/.github/workflows/beta-release.yml +12 -4
  3. package/CHANGELOG.md +15 -1
  4. package/config.schema.json +583 -937
  5. package/dist/device/blindtilt.d.ts +1 -4
  6. package/dist/device/blindtilt.d.ts.map +1 -1
  7. package/dist/device/blindtilt.js +68 -66
  8. package/dist/device/blindtilt.js.map +1 -1
  9. package/dist/device/bot.d.ts +1 -4
  10. package/dist/device/bot.d.ts.map +1 -1
  11. package/dist/device/bot.js +63 -59
  12. package/dist/device/bot.js.map +1 -1
  13. package/dist/device/ceilinglight.d.ts +1 -4
  14. package/dist/device/ceilinglight.d.ts.map +1 -1
  15. package/dist/device/ceilinglight.js +56 -65
  16. package/dist/device/ceilinglight.js.map +1 -1
  17. package/dist/device/colorbulb.d.ts +1 -4
  18. package/dist/device/colorbulb.d.ts.map +1 -1
  19. package/dist/device/colorbulb.js +73 -80
  20. package/dist/device/colorbulb.js.map +1 -1
  21. package/dist/device/contact.d.ts +1 -4
  22. package/dist/device/contact.d.ts.map +1 -1
  23. package/dist/device/contact.js +38 -38
  24. package/dist/device/contact.js.map +1 -1
  25. package/dist/device/curtain.d.ts +1 -4
  26. package/dist/device/curtain.d.ts.map +1 -1
  27. package/dist/device/curtain.js +60 -60
  28. package/dist/device/curtain.js.map +1 -1
  29. package/dist/device/device.d.ts +6 -6
  30. package/dist/device/device.d.ts.map +1 -1
  31. package/dist/device/device.js +86 -20
  32. package/dist/device/device.js.map +1 -1
  33. package/dist/device/fan.d.ts +1 -4
  34. package/dist/device/fan.d.ts.map +1 -1
  35. package/dist/device/fan.js +50 -51
  36. package/dist/device/fan.js.map +1 -1
  37. package/dist/device/hub.d.ts +1 -4
  38. package/dist/device/hub.d.ts.map +1 -1
  39. package/dist/device/hub.js +48 -48
  40. package/dist/device/hub.js.map +1 -1
  41. package/dist/device/humidifier.d.ts +1 -4
  42. package/dist/device/humidifier.d.ts.map +1 -1
  43. package/dist/device/humidifier.js +53 -55
  44. package/dist/device/humidifier.js.map +1 -1
  45. package/dist/device/iosensor.d.ts +1 -4
  46. package/dist/device/iosensor.d.ts.map +1 -1
  47. package/dist/device/iosensor.js +35 -35
  48. package/dist/device/iosensor.js.map +1 -1
  49. package/dist/device/lightstrip.d.ts +1 -4
  50. package/dist/device/lightstrip.d.ts.map +1 -1
  51. package/dist/device/lightstrip.js +57 -65
  52. package/dist/device/lightstrip.js.map +1 -1
  53. package/dist/device/lock.d.ts +1 -4
  54. package/dist/device/lock.d.ts.map +1 -1
  55. package/dist/device/lock.js +38 -39
  56. package/dist/device/lock.js.map +1 -1
  57. package/dist/device/meter.d.ts +1 -4
  58. package/dist/device/meter.d.ts.map +1 -1
  59. package/dist/device/meter.js +35 -35
  60. package/dist/device/meter.js.map +1 -1
  61. package/dist/device/meterplus.d.ts +1 -4
  62. package/dist/device/meterplus.d.ts.map +1 -1
  63. package/dist/device/meterplus.js +35 -35
  64. package/dist/device/meterplus.js.map +1 -1
  65. package/dist/device/motion.d.ts +1 -4
  66. package/dist/device/motion.d.ts.map +1 -1
  67. package/dist/device/motion.js +27 -27
  68. package/dist/device/motion.js.map +1 -1
  69. package/dist/device/plug.d.ts +1 -4
  70. package/dist/device/plug.d.ts.map +1 -1
  71. package/dist/device/plug.js +32 -32
  72. package/dist/device/plug.js.map +1 -1
  73. package/dist/device/robotvacuumcleaner.d.ts +1 -4
  74. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  75. package/dist/device/robotvacuumcleaner.js +39 -40
  76. package/dist/device/robotvacuumcleaner.js.map +1 -1
  77. package/dist/device/waterdetector.d.ts +1 -4
  78. package/dist/device/waterdetector.d.ts.map +1 -1
  79. package/dist/device/waterdetector.js +28 -28
  80. package/dist/device/waterdetector.js.map +1 -1
  81. package/dist/irdevice/airconditioner.d.ts +1 -1
  82. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  83. package/dist/irdevice/airconditioner.js +31 -32
  84. package/dist/irdevice/airconditioner.js.map +1 -1
  85. package/dist/irdevice/airpurifier.d.ts +1 -1
  86. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  87. package/dist/irdevice/airpurifier.js +11 -12
  88. package/dist/irdevice/airpurifier.js.map +1 -1
  89. package/dist/irdevice/camera.d.ts +1 -1
  90. package/dist/irdevice/camera.d.ts.map +1 -1
  91. package/dist/irdevice/camera.js +9 -10
  92. package/dist/irdevice/camera.js.map +1 -1
  93. package/dist/irdevice/fan.d.ts +1 -1
  94. package/dist/irdevice/fan.d.ts.map +1 -1
  95. package/dist/irdevice/fan.js +22 -23
  96. package/dist/irdevice/fan.js.map +1 -1
  97. package/dist/irdevice/irdevice.d.ts +6 -6
  98. package/dist/irdevice/irdevice.d.ts.map +1 -1
  99. package/dist/irdevice/irdevice.js +28 -14
  100. package/dist/irdevice/irdevice.js.map +1 -1
  101. package/dist/irdevice/light.d.ts +1 -1
  102. package/dist/irdevice/light.d.ts.map +1 -1
  103. package/dist/irdevice/light.js +12 -13
  104. package/dist/irdevice/light.js.map +1 -1
  105. package/dist/irdevice/other.d.ts +1 -1
  106. package/dist/irdevice/other.d.ts.map +1 -1
  107. package/dist/irdevice/other.js +12 -15
  108. package/dist/irdevice/other.js.map +1 -1
  109. package/dist/irdevice/tv.d.ts +1 -1
  110. package/dist/irdevice/tv.d.ts.map +1 -1
  111. package/dist/irdevice/tv.js +27 -28
  112. package/dist/irdevice/tv.js.map +1 -1
  113. package/dist/irdevice/vacuumcleaner.d.ts +1 -1
  114. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  115. package/dist/irdevice/vacuumcleaner.js +9 -10
  116. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  117. package/dist/irdevice/waterheater.d.ts +1 -1
  118. package/dist/irdevice/waterheater.d.ts.map +1 -1
  119. package/dist/irdevice/waterheater.js +9 -10
  120. package/dist/irdevice/waterheater.js.map +1 -1
  121. package/dist/platform.d.ts +9 -22
  122. package/dist/platform.d.ts.map +1 -1
  123. package/dist/platform.js +154 -260
  124. package/dist/platform.js.map +1 -1
  125. package/dist/settings.d.ts +64 -82
  126. package/dist/settings.d.ts.map +1 -1
  127. package/dist/settings.js +0 -20
  128. package/dist/settings.js.map +1 -1
  129. package/dist/utils.d.ts +1 -102
  130. package/dist/utils.d.ts.map +1 -1
  131. package/dist/utils.js +0 -105
  132. package/dist/utils.js.map +1 -1
  133. package/docs/assets/highlight.css +42 -0
  134. package/docs/assets/main.js +1 -1
  135. package/docs/functions/default.html +1 -1
  136. package/docs/index.html +61 -50
  137. package/docs/media/security-privacy-bluetooth.png +0 -0
  138. package/package.json +5 -7
  139. package/src/device/blindtilt.ts +74 -74
  140. package/src/device/bot.ts +68 -67
  141. package/src/device/ceilinglight.ts +59 -70
  142. package/src/device/colorbulb.ts +79 -88
  143. package/src/device/contact.ts +40 -43
  144. package/src/device/curtain.ts +66 -68
  145. package/src/device/device.ts +86 -40
  146. package/src/device/fan.ts +52 -56
  147. package/src/device/hub.ts +50 -53
  148. package/src/device/humidifier.ts +56 -61
  149. package/src/device/iosensor.ts +37 -40
  150. package/src/device/lightstrip.ts +62 -72
  151. package/src/device/lock.ts +41 -45
  152. package/src/device/meter.ts +37 -40
  153. package/src/device/meterplus.ts +37 -40
  154. package/src/device/motion.ts +29 -32
  155. package/src/device/plug.ts +34 -37
  156. package/src/device/robotvacuumcleaner.ts +41 -49
  157. package/src/device/waterdetector.ts +30 -33
  158. package/src/irdevice/airconditioner.ts +33 -35
  159. package/src/irdevice/airpurifier.ts +12 -13
  160. package/src/irdevice/camera.ts +10 -11
  161. package/src/irdevice/fan.ts +24 -25
  162. package/src/irdevice/irdevice.ts +31 -27
  163. package/src/irdevice/light.ts +14 -15
  164. package/src/irdevice/other.ts +14 -17
  165. package/src/irdevice/tv.ts +28 -29
  166. package/src/irdevice/vacuumcleaner.ts +10 -11
  167. package/src/irdevice/waterheater.ts +10 -11
  168. package/src/platform.ts +178 -287
  169. package/src/settings.ts +67 -88
  170. package/src/utils.ts +2 -106
  171. package/dist/types/bledevicestatus.d.ts +0 -281
  172. package/dist/types/bledevicestatus.d.ts.map +0 -1
  173. package/dist/types/bledevicestatus.js +0 -2
  174. package/dist/types/bledevicestatus.js.map +0 -1
  175. package/dist/types/devicelist.d.ts +0 -89
  176. package/dist/types/devicelist.d.ts.map +0 -1
  177. package/dist/types/devicelist.js +0 -6
  178. package/dist/types/devicelist.js.map +0 -1
  179. package/dist/types/deviceresponse.d.ts +0 -13
  180. package/dist/types/deviceresponse.d.ts.map +0 -1
  181. package/dist/types/deviceresponse.js +0 -2
  182. package/dist/types/deviceresponse.js.map +0 -1
  183. package/dist/types/devicestatus.d.ts +0 -149
  184. package/dist/types/devicestatus.d.ts.map +0 -1
  185. package/dist/types/devicestatus.js +0 -3
  186. package/dist/types/devicestatus.js.map +0 -1
  187. package/dist/types/devicewebhookstatus.d.ts +0 -156
  188. package/dist/types/devicewebhookstatus.d.ts.map +0 -1
  189. package/dist/types/devicewebhookstatus.js +0 -2
  190. package/dist/types/devicewebhookstatus.js.map +0 -1
  191. package/dist/types/irdevicelist.d.ts +0 -10
  192. package/dist/types/irdevicelist.d.ts.map +0 -1
  193. package/dist/types/irdevicelist.js +0 -2
  194. package/dist/types/irdevicelist.js.map +0 -1
  195. package/dist/types/pushbody.d.ts +0 -6
  196. package/dist/types/pushbody.d.ts.map +0 -1
  197. package/dist/types/pushbody.js +0 -2
  198. package/dist/types/pushbody.js.map +0 -1
  199. package/src/types/bledevicestatus.ts +0 -303
  200. package/src/types/devicelist.ts +0 -124
  201. package/src/types/deviceresponse.ts +0 -14
  202. package/src/types/devicestatus.ts +0 -178
  203. package/src/types/devicewebhookstatus.ts +0 -191
  204. package/src/types/irdevicelist.ts +0 -15
  205. package/src/types/pushbody.ts +0 -9
@@ -3,13 +3,10 @@
3
3
  * plug.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
5
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
6
+ import type { bodyChange, device, plugMiniJPServiceData, plugMiniJPWebhookContext, plugMiniStatus, plugMiniUSServiceData, plugMiniUSWebhookContext, plugStatus, plugWebhookContext, SwitchbotDevice, WoPlugMini } from 'node-switchbot'
6
7
 
7
8
  import type { SwitchBotPlatform } from '../platform.js'
8
9
  import type { devicesConfig } from '../settings.js'
9
- import type { plugMiniJPServiceData, plugMiniUSServiceData } from '../types/bledevicestatus.js'
10
- import type { device } from '../types/devicelist.js'
11
- import type { plugMiniStatus, plugStatus } from '../types/devicestatus.js'
12
- import type { plugMiniJPWebhookContext, plugMiniUSWebhookContext, plugWebhookContext } from '../types/devicewebhookstatus.js'
13
10
 
14
11
  /*
15
12
  * For Testing Locally:
@@ -74,7 +71,7 @@ export class Plug extends deviceBase {
74
71
  this.debugLog('Retrieve initial values and update Homekit')
75
72
  this.refreshStatus()
76
73
  } catch (e: any) {
77
- this.errorLog(`failed to retrieve initial values and update Homekit, Error: ${e}`)
74
+ this.errorLog(`failed to retrieve initial values and update Homekit, Error: ${e.message ?? e}`)
78
75
  }
79
76
 
80
77
  // regisiter webhook event handler if enabled
@@ -82,7 +79,7 @@ export class Plug extends deviceBase {
82
79
  this.debugLog('Registering Webhook Event Handler')
83
80
  this.registerWebhook()
84
81
  } catch (e: any) {
85
- this.errorLog(`failed to registerWebhook, Error: ${e}`)
82
+ this.errorLog(`failed to registerWebhook, Error: ${e.message ?? e}`)
86
83
  }
87
84
 
88
85
  // regisiter platform BLE event handler if enabled
@@ -90,7 +87,7 @@ export class Plug extends deviceBase {
90
87
  this.debugLog('Registering Platform BLE Event Handler')
91
88
  this.registerPlatformBLE()
92
89
  } catch (e: any) {
93
- this.errorLog(`failed to registerPlatformBLE, Error: ${e}`)
90
+ this.errorLog(`failed to registerPlatformBLE, Error: ${e.message ?? e}`)
94
91
  }
95
92
 
96
93
  // Start an update interval
@@ -180,14 +177,14 @@ export class Plug extends deviceBase {
180
177
 
181
178
  async BLERefreshStatus(): Promise<void> {
182
179
  await this.debugLog('BLERefreshStatus')
183
- const switchbot = await this.switchbotBLE()
184
- if (switchbot === undefined) {
185
- await this.BLERefreshConnection(switchbot)
180
+ const switchBotBLE = await this.switchbotBLE()
181
+ if (switchBotBLE === undefined) {
182
+ await this.BLERefreshConnection(switchBotBLE)
186
183
  } else {
187
184
  // Start to monitor advertisement packets
188
185
  (async () => {
189
186
  // Start to monitor advertisement packets
190
- const serviceData = await this.monitorAdvertisementPackets(switchbot) as plugMiniUSServiceData | plugMiniJPServiceData
187
+ const serviceData = await this.monitorAdvertisementPackets(switchBotBLE) as plugMiniUSServiceData | plugMiniJPServiceData
191
188
  // Update HomeKit
192
189
  if ((serviceData.model === SwitchBotBLEModel.PlugMiniUS || SwitchBotBLEModel.PlugMiniJP)
193
190
  && serviceData.modelName === (SwitchBotBLEModelName.PlugMini || SwitchBotBLEModelName.PlugMini)) {
@@ -195,8 +192,8 @@ export class Plug extends deviceBase {
195
192
  await this.BLEparseStatus()
196
193
  await this.updateHomeKitCharacteristics()
197
194
  } else {
198
- await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`)
199
- await this.BLERefreshConnection(switchbot)
195
+ await this.errorLog(`failed to get serviceData, serviceData: ${JSON.stringify(serviceData)}`)
196
+ await this.BLERefreshConnection(switchBotBLE)
200
197
  }
201
198
  })()
202
199
  }
@@ -217,7 +214,7 @@ export class Plug extends deviceBase {
217
214
  await this.BLEparseStatus()
218
215
  await this.updateHomeKitCharacteristics()
219
216
  } catch (e: any) {
220
- await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`)
217
+ await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e.message ?? e}`)
221
218
  }
222
219
  }
223
220
  } catch (error) {
@@ -231,17 +228,17 @@ export class Plug extends deviceBase {
231
228
  async openAPIRefreshStatus(): Promise<void> {
232
229
  await this.debugLog('openAPIRefreshStatus')
233
230
  try {
234
- const { body, statusCode } = await this.deviceRefreshStatus()
235
- const deviceStatus: any = await body.json()
236
- await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
237
- if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
238
- await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
231
+ const { body } = await this.deviceRefreshStatus()
232
+ const deviceStatus: any = await body
233
+ await this.debugLog(`statusCode: ${deviceStatus.statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
234
+ if (await this.successfulStatusCodes(deviceStatus)) {
235
+ await this.debugSuccessLog(`statusCode: ${deviceStatus.statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
239
236
  this.deviceStatus = deviceStatus.body
240
237
  await this.openAPIparseStatus()
241
238
  await this.updateHomeKitCharacteristics()
242
239
  } else {
243
- await this.debugWarnLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
244
- await this.debugWarnLog(statusCode, deviceStatus)
240
+ await this.debugWarnLog(`statusCode: ${deviceStatus.statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
241
+ await this.debugWarnLog(deviceStatus)
245
242
  }
246
243
  } catch (e: any) {
247
244
  await this.apiError(e)
@@ -259,7 +256,7 @@ export class Plug extends deviceBase {
259
256
  await this.parseStatusWebhook()
260
257
  await this.updateHomeKitCharacteristics()
261
258
  } catch (e: any) {
262
- await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`)
259
+ await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e.message ?? e}`)
263
260
  }
264
261
  }
265
262
  } else {
@@ -301,23 +298,24 @@ export class Plug extends deviceBase {
301
298
  await this.debugLog('BLEpushChanges')
302
299
  if (this.Outlet.On !== this.accessory.context.On) {
303
300
  await this.debugLog(`BLEpushChanges On: ${this.Outlet.On}, OnCached: ${this.accessory.context.On}`)
304
- const switchbot = await this.platform.connectBLE(this.accessory, this.device)
301
+ const switchBotBLE = await this.platform.connectBLE(this.accessory, this.device)
305
302
  try {
306
303
  const formattedDeviceId = formatDeviceIdAsMac(this.device.deviceId)
307
304
  this.device.bleMac = formattedDeviceId
308
305
  await this.debugLog(`bleMac: ${this.device.bleMac}`)
309
- if (switchbot !== false) {
310
- switchbot
306
+ if (switchBotBLE !== false) {
307
+ switchBotBLE
311
308
  .discover({ model: this.device.bleModel, id: this.device.bleMac })
312
- .then(async (device_list: any) => {
309
+ .then(async (device_list: SwitchbotDevice[]) => {
310
+ const deviceList = device_list as unknown as WoPlugMini[]
313
311
  await this.infoLog(`On: ${this.Outlet.On}`)
314
312
  return await this.retryBLE({
315
313
  max: await this.maxRetryBLE(),
316
314
  fn: async () => {
317
315
  if (this.Outlet.On) {
318
- return await device_list[0].turnOn({ id: this.device.bleMac })
316
+ return await deviceList[0].turnOn()
319
317
  } else {
320
- return await device_list[0].turnOff({ id: this.device.bleMac })
318
+ return await deviceList[0].turnOff()
321
319
  }
322
320
  },
323
321
  })
@@ -332,7 +330,7 @@ export class Plug extends deviceBase {
332
330
  await this.BLEPushConnection()
333
331
  })
334
332
  } else {
335
- await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`)
333
+ await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${JSON.stringify(switchBotBLE)}`)
336
334
  await this.BLEPushConnection()
337
335
  }
338
336
  } catch (error) {
@@ -347,21 +345,20 @@ export class Plug extends deviceBase {
347
345
  await this.debugLog('openAPIpushChanges')
348
346
  if (this.Outlet.On !== this.accessory.context.On) {
349
347
  const command = this.Outlet.On ? 'turnOn' : 'turnOff'
350
- const bodyChange = JSON.stringify({
348
+ const bodyChange: bodyChange = {
351
349
  command: `${command}`,
352
350
  parameter: 'default',
353
351
  commandType: 'command',
354
- })
352
+ }
355
353
  await this.debugLog(`SwitchBot OpenAPI bodyChange: ${JSON.stringify(bodyChange)}`)
356
354
  try {
357
- const { body, statusCode } = await this.pushChangeRequest(bodyChange)
358
- const deviceStatus: any = await body.json()
359
- await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
360
- if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
361
- await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
355
+ const { body } = await this.pushChangeRequest(bodyChange)
356
+ const deviceStatus: any = await body
357
+ await this.debugLog(`statusCode: ${deviceStatus.statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
358
+ if (await this.successfulStatusCodes(deviceStatus)) {
359
+ await this.debugSuccessLog(`statusCode: ${deviceStatus.statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
362
360
  await this.updateHomeKitCharacteristics()
363
361
  } else {
364
- await this.statusCode(statusCode)
365
362
  await this.statusCode(deviceStatus.statusCode)
366
363
  }
367
364
  } catch (e: any) {
@@ -3,17 +3,10 @@
3
3
  * robotvacuumcleaner.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
5
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
6
+ import type { bodyChange, device, floorCleaningRobotS10Status, floorCleaningRobotS10WebhookContext, robotVacuumCleanerS1PlusStatus, robotVacuumCleanerS1PlusWebhookContext, robotVacuumCleanerS1Status, robotVacuumCleanerS1WebhookContext, robotVacuumCleanerServiceData, SwitchbotDevice } from 'node-switchbot'
6
7
 
7
8
  import type { SwitchBotPlatform } from '../platform.js'
8
9
  import type { devicesConfig } from '../settings.js'
9
- import type { robotVacuumCleanerServiceData } from '../types/bledevicestatus.js'
10
- import type { device } from '../types/devicelist.js'
11
- import type { floorCleaningRobotS10Status, robotVacuumCleanerS1PlusStatus, robotVacuumCleanerS1Status } from '../types/devicestatus.js'
12
- import type {
13
- floorCleaningRobotS10WebhookContext,
14
- robotVacuumCleanerS1PlusWebhookContext,
15
- robotVacuumCleanerS1WebhookContext,
16
- } from '../types/devicewebhookstatus.js'
17
10
 
18
11
  /*
19
12
  * For Testing Locally:
@@ -123,7 +116,7 @@ export class RobotVacuumCleaner extends deviceBase {
123
116
  this.debugLog('Retrieve initial values and update Homekit')
124
117
  this.refreshStatus()
125
118
  } catch (e: any) {
126
- this.errorLog(`failed to retrieve initial values and update Homekit, Error: ${e}`)
119
+ this.errorLog(`failed to retrieve initial values and update Homekit, Error: ${e.message ?? e}`)
127
120
  }
128
121
 
129
122
  // regisiter webhook event handler if enabled
@@ -131,7 +124,7 @@ export class RobotVacuumCleaner extends deviceBase {
131
124
  this.debugLog('Registering Webhook Event Handler')
132
125
  this.registerWebhook()
133
126
  } catch (e: any) {
134
- this.errorLog(`failed to registerWebhook, Error: ${e}`)
127
+ this.errorLog(`failed to registerWebhook, Error: ${e.message ?? e}`)
135
128
  }
136
129
 
137
130
  // regisiter platform BLE event handler if enabled
@@ -139,7 +132,7 @@ export class RobotVacuumCleaner extends deviceBase {
139
132
  this.debugLog('Registering Platform BLE Event Handler')
140
133
  this.registerPlatformBLE()
141
134
  } catch (e: any) {
142
- this.errorLog(`failed to registerPlatformBLE, Error: ${e}`)
135
+ this.errorLog(`failed to registerPlatformBLE, Error: ${e.message ?? e}`)
143
136
  }
144
137
 
145
138
  // Start an update interval
@@ -271,22 +264,22 @@ export class RobotVacuumCleaner extends deviceBase {
271
264
 
272
265
  async BLERefreshStatus(): Promise<void> {
273
266
  await this.debugLog('BLERefreshStatus')
274
- const switchbot = await this.switchbotBLE()
275
- if (switchbot === undefined) {
276
- await this.BLERefreshConnection(switchbot)
267
+ const switchBotBLE = await this.switchbotBLE()
268
+ if (switchBotBLE === undefined) {
269
+ await this.BLERefreshConnection(switchBotBLE)
277
270
  } else {
278
271
  // Start to monitor advertisement packets
279
272
  (async () => {
280
273
  // Start to monitor advertisement packets
281
- const serviceData = await this.monitorAdvertisementPackets(switchbot) as unknown as robotVacuumCleanerServiceData
274
+ const serviceData = await this.monitorAdvertisementPackets(switchBotBLE) as unknown as robotVacuumCleanerServiceData
282
275
  // Update HomeKit
283
276
  if (serviceData.model === SwitchBotBLEModel.Unknown && serviceData.modelName === SwitchBotBLEModelName.Unknown) {
284
277
  this.serviceData = serviceData
285
278
  await this.BLEparseStatus()
286
279
  await this.updateHomeKitCharacteristics()
287
280
  } else {
288
- await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`)
289
- await this.BLERefreshConnection(switchbot)
281
+ await this.errorLog(`failed to get serviceData, serviceData: ${JSON.stringify(serviceData)}`)
282
+ await this.BLERefreshConnection(switchBotBLE)
290
283
  }
291
284
  })()
292
285
  }
@@ -307,7 +300,7 @@ export class RobotVacuumCleaner extends deviceBase {
307
300
  await this.BLEparseStatus()
308
301
  await this.updateHomeKitCharacteristics()
309
302
  } catch (e: any) {
310
- await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`)
303
+ await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e.message ?? e}`)
311
304
  }
312
305
  }
313
306
  } catch (error) {
@@ -321,17 +314,17 @@ export class RobotVacuumCleaner extends deviceBase {
321
314
  async openAPIRefreshStatus(): Promise<void> {
322
315
  await this.debugLog('openAPIRefreshStatus')
323
316
  try {
324
- const { body, statusCode } = await this.deviceRefreshStatus()
325
- const deviceStatus: any = await body.json()
326
- await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
327
- if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
328
- await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
317
+ const { body } = await this.deviceRefreshStatus()
318
+ const deviceStatus: any = await body
319
+ await this.debugLog(`statusCode: ${deviceStatus.statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
320
+ if (await this.successfulStatusCodes(deviceStatus)) {
321
+ await this.debugSuccessLog(`statusCode: ${deviceStatus.statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
329
322
  this.deviceStatus = deviceStatus.body
330
323
  await this.openAPIparseStatus()
331
324
  await this.updateHomeKitCharacteristics()
332
325
  } else {
333
- await this.debugWarnLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
334
- await this.debugWarnLog(statusCode, deviceStatus)
326
+ await this.debugWarnLog(`statusCode: ${deviceStatus.statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
327
+ await this.debugWarnLog(deviceStatus)
335
328
  }
336
329
  } catch (e: any) {
337
330
  await this.apiError(e)
@@ -349,7 +342,7 @@ export class RobotVacuumCleaner extends deviceBase {
349
342
  await this.parseStatusWebhook()
350
343
  await this.updateHomeKitCharacteristics()
351
344
  } catch (e: any) {
352
- await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`)
345
+ await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e.message ?? e}`)
353
346
  }
354
347
  }
355
348
  } else {
@@ -388,23 +381,24 @@ export class RobotVacuumCleaner extends deviceBase {
388
381
  async BLEpushChanges(): Promise<void> {
389
382
  await this.debugLog('BLEpushChanges')
390
383
  if (this.LightBulb.On !== this.accessory.context.On) {
391
- const switchbot = await this.platform.connectBLE(this.accessory, this.device)
384
+ const switchBotBLE = await this.platform.connectBLE(this.accessory, this.device)
392
385
  try {
393
386
  const formattedDeviceId = formatDeviceIdAsMac(this.device.deviceId)
394
387
  this.device.bleMac = formattedDeviceId
395
388
  await this.debugLog(`bleMac: ${this.device.bleMac}`)
396
- if (switchbot !== false) {
397
- switchbot
389
+ if (switchBotBLE !== false) {
390
+ switchBotBLE
398
391
  .discover({ model: this.device.bleModel, id: this.device.bleMac })
399
- .then(async (device_list: any) => {
392
+ .then(async (device_list: SwitchbotDevice[]) => {
393
+ const deviceList = device_list as unknown as SwitchbotDevice[]
400
394
  await this.infoLog(`On: ${this.LightBulb.On}`)
401
395
  return await this.retryBLE({
402
396
  max: await this.maxRetryBLE(),
403
397
  fn: async () => {
404
398
  if (this.LightBulb.On) {
405
- return await device_list[0].turnOn({ id: this.device.bleMac })
399
+ return await deviceList[0].turnOn()
406
400
  } else {
407
- return await device_list[0].turnOff({ id: this.device.bleMac })
401
+ return await deviceList[0].turnOff()
408
402
  }
409
403
  },
410
404
  })
@@ -419,7 +413,7 @@ export class RobotVacuumCleaner extends deviceBase {
419
413
  await this.BLEPushConnection()
420
414
  })
421
415
  } else {
422
- await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`)
416
+ await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${JSON.stringify(switchBotBLE)}`)
423
417
  await this.BLEPushConnection()
424
418
  }
425
419
  } catch (error) {
@@ -434,21 +428,20 @@ export class RobotVacuumCleaner extends deviceBase {
434
428
  await this.debugLog('openAPIpushChanges')
435
429
  if (this.LightBulb.On !== this.accessory.context.On) {
436
430
  const command = this.LightBulb.On ? 'start' : 'dock'
437
- const bodyChange = JSON.stringify({
431
+ const bodyChange: bodyChange = {
438
432
  command: `${command}`,
439
433
  parameter: 'default',
440
434
  commandType: 'command',
441
- })
435
+ }
442
436
  await this.debugLog(`SwitchBot OpenAPI bodyChange: ${JSON.stringify(bodyChange)}`)
443
437
  try {
444
- const { body, statusCode } = await this.pushChangeRequest(bodyChange)
445
- const deviceStatus: any = await body.json()
446
- await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
447
- if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
448
- await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
438
+ const { body } = await this.pushChangeRequest(bodyChange)
439
+ const deviceStatus: any = await body
440
+ await this.debugLog(`statusCode: ${deviceStatus.statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
441
+ if (await this.successfulStatusCodes(deviceStatus)) {
442
+ await this.debugSuccessLog(`statusCode: ${deviceStatus.statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
449
443
  await this.updateHomeKitCharacteristics()
450
444
  } else {
451
- await this.statusCode(statusCode)
452
445
  await this.statusCode(deviceStatus.statusCode)
453
446
  }
454
447
  } catch (e: any) {
@@ -471,21 +464,20 @@ export class RobotVacuumCleaner extends deviceBase {
471
464
  : this.LightBulb.Brightness === 75
472
465
  ? '2'
473
466
  : this.LightBulb.Brightness === 100 ? '3' : 'default'
474
- const bodyChange = JSON.stringify({
467
+ const bodyChange: bodyChange = {
475
468
  command: `${command}`,
476
469
  parameter: `${parameter}`,
477
470
  commandType: 'command',
478
- })
471
+ }
479
472
  await this.debugLog(`SwitchBot OpenAPI bodyChange: ${JSON.stringify(bodyChange)}`)
480
473
  try {
481
- const { body, statusCode } = await this.pushChangeRequest(bodyChange)
482
- const deviceStatus: any = await body.json()
483
- await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
484
- if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
485
- await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
474
+ const { body } = await this.pushChangeRequest(bodyChange)
475
+ const deviceStatus: any = await body
476
+ await this.debugLog(`statusCode: ${deviceStatus.statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
477
+ if (await this.successfulStatusCodes(deviceStatus)) {
478
+ await this.debugSuccessLog(`statusCode: ${deviceStatus.statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
486
479
  await this.updateHomeKitCharacteristics()
487
480
  } else {
488
- await this.statusCode(statusCode)
489
481
  await this.statusCode(deviceStatus.statusCode)
490
482
  }
491
483
  } catch (e: any) {
@@ -3,13 +3,10 @@
3
3
  * waterdetector.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
5
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
6
+ import type { device, waterLeakDetectorServiceData, waterLeakDetectorStatus, waterLeakDetectorWebhookContext } from 'node-switchbot'
6
7
 
7
8
  import type { SwitchBotPlatform } from '../platform.js'
8
- import type { devicesConfig } from '../settings.js'
9
- import type { waterLeakDetectorServiceData } from '../types/bledevicestatus.js'
10
- import type { device } from '../types/devicelist.js'
11
- import type { waterLeakDetectorStatus } from '../types/devicestatus.js'
12
- import type { waterLeakDetectorWebhookContext } from '../types/devicewebhookstatus.js'
9
+ import type { devicesConfig, waterDetectorConfig } from '../settings.js'
13
10
 
14
11
  /*
15
12
  * For Testing Locally:
@@ -90,7 +87,7 @@ export class WaterDetector extends deviceBase {
90
87
  })
91
88
 
92
89
  // Initialize Leak Sensor Service
93
- if (device.waterdetector?.hide_leak) {
90
+ if ((device as waterDetectorConfig).hide_leak) {
94
91
  if (this.LeakSensor) {
95
92
  this.debugLog('Removing Leak Sensor Service')
96
93
  this.LeakSensor.Service = this.accessory.getService(this.hap.Service.LeakSensor) as Service
@@ -119,7 +116,7 @@ export class WaterDetector extends deviceBase {
119
116
  this.debugLog('Retrieve initial values and update Homekit')
120
117
  this.refreshStatus()
121
118
  } catch (e: any) {
122
- this.errorLog(`failed to retrieve initial values and update Homekit, Error: ${e}`)
119
+ this.errorLog(`failed to retrieve initial values and update Homekit, Error: ${e.message ?? e}`)
123
120
  }
124
121
 
125
122
  // regisiter webhook event handler if enabled
@@ -127,7 +124,7 @@ export class WaterDetector extends deviceBase {
127
124
  this.debugLog('Registering Webhook Event Handler')
128
125
  this.registerWebhook()
129
126
  } catch (e: any) {
130
- this.errorLog(`failed to registerWebhook, Error: ${e}`)
127
+ this.errorLog(`failed to registerWebhook, Error: ${e.message ?? e}`)
131
128
  }
132
129
 
133
130
  // regisiter platform BLE event handler if enabled
@@ -135,7 +132,7 @@ export class WaterDetector extends deviceBase {
135
132
  this.debugLog('Registering Platform BLE Event Handler')
136
133
  this.registerPlatformBLE()
137
134
  } catch (e: any) {
138
- this.errorLog(`failed to registerPlatformBLE, Error: ${e}`)
135
+ this.errorLog(`failed to registerPlatformBLE, Error: ${e.message ?? e}`)
139
136
  }
140
137
 
141
138
  // Start an update interval
@@ -152,13 +149,13 @@ export class WaterDetector extends deviceBase {
152
149
  await this.debugLog(`(state, status, battery) = BLE: (${this.serviceData.state}, ${this.serviceData.status}, ${this.serviceData.battery}), current:(${this.LeakSensor?.LeakDetected}, ${this.Battery.BatteryLevel})`)
153
150
 
154
151
  // LeakSensor
155
- if (!this.device.waterdetector?.hide_leak && this.LeakSensor?.Service) {
152
+ if (!(this.device as waterDetectorConfig).hide_leak && this.LeakSensor?.Service) {
156
153
  // StatusActive
157
154
  this.LeakSensor.StatusActive = this.serviceData.state
158
155
  await this.debugLog(`StatusActive: ${this.LeakSensor.StatusActive}`)
159
156
 
160
157
  // LeakDetected
161
- if (this.device.waterdetector?.dry) {
158
+ if ((this.device as waterDetectorConfig).dry) {
162
159
  this.LeakSensor.LeakDetected = this.serviceData.status === 0 ? 1 : 0
163
160
  this.debugLog(`LeakDetected: ${this.LeakSensor.LeakDetected}`)
164
161
  } else {
@@ -181,13 +178,13 @@ export class WaterDetector extends deviceBase {
181
178
  await this.debugLog(`(status, battery) = OpenAPI: (${this.deviceStatus.status}, ${this.deviceStatus.battery}), current:(${this.LeakSensor?.LeakDetected}, ${this.Battery.BatteryLevel})`)
182
179
 
183
180
  // LeakSensor
184
- if (!this.device.waterdetector?.hide_leak && this.LeakSensor?.Service) {
181
+ if (!(this.device as waterDetectorConfig).hide_leak && this.LeakSensor?.Service) {
185
182
  // StatusActive
186
183
  this.LeakSensor.StatusActive = this.deviceStatus.battery !== 0
187
184
  await this.debugLog(`StatusActive: ${this.LeakSensor.StatusActive}`)
188
185
 
189
186
  // LeakDetected
190
- if (this.device.waterdetector?.dry) {
187
+ if ((this.device as waterDetectorConfig).dry) {
191
188
  this.LeakSensor.LeakDetected = this.deviceStatus.status === 0 ? 1 : 0
192
189
  this.debugLog(`LeakDetected: ${this.LeakSensor.LeakDetected}`)
193
190
  } else {
@@ -227,13 +224,13 @@ export class WaterDetector extends deviceBase {
227
224
  await this.debugLog(`(detectionState, battery) = Webhook: (${this.webhookContext.detectionState}, ${this.webhookContext.battery}), current:(${this.LeakSensor?.LeakDetected}, ${this.Battery.BatteryLevel})`)
228
225
 
229
226
  // LeakSensor
230
- if (!this.device.waterdetector?.hide_leak && this.LeakSensor?.Service) {
227
+ if (!(this.device as waterDetectorConfig).hide_leak && this.LeakSensor?.Service) {
231
228
  // StatusActive
232
229
  this.LeakSensor.StatusActive = !!this.webhookContext.detectionState
233
230
  await this.debugLog(`StatusActive: ${this.LeakSensor.StatusActive}`)
234
231
 
235
232
  // LeakDetected
236
- if (this.device.waterdetector?.dry) {
233
+ if ((this.device as waterDetectorConfig).dry) {
237
234
  this.LeakSensor.LeakDetected = this.webhookContext.detectionState === 0 ? 1 : 0
238
235
  this.debugLog(`LeakDetected: ${this.LeakSensor.LeakDetected}`)
239
236
  } else {
@@ -271,22 +268,22 @@ export class WaterDetector extends deviceBase {
271
268
 
272
269
  async BLERefreshStatus(): Promise<void> {
273
270
  await this.debugLog('BLERefreshStatus')
274
- const switchbot = await this.switchbotBLE()
275
- if (switchbot === undefined) {
276
- await this.BLERefreshConnection(switchbot)
271
+ const switchBotBLE = await this.switchbotBLE()
272
+ if (switchBotBLE === undefined) {
273
+ await this.BLERefreshConnection(switchBotBLE)
277
274
  } else {
278
275
  // Start to monitor advertisement packets
279
276
  (async () => {
280
277
  // Start to monitor advertisement packets
281
- const serviceData = await this.monitorAdvertisementPackets(switchbot) as waterLeakDetectorServiceData
278
+ const serviceData = await this.monitorAdvertisementPackets(switchBotBLE) as waterLeakDetectorServiceData
282
279
  // Update HomeKit
283
280
  if (serviceData.model === SwitchBotBLEModel.Unknown && serviceData.modelName === SwitchBotBLEModelName.Unknown) {
284
281
  this.serviceData = serviceData
285
282
  await this.BLEparseStatus()
286
283
  await this.updateHomeKitCharacteristics()
287
284
  } else {
288
- await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`)
289
- await this.BLERefreshConnection(switchbot)
285
+ await this.errorLog(`failed to get serviceData, serviceData: ${JSON.stringify(serviceData)}`)
286
+ await this.BLERefreshConnection(switchBotBLE)
290
287
  }
291
288
  })()
292
289
  }
@@ -307,7 +304,7 @@ export class WaterDetector extends deviceBase {
307
304
  await this.BLEparseStatus()
308
305
  await this.updateHomeKitCharacteristics()
309
306
  } catch (e: any) {
310
- await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`)
307
+ await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e.message ?? e}`)
311
308
  }
312
309
  }
313
310
  } catch (error) {
@@ -321,17 +318,17 @@ export class WaterDetector extends deviceBase {
321
318
  async openAPIRefreshStatus(): Promise<void> {
322
319
  await this.debugLog('openAPIRefreshStatus')
323
320
  try {
324
- const { body, statusCode } = await this.deviceRefreshStatus()
325
- const deviceStatus: any = await body.json()
326
- await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
327
- if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
328
- await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
321
+ const { body } = await this.deviceRefreshStatus()
322
+ const deviceStatus: any = await body
323
+ await this.debugLog(`statusCode: ${deviceStatus.statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
324
+ if (await this.successfulStatusCodes(deviceStatus)) {
325
+ await this.debugSuccessLog(`statusCode: ${deviceStatus.statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
329
326
  this.deviceStatus = deviceStatus.body
330
327
  await this.openAPIparseStatus()
331
328
  await this.updateHomeKitCharacteristics()
332
329
  } else {
333
- await this.debugWarnLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
334
- await this.debugWarnLog(statusCode, deviceStatus)
330
+ await this.debugWarnLog(`statusCode: ${deviceStatus.statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
331
+ await this.debugWarnLog(deviceStatus)
335
332
  }
336
333
  } catch (e: any) {
337
334
  await this.apiError(e)
@@ -349,7 +346,7 @@ export class WaterDetector extends deviceBase {
349
346
  await this.parseStatusWebhook()
350
347
  await this.updateHomeKitCharacteristics()
351
348
  } catch (e: any) {
352
- await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`)
349
+ await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e.message ?? e}`)
353
350
  }
354
351
  }
355
352
  } else {
@@ -361,7 +358,7 @@ export class WaterDetector extends deviceBase {
361
358
  * Updates the status for each of the HomeKit Characteristics
362
359
  */
363
360
  async updateHomeKitCharacteristics(): Promise<void> {
364
- if (!this.device.waterdetector?.hide_leak && this.LeakSensor?.Service) {
361
+ if (!(this.device as waterDetectorConfig).hide_leak && this.LeakSensor?.Service) {
365
362
  // StatusActive
366
363
  await this.updateCharacteristic(this.LeakSensor.Service, this.hap.Characteristic.StatusActive, this.LeakSensor.StatusActive, 'StatusActive')
367
364
  // LeakDetected
@@ -383,7 +380,7 @@ export class WaterDetector extends deviceBase {
383
380
 
384
381
  async offlineOff(): Promise<void> {
385
382
  if (this.device.offline) {
386
- if (!this.device.waterdetector?.hide_leak && this.LeakSensor?.Service) {
383
+ if (!(this.device as waterDetectorConfig).hide_leak && this.LeakSensor?.Service) {
387
384
  this.LeakSensor.Service.updateCharacteristic(this.hap.Characteristic.StatusActive, false)
388
385
  this.LeakSensor.Service.updateCharacteristic(this.hap.Characteristic.LeakDetected, this.hap.Characteristic.LeakDetected.LEAK_NOT_DETECTED)
389
386
  }
@@ -391,7 +388,7 @@ export class WaterDetector extends deviceBase {
391
388
  }
392
389
 
393
390
  async apiError(e: any): Promise<void> {
394
- if (!this.device.waterdetector?.hide_leak && this.LeakSensor?.Service) {
391
+ if (!(this.device as waterDetectorConfig).hide_leak && this.LeakSensor?.Service) {
395
392
  this.LeakSensor.Service.updateCharacteristic(this.hap.Characteristic.StatusActive, e)
396
393
  this.LeakSensor.Service.updateCharacteristic(this.hap.Characteristic.LeakDetected, e)
397
394
  }