@switchbot/homebridge-switchbot 3.5.1-beta.0 → 3.5.1-beta.10

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 (197) hide show
  1. package/README.md +16 -0
  2. package/dist/device/blindtilt.d.ts +15 -6
  3. package/dist/device/blindtilt.d.ts.map +1 -1
  4. package/dist/device/blindtilt.js +224 -370
  5. package/dist/device/blindtilt.js.map +1 -1
  6. package/dist/device/bot.d.ts +9 -4
  7. package/dist/device/bot.d.ts.map +1 -1
  8. package/dist/device/bot.js +197 -221
  9. package/dist/device/bot.js.map +1 -1
  10. package/dist/device/ceilinglight.d.ts +10 -5
  11. package/dist/device/ceilinglight.d.ts.map +1 -1
  12. package/dist/device/ceilinglight.js +214 -292
  13. package/dist/device/ceilinglight.js.map +1 -1
  14. package/dist/device/colorbulb.d.ts +10 -5
  15. package/dist/device/colorbulb.d.ts.map +1 -1
  16. package/dist/device/colorbulb.js +335 -421
  17. package/dist/device/colorbulb.js.map +1 -1
  18. package/dist/device/contact.d.ts +9 -4
  19. package/dist/device/contact.d.ts.map +1 -1
  20. package/dist/device/contact.js +121 -200
  21. package/dist/device/contact.js.map +1 -1
  22. package/dist/device/curtain.d.ts +20 -7
  23. package/dist/device/curtain.d.ts.map +1 -1
  24. package/dist/device/curtain.js +229 -403
  25. package/dist/device/curtain.js.map +1 -1
  26. package/dist/device/device.d.ts +41 -22
  27. package/dist/device/device.d.ts.map +1 -1
  28. package/dist/device/device.js +212 -181
  29. package/dist/device/device.js.map +1 -1
  30. package/dist/device/fan.d.ts +9 -4
  31. package/dist/device/fan.d.ts.map +1 -1
  32. package/dist/device/fan.js +204 -249
  33. package/dist/device/fan.js.map +1 -1
  34. package/dist/device/hub.d.ts +9 -5
  35. package/dist/device/hub.d.ts.map +1 -1
  36. package/dist/device/hub.js +107 -233
  37. package/dist/device/hub.js.map +1 -1
  38. package/dist/device/humidifier.d.ts +12 -4
  39. package/dist/device/humidifier.d.ts.map +1 -1
  40. package/dist/device/humidifier.js +193 -235
  41. package/dist/device/humidifier.js.map +1 -1
  42. package/dist/device/iosensor.d.ts +9 -4
  43. package/dist/device/iosensor.d.ts.map +1 -1
  44. package/dist/device/iosensor.js +92 -159
  45. package/dist/device/iosensor.js.map +1 -1
  46. package/dist/device/lightstrip.d.ts +10 -5
  47. package/dist/device/lightstrip.d.ts.map +1 -1
  48. package/dist/device/lightstrip.js +288 -370
  49. package/dist/device/lightstrip.js.map +1 -1
  50. package/dist/device/lock.d.ts +10 -5
  51. package/dist/device/lock.d.ts.map +1 -1
  52. package/dist/device/lock.js +172 -219
  53. package/dist/device/lock.js.map +1 -1
  54. package/dist/device/meter.d.ts +9 -4
  55. package/dist/device/meter.d.ts.map +1 -1
  56. package/dist/device/meter.js +94 -160
  57. package/dist/device/meter.js.map +1 -1
  58. package/dist/device/meterplus.d.ts +9 -4
  59. package/dist/device/meterplus.d.ts.map +1 -1
  60. package/dist/device/meterplus.js +95 -157
  61. package/dist/device/meterplus.js.map +1 -1
  62. package/dist/device/motion.d.ts +9 -4
  63. package/dist/device/motion.d.ts.map +1 -1
  64. package/dist/device/motion.js +85 -144
  65. package/dist/device/motion.js.map +1 -1
  66. package/dist/device/plug.d.ts +9 -4
  67. package/dist/device/plug.d.ts.map +1 -1
  68. package/dist/device/plug.js +100 -127
  69. package/dist/device/plug.js.map +1 -1
  70. package/dist/device/robotvacuumcleaner.d.ts +9 -6
  71. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  72. package/dist/device/robotvacuumcleaner.js +172 -259
  73. package/dist/device/robotvacuumcleaner.js.map +1 -1
  74. package/dist/device/waterdetector.d.ts +12 -4
  75. package/dist/device/waterdetector.d.ts.map +1 -1
  76. package/dist/device/waterdetector.js +106 -131
  77. package/dist/device/waterdetector.js.map +1 -1
  78. package/dist/irdevice/airconditioner.d.ts +2 -1
  79. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  80. package/dist/irdevice/airconditioner.js +2 -3
  81. package/dist/irdevice/airconditioner.js.map +1 -1
  82. package/dist/irdevice/airpurifier.d.ts +2 -1
  83. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  84. package/dist/irdevice/airpurifier.js +2 -3
  85. package/dist/irdevice/airpurifier.js.map +1 -1
  86. package/dist/irdevice/camera.d.ts +2 -1
  87. package/dist/irdevice/camera.d.ts.map +1 -1
  88. package/dist/irdevice/camera.js +2 -3
  89. package/dist/irdevice/camera.js.map +1 -1
  90. package/dist/irdevice/fan.d.ts +2 -1
  91. package/dist/irdevice/fan.d.ts.map +1 -1
  92. package/dist/irdevice/fan.js +2 -3
  93. package/dist/irdevice/fan.js.map +1 -1
  94. package/dist/irdevice/irdevice.d.ts +3 -1
  95. package/dist/irdevice/irdevice.d.ts.map +1 -1
  96. package/dist/irdevice/irdevice.js +5 -1
  97. package/dist/irdevice/irdevice.js.map +1 -1
  98. package/dist/irdevice/light.d.ts +2 -1
  99. package/dist/irdevice/light.d.ts.map +1 -1
  100. package/dist/irdevice/light.js +2 -3
  101. package/dist/irdevice/light.js.map +1 -1
  102. package/dist/irdevice/other.d.ts +2 -1
  103. package/dist/irdevice/other.d.ts.map +1 -1
  104. package/dist/irdevice/other.js +2 -3
  105. package/dist/irdevice/other.js.map +1 -1
  106. package/dist/irdevice/tv.d.ts +2 -1
  107. package/dist/irdevice/tv.d.ts.map +1 -1
  108. package/dist/irdevice/tv.js +2 -3
  109. package/dist/irdevice/tv.js.map +1 -1
  110. package/dist/irdevice/vacuumcleaner.d.ts +2 -1
  111. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  112. package/dist/irdevice/vacuumcleaner.js +2 -3
  113. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  114. package/dist/irdevice/waterheater.d.ts +2 -1
  115. package/dist/irdevice/waterheater.d.ts.map +1 -1
  116. package/dist/irdevice/waterheater.js +2 -3
  117. package/dist/irdevice/waterheater.js.map +1 -1
  118. package/dist/platform.d.ts +14 -14
  119. package/dist/platform.d.ts.map +1 -1
  120. package/dist/platform.js +102 -86
  121. package/dist/platform.js.map +1 -1
  122. package/dist/settings.d.ts +49 -190
  123. package/dist/settings.d.ts.map +1 -1
  124. package/dist/settings.js +19 -0
  125. package/dist/settings.js.map +1 -1
  126. package/dist/types/bledevicestatus.d.ts +279 -0
  127. package/dist/types/bledevicestatus.d.ts.map +1 -0
  128. package/dist/types/bledevicestatus.js +2 -0
  129. package/dist/types/bledevicestatus.js.map +1 -0
  130. package/dist/types/devicelist.d.ts +89 -0
  131. package/dist/types/devicelist.d.ts.map +1 -0
  132. package/dist/types/devicelist.js +6 -0
  133. package/dist/types/devicelist.js.map +1 -0
  134. package/dist/types/deviceresponse.d.ts +13 -0
  135. package/dist/types/deviceresponse.d.ts.map +1 -0
  136. package/dist/types/deviceresponse.js +2 -0
  137. package/dist/types/deviceresponse.js.map +1 -0
  138. package/dist/types/devicestatus.d.ts +149 -0
  139. package/dist/types/devicestatus.d.ts.map +1 -0
  140. package/dist/types/devicestatus.js +3 -0
  141. package/dist/types/devicestatus.js.map +1 -0
  142. package/dist/types/devicewebhookstatus.d.ts +156 -0
  143. package/dist/types/devicewebhookstatus.d.ts.map +1 -0
  144. package/dist/types/devicewebhookstatus.js +2 -0
  145. package/dist/types/devicewebhookstatus.js.map +1 -0
  146. package/dist/types/irdevicelist.d.ts +10 -0
  147. package/dist/types/irdevicelist.d.ts.map +1 -0
  148. package/dist/types/irdevicelist.js +2 -0
  149. package/dist/types/irdevicelist.js.map +1 -0
  150. package/dist/types/pushbody.d.ts +6 -0
  151. package/dist/types/pushbody.d.ts.map +1 -0
  152. package/dist/types/pushbody.js +2 -0
  153. package/dist/types/pushbody.js.map +1 -0
  154. package/dist/utils.d.ts +25 -0
  155. package/dist/utils.d.ts.map +1 -1
  156. package/dist/utils.js +28 -0
  157. package/dist/utils.js.map +1 -1
  158. package/package.json +11 -11
  159. package/src/device/blindtilt.ts +254 -376
  160. package/src/device/bot.ts +209 -224
  161. package/src/device/ceilinglight.ts +227 -297
  162. package/src/device/colorbulb.ts +345 -435
  163. package/src/device/contact.ts +139 -200
  164. package/src/device/curtain.ts +254 -414
  165. package/src/device/device.ts +221 -190
  166. package/src/device/fan.ts +222 -253
  167. package/src/device/hub.ts +127 -248
  168. package/src/device/humidifier.ts +217 -246
  169. package/src/device/iosensor.ts +115 -168
  170. package/src/device/lightstrip.ts +303 -380
  171. package/src/device/lock.ts +188 -224
  172. package/src/device/meter.ts +117 -179
  173. package/src/device/meterplus.ts +118 -176
  174. package/src/device/motion.ts +100 -146
  175. package/src/device/plug.ts +111 -131
  176. package/src/device/robotvacuumcleaner.ts +191 -258
  177. package/src/device/waterdetector.ts +124 -141
  178. package/src/irdevice/airconditioner.ts +4 -4
  179. package/src/irdevice/airpurifier.ts +4 -4
  180. package/src/irdevice/camera.ts +4 -4
  181. package/src/irdevice/fan.ts +4 -4
  182. package/src/irdevice/irdevice.ts +8 -2
  183. package/src/irdevice/light.ts +4 -4
  184. package/src/irdevice/other.ts +4 -4
  185. package/src/irdevice/tv.ts +4 -4
  186. package/src/irdevice/vacuumcleaner.ts +4 -4
  187. package/src/irdevice/waterheater.ts +4 -4
  188. package/src/platform.ts +104 -87
  189. package/src/settings.ts +30 -238
  190. package/src/types/bledevicestatus.ts +305 -0
  191. package/src/types/devicelist.ts +124 -0
  192. package/src/types/deviceresponse.ts +15 -0
  193. package/src/types/devicestatus.ts +178 -0
  194. package/src/types/devicewebhookstatus.ts +196 -0
  195. package/src/types/irdevicelist.ts +15 -0
  196. package/src/types/pushbody.ts +9 -0
  197. package/src/utils.ts +33 -0
@@ -3,12 +3,16 @@
3
3
  * waterdetector.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
5
  import { deviceBase } from './device.js';
6
- import { interval, Subject } from 'rxjs';
7
- import { skipWhile } from 'rxjs/operators';
6
+ import { Subject, interval, skipWhile } from 'rxjs';
7
+ import { SwitchBotBLEModel, SwitchBotBLEModelName } from 'node-switchbot';
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 { waterLeakDetectorServiceData } 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 { waterLeakDetectorStatus } from '../types/devicestatus.js';
15
+ import type { waterLeakDetectorWebhookContext } from '../types/devicewebhookstatus.js';
12
16
 
13
17
  /**
14
18
  * Platform Accessory
@@ -42,7 +46,6 @@ export class WaterDetector extends deviceBase {
42
46
  device: device & devicesConfig,
43
47
  ) {
44
48
  super(platform, accessory, device);
45
-
46
49
  // this is subject we use to track when we need to POST changes to the SwitchBot API
47
50
  this.doWaterDetectorUpdate = new Subject();
48
51
  this.WaterDetectorUpdateInProgress = false;
@@ -103,68 +106,65 @@ export class WaterDetector extends deviceBase {
103
106
  }
104
107
 
105
108
  // Retrieve initial values and updateHomekit
109
+ this.debugLog('retrieve initial values and Update Homekit');
106
110
  this.refreshStatus();
107
111
 
108
112
  // Retrieve initial values and updateHomekit
109
- this.updateHomeKitCharacteristics();
113
+ // this.updateHomeKitCharacteristics();
114
+
115
+ //regisiter webhook event handler
116
+ this.registerWebhook();
110
117
 
111
118
  // Start an update interval
112
119
  interval(this.deviceRefreshRate * 1000)
113
120
  .pipe(skipWhile(() => this.WaterDetectorUpdateInProgress))
114
121
  .subscribe(async () => {
122
+ await this.debugLog(`update interval: ${this.deviceRefreshRate * 1000} seconds`);
115
123
  await this.refreshStatus();
116
124
  });
117
-
118
- //regisiter webhook event handler
119
- this.registerWebhook(accessory, device);
120
125
  }
121
126
 
122
- async BLEparseStatus(serviceData: serviceData): Promise<void> {
123
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
124
- // Battery
125
- this.Battery.BatteryLevel = Number(serviceData.battery);
126
- if (this.Battery.BatteryLevel < 15) {
127
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
128
- } else {
129
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
130
- }
131
- this.debugLog(`${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}, StatusLowBattery: ${this.Battery.StatusLowBattery}`);
132
-
133
- // LeakDetected
134
- if (this.device.waterdetector?.hide_leak) {
135
- this.LeakSensor!.LeakDetected = serviceData.status!;
136
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LeakDetected: ${this.LeakSensor!.LeakDetected}`);
127
+ async BLEparseStatus(serviceData: waterLeakDetectorServiceData): Promise<void> {
128
+ await this.debugLog('BLEparseStatus');
129
+ if (this.device.waterdetector?.hide_leak && this.LeakSensor?.Service) {
130
+ // StatusActive
131
+ this.LeakSensor.StatusActive = serviceData.state;
132
+ await this.debugLog(`StatusActive: ${this.LeakSensor.StatusActive}`);
133
+ // LeakDetected
134
+ this.LeakSensor.LeakDetected = serviceData.status;
135
+ this.debugLog(`LeakDetected: ${this.LeakSensor.LeakDetected}`);
137
136
  }
137
+ // BatteryLevel
138
+ this.Battery.BatteryLevel = Number(serviceData.battery);
139
+ await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
140
+ // StatusLowBattery
141
+ this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
142
+ ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
143
+ await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`);
138
144
  }
139
145
 
140
- async openAPIparseStatus(deviceStatus: deviceStatus): Promise<void> {
141
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
142
- // StatusLowBattery
143
- this.Battery.BatteryLevel = Number(deviceStatus.body.battery);
144
- if (this.Battery.BatteryLevel < 10) {
145
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
146
- } else {
147
- this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
146
+ async openAPIparseStatus(deviceStatus: waterLeakDetectorStatus): Promise<void> {
147
+ await this.debugLog('openAPIparseStatus');
148
+ if (!this.device.waterdetector?.hide_leak && this.LeakSensor?.Service) {
149
+ // StatusActive
150
+ this.LeakSensor.StatusActive = deviceStatus.battery === 0 ? false : true;
151
+ await this.debugLog(`StatusActive: ${this.LeakSensor.StatusActive}`);
152
+ // LeakDetected
153
+ this.LeakSensor.LeakDetected = deviceStatus.status;
154
+ this.debugLog(`LeakDetected: ${this.LeakSensor.LeakDetected}`);
148
155
  }
149
- this.debugLog(`${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}, StatusLowBattery: ${this.Battery.StatusLowBattery}`);
150
-
151
156
  // BatteryLevel
152
- if (Number.isNaN(this.Battery.BatteryLevel)) {
153
- this.Battery.BatteryLevel = 100;
154
- }
155
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
156
-
157
- // LeakDetected
158
- if (!this.device.waterdetector?.hide_leak) {
159
- this.LeakSensor!.LeakDetected = deviceStatus.body.status!;
160
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LeakDetected: ${this.LeakSensor!.LeakDetected}`);
161
- }
162
-
163
- // Firmware Version
164
- const version = deviceStatus.body.version?.toString();
165
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Firmware Version: ${version?.replace(/^V|-.*$/g, '')}`);
166
- if (deviceStatus.body.version) {
167
- const deviceVersion = version?.replace(/^V|-.*$/g, '') ?? '0.0.0';
157
+ this.Battery.BatteryLevel = Number(deviceStatus.battery);
158
+ await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
159
+ // StatusLowBattery
160
+ this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
161
+ ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
162
+ await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`);
163
+ // FirmwareVersion
164
+ const version = deviceStatus.version.toString();
165
+ await this.debugLog(`FirmwareVersion: ${version.replace(/^V|-.*$/g, '')}`);
166
+ if (deviceStatus.version) {
167
+ const deviceVersion = version.replace(/^V|-.*$/g, '') ?? '0.0.0';
168
168
  this.accessory
169
169
  .getService(this.hap.Service.AccessoryInformation)!
170
170
  .setCharacteristic(this.hap.Characteristic.HardwareRevision, deviceVersion)
@@ -172,41 +172,64 @@ export class WaterDetector extends deviceBase {
172
172
  .getCharacteristic(this.hap.Characteristic.FirmwareRevision)
173
173
  .updateValue(deviceVersion);
174
174
  this.accessory.context.deviceVersion = deviceVersion;
175
- this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceVersion: ${this.accessory.context.deviceVersion}`);
175
+ await this.debugSuccessLog(`deviceVersion: ${this.accessory.context.deviceVersion}`);
176
176
  }
177
177
  }
178
178
 
179
+ async parseStatusWebhook(context: waterLeakDetectorWebhookContext): Promise<void> {
180
+ await this.debugLog('parseStatusWebhook');
181
+ await this.debugLog(`(detectionState, battery) = Webhook: (${context.detectionState}, ${context.battery}),`
182
+ + ` current:(${this.LeakSensor?.LeakDetected}, ${this.Battery.BatteryLevel})`);
183
+ if (!this.device.waterdetector?.hide_leak && this.LeakSensor?.Service) {
184
+ // StatusActive
185
+ this.LeakSensor.StatusActive = context.detectionState ? true : false;
186
+ await this.debugLog(`StatusActive: ${this.LeakSensor.StatusActive}`);
187
+ // LeakDetected
188
+ this.LeakSensor.LeakDetected = context.detectionState;
189
+ await this.debugLog(`LeakDetected: ${this.LeakSensor.LeakDetected}`);
190
+ }
191
+ // BatteryLevel
192
+ this.Battery.BatteryLevel = Number(context.battery);
193
+ await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`);
194
+ // StatusLowBattery
195
+ this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
196
+ ? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
197
+ await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`);
198
+ }
199
+
200
+ /**
201
+ * Asks the SwitchBot API for the latest device information
202
+ */
179
203
  async refreshStatus(): Promise<void> {
180
204
  if (!this.device.enableCloudService && this.OpenAPI) {
181
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} refreshStatus enableCloudService: ${this.device.enableCloudService}`);
205
+ await this.errorLog(`refreshStatus enableCloudService: ${this.device.enableCloudService}`);
182
206
  } else if (this.BLE) {
183
207
  await this.BLERefreshStatus();
184
208
  } else if (this.OpenAPI && this.platform.config.credentials?.token) {
185
209
  await this.openAPIRefreshStatus();
186
210
  } else {
187
211
  await this.offlineOff();
188
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
189
- + ` ${this.device.connectionType}, refreshStatus will not happen.`);
212
+ await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, refreshStatus will not happen.`);
190
213
  }
191
214
  }
192
215
 
193
216
  async BLERefreshStatus(): Promise<void> {
194
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
217
+ await this.debugLog('BLERefreshStatus');
195
218
  const switchbot = await this.switchbotBLE();
196
219
 
197
220
  if (switchbot === undefined) {
198
221
  await this.BLERefreshConnection(switchbot);
199
222
  } else {
200
- // Start to monitor advertisement packets
201
- (async () => {
202
223
  // Start to monitor advertisement packets
203
- const serviceData: serviceData = await this.monitorAdvertisementPackets(switchbot);
224
+ (async () => {
225
+ // Start to monitor advertisement packets
226
+ const serviceData = await this.monitorAdvertisementPackets(switchbot) as unknown as waterLeakDetectorServiceData;
204
227
  // Update HomeKit
205
- if (serviceData.model !== '' && serviceData.modelName !== '') {
228
+ if (serviceData.model === SwitchBotBLEModel.Unknown && serviceData.modelName === SwitchBotBLEModelName.Unknown) {
206
229
  await this.BLEparseStatus(serviceData);
207
230
  await this.updateHomeKitCharacteristics();
208
231
  } else {
209
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
232
+ await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
210
233
  await this.BLERefreshConnection(switchbot);
211
234
  }
212
235
  })();
@@ -214,47 +237,39 @@ export class WaterDetector extends deviceBase {
214
237
  }
215
238
 
216
239
  async openAPIRefreshStatus(): Promise<void> {
217
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
240
+ await this.debugLog('openAPIRefreshStatus');
218
241
  try {
219
242
  const { body, statusCode } = await this.deviceRefreshStatus();
220
243
  const deviceStatus: any = await body.json();
221
- await this.refreshStatusCodes(statusCode, deviceStatus);
222
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
223
- await this.successfulRefreshStatus(statusCode, deviceStatus);
224
- await this.openAPIparseStatus(deviceStatus);
244
+ await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);;
245
+ if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
246
+ await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
247
+ await this.openAPIparseStatus(deviceStatus.body);
225
248
  await this.updateHomeKitCharacteristics();
226
249
  } else {
227
- await this.statusCodes(statusCode, deviceStatus);
250
+ await this.debugWarnLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`);
251
+ await this.debugWarnLog(statusCode, deviceStatus);
228
252
  }
229
253
  } catch (e: any) {
230
- this.apiError(e);
231
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
232
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
254
+ await this.apiError(e);
255
+ await this.errorLog(`failed openAPIRefreshStatus with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
233
256
  }
234
257
  }
235
258
 
236
- async registerWebhook(accessory: PlatformAccessory, device: device & devicesConfig) {
237
- if (device.webhook) {
238
- this.debugLog(`${device.deviceType}: ${accessory.displayName} is listening webhook.`);
239
- this.platform.webhookEventHandler[device.deviceId] = async (context) => {
259
+ async registerWebhook() {
260
+ if (this.device.webhook) {
261
+ await this.debugLog('is listening webhook.');
262
+ this.platform.webhookEventHandler[this.device.deviceId] = async (context: waterLeakDetectorWebhookContext) => {
240
263
  try {
241
- this.debugLog(`${device.deviceType}: ${accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
242
- const { detectionState, battery } = context;
243
- const { LeakDetected } = this.LeakSensor ? this.LeakSensor : { LeakDetected: undefined };
244
- const { BatteryLevel } = this.Battery ? this.Battery : { BatteryLevel: undefined };
245
- this.debugLog(`${device.deviceType}: ${accessory.displayName} (detectionState, battery) = Webhook: (${detectionState}, ${battery}), `
246
- + `current: (${LeakDetected}, ${BatteryLevel})`);
247
- if (!device.waterdetector?.hide_leak) {
248
- this.LeakSensor!.LeakDetected = detectionState;
249
- }
250
- this.Battery.BatteryLevel = battery;
251
- this.updateHomeKitCharacteristics();
264
+ await this.debugLog(`received Webhook: ${JSON.stringify(context)}`);
265
+ await this.parseStatusWebhook(context);
266
+ await this.updateHomeKitCharacteristics();
252
267
  } catch (e: any) {
253
- this.errorLog(`${device.deviceType}: ${accessory.displayName} failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
268
+ await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
254
269
  }
255
270
  };
256
271
  } else {
257
- this.debugLog(`${device.deviceType}: ${accessory.displayName} is not listening webhook.`);
272
+ await this.debugLog('is not listening webhook.');
258
273
  }
259
274
  }
260
275
 
@@ -262,75 +277,43 @@ export class WaterDetector extends deviceBase {
262
277
  * Updates the status for each of the HomeKit Characteristics
263
278
  */
264
279
  async updateHomeKitCharacteristics(): Promise<void> {
265
- const mqttmessage: string[] = [];
266
- const entry = { time: Math.round(new Date().valueOf() / 1000) };
267
- if (!this.device.waterdetector?.hide_leak) {
268
- if (this.LeakSensor!.LeakDetected === undefined) {
269
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LeakDetected: ${this.LeakSensor!.LeakDetected}`);
270
- } else {
271
- if (this.device.mqttURL) {
272
- mqttmessage.push(`"LeakDetected": ${this.LeakSensor!.LeakDetected}`);
273
- }
274
- if (this.device.history) {
275
- entry['leak'] = this.LeakSensor!.LeakDetected;
276
- }
277
- this.accessory.context.LeakDetected = this.LeakSensor!.LeakDetected;
278
- this.LeakSensor!.Service.updateCharacteristic(this.hap.Characteristic.LeakDetected, this.LeakSensor!.LeakDetected);
279
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic LeakDetected: ${this.LeakSensor!.LeakDetected}`);
280
- }
281
- }
282
- if (this.Battery.BatteryLevel === undefined) {
283
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
284
- } else {
285
- if (this.device.mqttURL) {
286
- mqttmessage.push(`"battery": ${this.Battery.BatteryLevel}`);
287
- }
288
- this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
289
- this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
290
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.Battery.BatteryLevel}`);
291
- }
292
- if (this.Battery.StatusLowBattery === undefined) {
293
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
294
- } else {
295
- if (this.device.mqttURL) {
296
- mqttmessage.push(`"lowBattery": ${this.Battery.StatusLowBattery}`);
297
- }
298
- this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
299
- this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
300
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
301
- + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
302
- }
303
- if (this.device.mqttURL) {
304
- this.mqttPublish(`{${mqttmessage.join(',')}}`);
305
- }
306
- if (!this.device.waterdetector?.hide_leak) {
307
- if (Number(this.LeakSensor!.LeakDetected) > 0) {
308
- // reject unreliable data
309
- if (this.device.history) {
310
- this.historyService?.addEntry(entry);
311
- }
312
- }
280
+ if (!this.device.waterdetector?.hide_leak && this.LeakSensor?.Service) {
281
+ // StatusActive
282
+ await this.updateCharacteristic(this.LeakSensor.Service, this.hap.Characteristic.StatusActive,
283
+ this.LeakSensor.StatusActive, 'StatusActive');
284
+ // LeakDetected
285
+ await this.updateCharacteristic(this.LeakSensor.Service, this.hap.Characteristic.LeakDetected,
286
+ this.LeakSensor.LeakDetected, 'LeakDetected');
313
287
  }
288
+ // BatteryLevel
289
+ await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.BatteryLevel,
290
+ this.Battery.BatteryLevel, 'BatteryLevel');
291
+ // StatusLowBattery
292
+ await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.StatusLowBattery,
293
+ this.Battery.StatusLowBattery, 'StatusLowBattery');
314
294
  }
315
295
 
316
296
  async BLERefreshConnection(switchbot: any): Promise<void> {
317
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot:`
318
- + ` ${JSON.stringify(switchbot)}`);
297
+ await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${JSON.stringify(switchbot)}`);
319
298
  if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
320
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Refresh Status`);
299
+ await this.warnLog('Using OpenAPI Connection to Refresh Status');
321
300
  await this.openAPIRefreshStatus();
322
301
  }
323
302
  }
324
303
 
325
304
  async offlineOff(): Promise<void> {
326
- if (this.device.offline && !this.device.waterdetector?.hide_leak) {
327
- this.LeakSensor!.Service.updateCharacteristic(this.hap.Characteristic.LeakDetected, this.hap.Characteristic.LeakDetected.LEAK_NOT_DETECTED);
305
+ if (this.device.offline) {
306
+ if (!this.device.waterdetector?.hide_leak && this.LeakSensor?.Service) {
307
+ this.LeakSensor.Service.updateCharacteristic(this.hap.Characteristic.StatusActive, false);
308
+ this.LeakSensor.Service.updateCharacteristic(this.hap.Characteristic.LeakDetected, this.hap.Characteristic.LeakDetected.LEAK_NOT_DETECTED);
309
+ }
328
310
  }
329
311
  }
330
312
 
331
- async apiError(e: any): Promise<void> {
332
- if (!this.device.waterdetector?.hide_leak) {
333
- this.LeakSensor!.Service.updateCharacteristic(this.hap.Characteristic.LeakDetected, e);
313
+ async apiError(e: any): Promise < void> {
314
+ if(!this.device.waterdetector?.hide_leak && this.LeakSensor?.Service) {
315
+ this.LeakSensor.Service.updateCharacteristic(this.hap.Characteristic.StatusActive, e);
316
+ this.LeakSensor.Service.updateCharacteristic(this.hap.Characteristic.LeakDetected, e);
334
317
  }
335
318
  this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
336
319
  this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
@@ -5,7 +5,8 @@
5
5
  import { irdeviceBase } from './irdevice.js';
6
6
 
7
7
  import type { SwitchBotPlatform } from '../platform.js';
8
- import type { irDevicesConfig, irdevice } from '../settings.js';
8
+ import type { irDevicesConfig } from '../settings.js';
9
+ import type { irdevice } from '../types/irdevicelist.js';
9
10
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
10
11
 
11
12
  /**
@@ -358,9 +359,8 @@ export class AirConditioner extends irdeviceBase {
358
359
  await this.statusCode(deviceStatus.statusCode);
359
360
  }
360
361
  } catch (e: any) {
361
- this.apiError(e);
362
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}`
363
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
362
+ await this.apiError(e);
363
+ await this.pushChangeError(e);
364
364
  }
365
365
  } else {
366
366
  this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}`
@@ -5,7 +5,8 @@
5
5
  import { irdeviceBase } from './irdevice.js';
6
6
 
7
7
  import type { SwitchBotPlatform } from '../platform.js';
8
- import type { irDevicesConfig, irdevice } from '../settings.js';
8
+ import type { irDevicesConfig } from '../settings.js';
9
+ import type { irdevice } from '../types/irdevicelist.js';
9
10
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
10
11
 
11
12
  /**
@@ -235,9 +236,8 @@ export class AirPurifier extends irdeviceBase {
235
236
  await this.statusCode(deviceStatus.statusCode);
236
237
  }
237
238
  } catch (e: any) {
238
- this.apiError(e);
239
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}`
240
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
239
+ await this.apiError(e);
240
+ await this.pushChangeError(e);
241
241
  }
242
242
  } else {
243
243
  this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}`
@@ -5,7 +5,8 @@
5
5
  import { irdeviceBase } from './irdevice.js';
6
6
 
7
7
  import type { SwitchBotPlatform } from '../platform.js';
8
- import type { irDevicesConfig, irdevice } from '../settings.js';
8
+ import type { irDevicesConfig } from '../settings.js';
9
+ import type { irdevice } from '../types/irdevicelist.js';
9
10
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
10
11
 
11
12
  /**
@@ -113,9 +114,8 @@ export class Camera extends irdeviceBase {
113
114
  await this.statusCode(deviceStatus.statusCode);
114
115
  }
115
116
  } catch (e: any) {
116
- this.apiError(e);
117
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}`
118
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
117
+ await this.apiError(e);
118
+ await this.pushChangeError(e);
119
119
  }
120
120
  } else {
121
121
  this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}`
@@ -5,7 +5,8 @@
5
5
  import { irdeviceBase } from './irdevice.js';
6
6
 
7
7
  import type { SwitchBotPlatform } from '../platform.js';
8
- import type { irDevicesConfig, irdevice } from '../settings.js';
8
+ import type { irDevicesConfig } from '../settings.js';
9
+ import type { irdevice } from '../types/irdevicelist.js';
9
10
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
10
11
 
11
12
  /**
@@ -213,9 +214,8 @@ export class IRFan extends irdeviceBase {
213
214
  await this.statusCode(deviceStatus.statusCode);
214
215
  }
215
216
  } catch (e: any) {
216
- this.apiError(e);
217
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}`
218
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
217
+ await this.apiError(e);
218
+ await this.pushChangeError(e);
219
219
  }
220
220
  } else {
221
221
  this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}`
@@ -7,7 +7,8 @@ import { Devices } from '../settings.js';
7
7
 
8
8
  import type { SwitchBotPlatform } from '../platform.js';
9
9
  import type { API, HAP, Logging, PlatformAccessory } from 'homebridge';
10
- import type { SwitchBotPlatformConfig, irDevicesConfig, irdevice } from '../settings.js';
10
+ import type { SwitchBotPlatformConfig, irDevicesConfig } from '../settings.js';
11
+ import type { irdevice } from '../types/irdevicelist.js';
11
12
 
12
13
  export abstract class irdeviceBase {
13
14
  public readonly api: API;
@@ -179,7 +180,7 @@ export abstract class irdeviceBase {
179
180
  const validVersion = match?.join('.');
180
181
  deviceVersion = validVersion ?? '0.0.0';
181
182
  } else {
182
- deviceVersion = version?.replace(/^V|-.*$/g, '') ?? '0.0.0';
183
+ deviceVersion = version.replace(/^V|-.*$/g, '') ?? '0.0.0';
183
184
  }
184
185
  accessory
185
186
  .getService(this.hap.Service.AccessoryInformation)!
@@ -213,6 +214,11 @@ export abstract class irdeviceBase {
213
214
  + ` body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
214
215
  }
215
216
 
217
+ async pushChangeError(e: Error) {
218
+ this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}`
219
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
220
+ }
221
+
216
222
  async disablePushOnChanges(device: irdevice & irDevicesConfig): Promise<void> {
217
223
  if (device.disablePushOn === undefined) {
218
224
  this.disablePushOn = false;
@@ -5,7 +5,8 @@
5
5
  import { irdeviceBase } from './irdevice.js';
6
6
 
7
7
  import type { SwitchBotPlatform } from '../platform.js';
8
- import type { irDevicesConfig, irdevice } from '../settings.js';
8
+ import type { irDevicesConfig } from '../settings.js';
9
+ import type { irdevice } from '../types/irdevicelist.js';
9
10
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
10
11
 
11
12
  /**
@@ -227,9 +228,8 @@ export class Light extends irdeviceBase {
227
228
  await this.statusCode(deviceStatus.statusCode);
228
229
  }
229
230
  } catch (e: any) {
230
- this.apiError(e);
231
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}`
232
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
231
+ await this.apiError(e);
232
+ await this.pushChangeError(e);
233
233
  }
234
234
  } else {
235
235
  this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName} Connection Type: `
@@ -5,7 +5,8 @@
5
5
  import { irdeviceBase } from './irdevice.js';
6
6
 
7
7
  import type { SwitchBotPlatform } from '../platform.js';
8
- import type { irDevicesConfig, irdevice } from '../settings.js';
8
+ import type { irDevicesConfig } from '../settings.js';
9
+ import type { irdevice } from '../types/irdevicelist.js';
9
10
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
10
11
 
11
12
  /**
@@ -544,9 +545,8 @@ export class Others extends irdeviceBase {
544
545
  await this.statusCode(deviceStatus.statusCode);
545
546
  }
546
547
  } catch (e: any) {
547
- this.apiError(e);
548
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}`
549
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
548
+ await this.apiError(e);
549
+ await this.pushChangeError(e);
550
550
  }
551
551
  } else {
552
552
  this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}`
@@ -5,7 +5,8 @@
5
5
  import { irdeviceBase } from './irdevice.js';
6
6
 
7
7
  import type { SwitchBotPlatform } from '../platform.js';
8
- import type { irDevicesConfig, irdevice } from '../settings.js';
8
+ import type { irDevicesConfig } from '../settings.js';
9
+ import type { irdevice } from '../types/irdevicelist.js';
9
10
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
10
11
 
11
12
  /**
@@ -376,9 +377,8 @@ export class TV extends irdeviceBase {
376
377
  await this.statusCode(deviceStatus.statusCode);
377
378
  }
378
379
  } catch (e: any) {
379
- this.apiError(e);
380
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushTVChanges with ${this.device.connectionType}`
381
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
380
+ await this.apiError(e);
381
+ await this.pushChangeError(e);
382
382
  }
383
383
  } else {
384
384
  this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}`
@@ -5,7 +5,8 @@
5
5
  import { irdeviceBase } from './irdevice.js';
6
6
 
7
7
  import type { SwitchBotPlatform } from '../platform.js';
8
- import type { irDevicesConfig, irdevice } from '../settings.js';
8
+ import type { irDevicesConfig } from '../settings.js';
9
+ import type { irdevice } from '../types/irdevicelist.js';
9
10
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
10
11
 
11
12
  /**
@@ -110,9 +111,8 @@ export class VacuumCleaner extends irdeviceBase {
110
111
  await this.statusCode(deviceStatus.statusCode);
111
112
  }
112
113
  } catch (e: any) {
113
- this.apiError(e);
114
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChange`
115
- + ` with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
114
+ await this.apiError(e);
115
+ await this.pushChangeError(e);
116
116
  }
117
117
  } else {
118
118
  this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}`
@@ -5,7 +5,8 @@
5
5
  import { irdeviceBase } from './irdevice.js';
6
6
 
7
7
  import type { SwitchBotPlatform } from '../platform.js';
8
- import type { irDevicesConfig, irdevice } from '../settings.js';
8
+ import type { irDevicesConfig } from '../settings.js';
9
+ import type { irdevice } from '../types/irdevicelist.js';
9
10
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
10
11
 
11
12
  /**
@@ -112,9 +113,8 @@ export class WaterHeater extends irdeviceBase {
112
113
  await this.statusCode(deviceStatus.statusCode);
113
114
  }
114
115
  } catch (e: any) {
115
- this.apiError(e);
116
- this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}`
117
- + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
116
+ await this.apiError(e);
117
+ await this.pushChangeError(e);
118
118
  }
119
119
  } else {
120
120
  this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}`