@switchbot/homebridge-switchbot 3.5.1-beta.11 → 3.5.1-beta.13

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 (153) hide show
  1. package/config.schema.json +19 -3
  2. package/dist/device/blindtilt.d.ts +6 -4
  3. package/dist/device/blindtilt.d.ts.map +1 -1
  4. package/dist/device/blindtilt.js +57 -45
  5. package/dist/device/blindtilt.js.map +1 -1
  6. package/dist/device/bot.d.ts +6 -3
  7. package/dist/device/bot.d.ts.map +1 -1
  8. package/dist/device/bot.js +38 -24
  9. package/dist/device/bot.js.map +1 -1
  10. package/dist/device/ceilinglight.d.ts +6 -3
  11. package/dist/device/ceilinglight.d.ts.map +1 -1
  12. package/dist/device/ceilinglight.js +44 -27
  13. package/dist/device/ceilinglight.js.map +1 -1
  14. package/dist/device/colorbulb.d.ts +6 -3
  15. package/dist/device/colorbulb.d.ts.map +1 -1
  16. package/dist/device/colorbulb.js +47 -32
  17. package/dist/device/colorbulb.js.map +1 -1
  18. package/dist/device/contact.d.ts +6 -3
  19. package/dist/device/contact.d.ts.map +1 -1
  20. package/dist/device/contact.js +40 -28
  21. package/dist/device/contact.js.map +1 -1
  22. package/dist/device/curtain.d.ts +6 -4
  23. package/dist/device/curtain.d.ts.map +1 -1
  24. package/dist/device/curtain.js +35 -22
  25. package/dist/device/curtain.js.map +1 -1
  26. package/dist/device/device.d.ts +13 -2
  27. package/dist/device/device.d.ts.map +1 -1
  28. package/dist/device/device.js +223 -108
  29. package/dist/device/device.js.map +1 -1
  30. package/dist/device/fan.d.ts +6 -3
  31. package/dist/device/fan.d.ts.map +1 -1
  32. package/dist/device/fan.js +48 -29
  33. package/dist/device/fan.js.map +1 -1
  34. package/dist/device/hub.d.ts +6 -3
  35. package/dist/device/hub.d.ts.map +1 -1
  36. package/dist/device/hub.js +43 -26
  37. package/dist/device/hub.js.map +1 -1
  38. package/dist/device/humidifier.d.ts +6 -3
  39. package/dist/device/humidifier.d.ts.map +1 -1
  40. package/dist/device/humidifier.js +43 -26
  41. package/dist/device/humidifier.js.map +1 -1
  42. package/dist/device/iosensor.d.ts +6 -3
  43. package/dist/device/iosensor.d.ts.map +1 -1
  44. package/dist/device/iosensor.js +39 -24
  45. package/dist/device/iosensor.js.map +1 -1
  46. package/dist/device/lightstrip.d.ts +6 -3
  47. package/dist/device/lightstrip.d.ts.map +1 -1
  48. package/dist/device/lightstrip.js +43 -27
  49. package/dist/device/lightstrip.js.map +1 -1
  50. package/dist/device/lock.d.ts +6 -3
  51. package/dist/device/lock.d.ts.map +1 -1
  52. package/dist/device/lock.js +33 -22
  53. package/dist/device/lock.js.map +1 -1
  54. package/dist/device/meter.d.ts +6 -3
  55. package/dist/device/meter.d.ts.map +1 -1
  56. package/dist/device/meter.js +38 -24
  57. package/dist/device/meter.js.map +1 -1
  58. package/dist/device/meterplus.d.ts +6 -3
  59. package/dist/device/meterplus.d.ts.map +1 -1
  60. package/dist/device/meterplus.js +37 -24
  61. package/dist/device/meterplus.js.map +1 -1
  62. package/dist/device/motion.d.ts +6 -3
  63. package/dist/device/motion.d.ts.map +1 -1
  64. package/dist/device/motion.js +33 -22
  65. package/dist/device/motion.js.map +1 -1
  66. package/dist/device/plug.d.ts +6 -3
  67. package/dist/device/plug.d.ts.map +1 -1
  68. package/dist/device/plug.js +27 -16
  69. package/dist/device/plug.js.map +1 -1
  70. package/dist/device/robotvacuumcleaner.d.ts +6 -3
  71. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  72. package/dist/device/robotvacuumcleaner.js +34 -21
  73. package/dist/device/robotvacuumcleaner.js.map +1 -1
  74. package/dist/device/waterdetector.d.ts +6 -3
  75. package/dist/device/waterdetector.d.ts.map +1 -1
  76. package/dist/device/waterdetector.js +38 -23
  77. package/dist/device/waterdetector.js.map +1 -1
  78. package/dist/irdevice/airconditioner.d.ts +1 -3
  79. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  80. package/dist/irdevice/airconditioner.js +32 -138
  81. package/dist/irdevice/airconditioner.js.map +1 -1
  82. package/dist/irdevice/airpurifier.d.ts +0 -1
  83. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  84. package/dist/irdevice/airpurifier.js +13 -44
  85. package/dist/irdevice/airpurifier.js.map +1 -1
  86. package/dist/irdevice/camera.d.ts.map +1 -1
  87. package/dist/irdevice/camera.js +3 -10
  88. package/dist/irdevice/camera.js.map +1 -1
  89. package/dist/irdevice/fan.d.ts.map +1 -1
  90. package/dist/irdevice/fan.js +7 -25
  91. package/dist/irdevice/fan.js.map +1 -1
  92. package/dist/irdevice/irdevice.d.ts +1 -1
  93. package/dist/irdevice/irdevice.js +5 -5
  94. package/dist/irdevice/irdevice.js.map +1 -1
  95. package/dist/irdevice/light.d.ts.map +1 -1
  96. package/dist/irdevice/light.js +9 -27
  97. package/dist/irdevice/light.js.map +1 -1
  98. package/dist/irdevice/other.js +1 -1
  99. package/dist/irdevice/other.js.map +1 -1
  100. package/dist/irdevice/tv.d.ts.map +1 -1
  101. package/dist/irdevice/tv.js +3 -18
  102. package/dist/irdevice/tv.js.map +1 -1
  103. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  104. package/dist/irdevice/vacuumcleaner.js +2 -9
  105. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  106. package/dist/irdevice/waterheater.d.ts.map +1 -1
  107. package/dist/irdevice/waterheater.js +2 -9
  108. package/dist/irdevice/waterheater.js.map +1 -1
  109. package/dist/platform.d.ts +0 -11
  110. package/dist/platform.d.ts.map +1 -1
  111. package/dist/platform.js +11 -184
  112. package/dist/platform.js.map +1 -1
  113. package/dist/settings.d.ts +9 -8
  114. package/dist/settings.d.ts.map +1 -1
  115. package/dist/settings.js.map +1 -1
  116. package/dist/types/bledevicestatus.d.ts +2 -1
  117. package/dist/types/bledevicestatus.d.ts.map +1 -1
  118. package/dist/types/devicestatus.d.ts +1 -1
  119. package/dist/types/devicestatus.d.ts.map +1 -1
  120. package/package.json +9 -9
  121. package/src/device/blindtilt.ts +60 -47
  122. package/src/device/bot.ts +47 -25
  123. package/src/device/ceilinglight.ts +53 -27
  124. package/src/device/colorbulb.ts +50 -39
  125. package/src/device/contact.ts +43 -28
  126. package/src/device/curtain.ts +45 -23
  127. package/src/device/device.ts +226 -96
  128. package/src/device/fan.ts +61 -30
  129. package/src/device/hub.ts +55 -29
  130. package/src/device/humidifier.ts +55 -31
  131. package/src/device/iosensor.ts +45 -27
  132. package/src/device/lightstrip.ts +48 -28
  133. package/src/device/lock.ts +49 -23
  134. package/src/device/meter.ts +54 -26
  135. package/src/device/meterplus.ts +50 -26
  136. package/src/device/motion.ts +45 -24
  137. package/src/device/plug.ts +34 -17
  138. package/src/device/robotvacuumcleaner.ts +49 -23
  139. package/src/device/waterdetector.ts +56 -25
  140. package/src/irdevice/airconditioner.ts +41 -125
  141. package/src/irdevice/airpurifier.ts +18 -40
  142. package/src/irdevice/camera.ts +4 -9
  143. package/src/irdevice/fan.ts +10 -22
  144. package/src/irdevice/irdevice.ts +5 -5
  145. package/src/irdevice/light.ts +10 -24
  146. package/src/irdevice/other.ts +1 -1
  147. package/src/irdevice/tv.ts +5 -16
  148. package/src/irdevice/vacuumcleaner.ts +3 -8
  149. package/src/irdevice/waterheater.ts +3 -8
  150. package/src/platform.ts +11 -184
  151. package/src/settings.ts +10 -8
  152. package/src/types/bledevicestatus.ts +4 -2
  153. package/src/types/devicestatus.ts +1 -1
@@ -23,6 +23,7 @@ export class AirPurifier extends irdeviceBase {
23
23
  RotationSpeed: CharacteristicValue;
24
24
  CurrentAirPurifierState: CharacteristicValue;
25
25
  TargetAirPurifierState: CharacteristicValue;
26
+ CurrentHeaterCoolerState: CharacteristicValue;
26
27
  };
27
28
 
28
29
  private TemperatureSensor: {
@@ -36,7 +37,6 @@ export class AirPurifier extends irdeviceBase {
36
37
  CurrentAPTemp!: CharacteristicValue;
37
38
  CurrentAPMode!: CharacteristicValue;
38
39
  CurrentAPFanSpeed!: CharacteristicValue;
39
- CurrentHeaterCoolerState!: CharacteristicValue;
40
40
 
41
41
  // Others
42
42
  Busy: any;
@@ -64,6 +64,7 @@ export class AirPurifier extends irdeviceBase {
64
64
  RotationSpeed: accessory.context.RotationSpeed ?? 0,
65
65
  CurrentAirPurifierState: accessory.context.CurrentAirPurifierState ?? this.hap.Characteristic.CurrentAirPurifierState.INACTIVE,
66
66
  TargetAirPurifierState: accessory.context.TargetAirPurifierState ?? this.hap.Characteristic.TargetAirPurifierState.AUTO,
67
+ CurrentHeaterCoolerState: accessory.context.CurrentHeaterCoolerState ?? this.hap.Characteristic.CurrentHeaterCoolerState.INACTIVE,
67
68
  };
68
69
  accessory.context.AirPurifier = this.AirPurifier as object;
69
70
 
@@ -187,7 +188,7 @@ export class AirPurifier extends irdeviceBase {
187
188
  + ` disablePushOff: ${this.disablePushOff}, disablePushOn: ${this.disablePushOn}`);
188
189
  if (!this.Busy) {
189
190
  this.Busy = true;
190
- this.CurrentHeaterCoolerState = this.hap.Characteristic.CurrentHeaterCoolerState.IDLE;
191
+ this.AirPurifier.CurrentHeaterCoolerState = this.hap.Characteristic.CurrentHeaterCoolerState.IDLE;
191
192
  }
192
193
  clearTimeout(this.Timeout);
193
194
 
@@ -210,12 +211,12 @@ export class AirPurifier extends irdeviceBase {
210
211
  });
211
212
  if (this.AirPurifier.Active === 1) {
212
213
  if ((Number(this.TemperatureSensor!.CurrentTemperature) || 24) < (this.LastTemperature || 30)) {
213
- this.CurrentHeaterCoolerState = this.hap.Characteristic.CurrentHeaterCoolerState.COOLING;
214
+ this.AirPurifier.CurrentHeaterCoolerState = this.hap.Characteristic.CurrentHeaterCoolerState.COOLING;
214
215
  } else {
215
- this.CurrentHeaterCoolerState = this.hap.Characteristic.CurrentHeaterCoolerState.HEATING;
216
+ this.AirPurifier.CurrentHeaterCoolerState = this.hap.Characteristic.CurrentHeaterCoolerState.HEATING;
216
217
  }
217
218
  } else {
218
- this.CurrentHeaterCoolerState = this.hap.Characteristic.CurrentHeaterCoolerState.INACTIVE;
219
+ this.AirPurifier.CurrentHeaterCoolerState = this.hap.Characteristic.CurrentHeaterCoolerState.INACTIVE;
219
220
  }
220
221
  await this.pushChanges(bodyChange);
221
222
  }
@@ -228,7 +229,7 @@ export class AirPurifier extends irdeviceBase {
228
229
  const { body, statusCode } = await this.pushChangeRequest(bodyChange);
229
230
  const deviceStatus: any = await body.json();
230
231
  await this.pushStatusCodes(statusCode, deviceStatus);
231
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
232
+ if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
232
233
  await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
233
234
  await this.updateHomeKitCharacteristics();
234
235
  } else {
@@ -247,47 +248,24 @@ export class AirPurifier extends irdeviceBase {
247
248
  async updateHomeKitCharacteristics(): Promise<void> {
248
249
  await this.debugLog('updateHomeKitCharacteristics');
249
250
  // Active
250
- if (this.AirPurifier.Active === undefined) {
251
- await this.debugLog(`Active: ${this.AirPurifier.Active}`);
252
- } else {
253
- this.accessory.context.Active = this.AirPurifier.Active;
254
- this.AirPurifier.Service.updateCharacteristic(this.hap.Characteristic.Active, this.AirPurifier.Active);
255
- await this.debugLog(`updateCharacteristic Active: ${this.AirPurifier.Active}`);
256
- }
251
+ await this.updateCharacteristic(this.AirPurifier.Service, this.hap.Characteristic.Active,
252
+ this.AirPurifier.Active, 'Active');
257
253
  // CurrentAirPurifierState
258
- if (this.AirPurifier.CurrentAirPurifierState === undefined) {
259
- await this.debugLog(`CurrentAirPurifierState: ${this.AirPurifier.CurrentAirPurifierState}`);
260
- } else {
261
- this.accessory.context.CurrentAirPurifierState = this.AirPurifier.CurrentAirPurifierState;
262
- this.AirPurifier.Service.updateCharacteristic(this.hap.Characteristic.CurrentAirPurifierState, this.AirPurifier.CurrentAirPurifierState);
263
- await this.debugLog('updateCharacteristic'
264
- + ` CurrentAirPurifierState: ${this.AirPurifier.CurrentAirPurifierState}`);
265
- }
254
+ await this.updateCharacteristic(this.AirPurifier.Service, this.hap.Characteristic.CurrentAirPurifierState,
255
+ this.AirPurifier.CurrentAirPurifierState, 'CurrentAirPurifierState');
266
256
  // CurrentHeaterCoolerState
267
- if (this.CurrentHeaterCoolerState === undefined) {
268
- await this.debugLog(`CurrentHeaterCoolerState: ${this.CurrentHeaterCoolerState}`);
269
- } else {
270
- this.accessory.context.CurrentHeaterCoolerState = this.CurrentHeaterCoolerState;
271
- this.AirPurifier.Service.updateCharacteristic(this.hap.Characteristic.CurrentHeaterCoolerState, this.CurrentHeaterCoolerState);
272
- await this.debugLog('updateCharacteristic'
273
- + ` CurrentHeaterCoolerState: ${this.CurrentHeaterCoolerState}`);
274
- }
257
+ await this.updateCharacteristic(this.AirPurifier.Service, this.hap.Characteristic.CurrentHeaterCoolerState,
258
+ this.AirPurifier.CurrentHeaterCoolerState, 'CurrentHeaterCoolerState');
275
259
  // CurrentTemperature
276
- if (this.TemperatureSensor.CurrentTemperature === undefined) {
277
- await this.debugLog(`CurrentTemperature: ${this.TemperatureSensor.CurrentTemperature}`);
278
- } else {
279
- this.accessory.context.CurrentTemperature = this.TemperatureSensor.CurrentTemperature;
280
- this.TemperatureSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, this.TemperatureSensor.CurrentTemperature);
281
- await this.debugLog('updateCharacteristic'
282
- + ` CurrentTemperature: ${this.TemperatureSensor.CurrentTemperature}`);
283
- }
260
+ await this.updateCharacteristic(this.TemperatureSensor.Service, this.hap.Characteristic.CurrentTemperature,
261
+ this.TemperatureSensor.CurrentTemperature, 'CurrentTemperature');
284
262
  }
285
263
 
286
264
  async apiError(e: any): Promise<void> {
287
- this.AirPurifier.Service.updateCharacteristic(this.hap.Characteristic.CurrentHeaterCoolerState, e);
288
- this.AirPurifier.Service.updateCharacteristic(this.hap.Characteristic.CurrentAirPurifierState, e);
289
- this.AirPurifier.Service.updateCharacteristic(this.hap.Characteristic.TargetAirPurifierState, e);
290
265
  this.AirPurifier.Service.updateCharacteristic(this.hap.Characteristic.Active, e);
266
+ this.AirPurifier.Service.updateCharacteristic(this.hap.Characteristic.TargetAirPurifierState, e);
267
+ this.AirPurifier.Service.updateCharacteristic(this.hap.Characteristic.CurrentAirPurifierState, e);
268
+ this.AirPurifier.Service.updateCharacteristic(this.hap.Characteristic.CurrentHeaterCoolerState, e);
291
269
  this.TemperatureSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, e);
292
270
  }
293
271
  }
@@ -106,7 +106,7 @@ export class Camera extends irdeviceBase {
106
106
  const { body, statusCode } = await this.pushChangeRequest(bodyChange);
107
107
  const deviceStatus: any = await body.json();
108
108
  await this.pushStatusCodes(statusCode, deviceStatus);
109
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
109
+ if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
110
110
  await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
111
111
  await this.updateHomeKitCharacteristics();
112
112
  } else {
@@ -124,14 +124,9 @@ export class Camera extends irdeviceBase {
124
124
 
125
125
  async updateHomeKitCharacteristics(): Promise<void> {
126
126
  await this.debugLog('updateHomeKitCharacteristics');
127
- // On
128
- if (this.Switch.On === undefined) {
129
- await this.debugLog(`On: ${this.Switch.On}`);
130
- } else {
131
- this.accessory.context.On = this.Switch.On;
132
- this.Switch.Service.updateCharacteristic(this.hap.Characteristic.On, this.Switch.On);
133
- await this.debugLog(`updateCharacteristic On: ${this.Switch.On}`);
134
- }
127
+ // Active
128
+ await this.updateCharacteristic(this.Switch.Service, this.hap.Characteristic.On,
129
+ this.Switch.On, 'On');
135
130
  }
136
131
 
137
132
  async apiError(e: any): Promise<void> {
@@ -206,7 +206,7 @@ export class IRFan extends irdeviceBase {
206
206
  const { body, statusCode } = await this.pushChangeRequest(bodyChange);
207
207
  const deviceStatus: any = await body.json();
208
208
  await this.pushStatusCodes(statusCode, deviceStatus);
209
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
209
+ if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
210
210
  await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
211
211
  await this.updateHomeKitCharacteristics();
212
212
  } else {
@@ -224,27 +224,15 @@ export class IRFan extends irdeviceBase {
224
224
 
225
225
  async updateHomeKitCharacteristics(): Promise<void> {
226
226
  await this.debugLog('updateHomeKitCharacteristics');
227
- if (this.Fan.Active === undefined) {
228
- await this.debugLog(`Active: ${this.Fan.Active}`);
229
- } else {
230
- this.accessory.context.Active = this.Fan.Active;
231
- this.Fan.Service.updateCharacteristic(this.hap.Characteristic.Active, this.Fan.Active);
232
- await this.debugLog(`updateCharacteristic Active: ${this.Fan.Active}`);
233
- }
234
- if (this.Fan.SwingMode === undefined) {
235
- await this.debugLog(`SwingMode: ${this.Fan.SwingMode}`);
236
- } else {
237
- this.accessory.context.SwingMode = this.Fan.SwingMode;
238
- this.Fan.Service.updateCharacteristic(this.hap.Characteristic.SwingMode, this.Fan.SwingMode);
239
- await this.debugLog(`updateCharacteristic SwingMode: ${this.Fan.SwingMode}`);
240
- }
241
- if (this.Fan.RotationSpeed === undefined) {
242
- await this.debugLog(`RotationSpeed: ${this.Fan.RotationSpeed}`);
243
- } else {
244
- this.accessory.context.RotationSpeed = this.Fan.RotationSpeed;
245
- this.Fan.Service.updateCharacteristic(this.hap.Characteristic.RotationSpeed, this.Fan.RotationSpeed);
246
- await this.debugLog(`updateCharacteristic RotationSpeed: ${this.Fan.RotationSpeed}`);
247
- }
227
+ // Active
228
+ await this.updateCharacteristic(this.Fan.Service, this.hap.Characteristic.Active,
229
+ this.Fan.Active, 'Active');
230
+ // SwingMode
231
+ await this.updateCharacteristic(this.Fan.Service, this.hap.Characteristic.SwingMode,
232
+ this.Fan.SwingMode, 'SwingMode');
233
+ // RotationSpeed
234
+ await this.updateCharacteristic(this.Fan.Service, this.hap.Characteristic.RotationSpeed,
235
+ this.Fan.RotationSpeed, 'RotationSpeed');
248
236
  }
249
237
 
250
238
  async apiError(e: any): Promise<void> {
@@ -202,7 +202,7 @@ export abstract class irdeviceBase {
202
202
  }
203
203
 
204
204
  async successfulStatusCodes(statusCode: any, deviceStatus: any) {
205
- return (statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100);
205
+ return await this.successfulStatusCodes(statusCode, deviceStatus);
206
206
  }
207
207
 
208
208
  /**
@@ -218,13 +218,13 @@ export abstract class irdeviceBase {
218
218
  async updateCharacteristic(Service: Service, Characteristic: any,
219
219
  CharacteristicValue: CharacteristicValue | undefined, CharacteristicName: string): Promise<void> {
220
220
  if (CharacteristicValue === undefined) {
221
- await await this.debugLog(`${CharacteristicName}: ${CharacteristicValue}`);
221
+ await this.debugLog(`${CharacteristicName}: ${CharacteristicValue}`);
222
222
  } else {
223
223
  Service.updateCharacteristic(Characteristic, CharacteristicValue);
224
- await await this.debugLog(`updateCharacteristic ${CharacteristicName}: ${CharacteristicValue}`);
225
- await await this.debugWarnLog(`context before: ${this.accessory.context[CharacteristicName]}`);
224
+ await this.debugLog(`updateCharacteristic ${CharacteristicName}: ${CharacteristicValue}`);
225
+ await this.debugWarnLog(`context before: ${this.accessory.context[CharacteristicName]}`);
226
226
  this.accessory.context[CharacteristicName] = CharacteristicValue;
227
- await await this.debugWarnLog(`context after: ${this.accessory.context[CharacteristicName]}`);
227
+ await this.debugWarnLog(`context after: ${this.accessory.context[CharacteristicName]}`);
228
228
  }
229
229
  }
230
230
 
@@ -219,7 +219,7 @@ export class Light extends irdeviceBase {
219
219
  const { body, statusCode } = await this.pushChangeRequest(bodyChange);
220
220
  const deviceStatus: any = await body.json();
221
221
  await this.pushStatusCodes(statusCode, deviceStatus);
222
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
222
+ if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
223
223
  await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
224
224
  this.accessory.context.On = On;
225
225
  await this.updateHomeKitCharacteristics();
@@ -239,34 +239,20 @@ export class Light extends irdeviceBase {
239
239
 
240
240
  async updateHomeKitCharacteristics(): Promise<void> {
241
241
  await this.debugLog('updateHomeKitCharacteristics');
242
- if (!this.device.irlight?.stateless) {
242
+ if (!this.device.irlight?.stateless && this.LightBulb?.Service) {
243
243
  // On
244
- if (this.LightBulb?.On === undefined) {
245
- await this.debugLog(`On: ${this.LightBulb?.On}`);
246
- } else {
247
- this.accessory.context.On = this.LightBulb.On;
248
- this.LightBulb?.Service.updateCharacteristic(this.hap.Characteristic.On, this.LightBulb.On);
249
- await this.debugLog(`updateCharacteristic On: ${this.LightBulb.On}`);
250
- }
244
+ await this.updateCharacteristic(this.LightBulb.Service, this.hap.Characteristic.On,
245
+ this.LightBulb.On, 'On');
251
246
  } else {
247
+ if (this.ProgrammableSwitchOn?.Service) {
252
248
  // On Stateful Programmable Switch
253
- if (this.ProgrammableSwitchOn?.ProgrammableSwitchOutputState === undefined) {
254
- await this.debugLog(`ProgrammableSwitchOutputStateOn: ${this.ProgrammableSwitchOn?.ProgrammableSwitchOutputState}`);
255
- } else {
256
- this.accessory.context.ProgrammableSwitchOutputStateOn = this.ProgrammableSwitchOn.ProgrammableSwitchOutputState;
257
- this.ProgrammableSwitchOn?.Service.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchOutputState,
258
- this.ProgrammableSwitchOn.ProgrammableSwitchOutputState);
259
- this.debugLog('updateCharacteristic'
260
- + ` ProgrammableSwitchOutputStateOn: ${this.ProgrammableSwitchOn.ProgrammableSwitchOutputState}`);
249
+ await this.updateCharacteristic(this.ProgrammableSwitchOn.Service, this.hap.Characteristic.ProgrammableSwitchOutputState,
250
+ this.ProgrammableSwitchOn.ProgrammableSwitchOutputState, 'ProgrammableSwitchOutputState');
261
251
  }
252
+ if (this.ProgrammableSwitchOff?.Service) {
262
253
  // Off Stateful Programmable Switch
263
- if (this.ProgrammableSwitchOff?.ProgrammableSwitchOutputState === undefined) {
264
- await this.debugLog(`ProgrammableSwitchOutputStateOff: ${this.ProgrammableSwitchOff?.ProgrammableSwitchOutputState}`);
265
- } else {
266
- this.accessory.context.ProgrammableSwitchOutputStateOff = this.ProgrammableSwitchOff.ProgrammableSwitchOutputState;
267
- this.ProgrammableSwitchOff.Service.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchOutputState,
268
- this.ProgrammableSwitchOff.ProgrammableSwitchOutputState);
269
- await this.debugLog(`updateCharacteristic ProgrammableSwitchOutputStateOff: ${this.ProgrammableSwitchOff?.ProgrammableSwitchOutputState}`);
254
+ await this.updateCharacteristic(this.ProgrammableSwitchOff.Service, this.hap.Characteristic.ProgrammableSwitchOutputState,
255
+ this.ProgrammableSwitchOff.ProgrammableSwitchOutputState, 'ProgrammableSwitchOutputState');
270
256
  }
271
257
  }
272
258
  }
@@ -537,7 +537,7 @@ export class Others extends irdeviceBase {
537
537
  const { body, statusCode } = await this.pushChangeRequest(bodyChange);
538
538
  const deviceStatus: any = await body.json();
539
539
  await this.pushStatusCodes(statusCode, deviceStatus);
540
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
540
+ if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
541
541
  await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
542
542
  await this.updateHomeKitCharacteristics();
543
543
  } else {
@@ -369,7 +369,7 @@ export class TV extends irdeviceBase {
369
369
  const { body, statusCode } = await this.pushChangeRequest(bodyChange);
370
370
  const deviceStatus: any = await body.json();
371
371
  await this.pushStatusCodes(statusCode, deviceStatus);
372
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
372
+ if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
373
373
  await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
374
374
  await this.updateHomeKitCharacteristics();
375
375
  } else {
@@ -388,22 +388,11 @@ export class TV extends irdeviceBase {
388
388
  async updateHomeKitCharacteristics(): Promise<void> {
389
389
  await this.debugLog('updateHomeKitCharacteristics');
390
390
  // Active
391
- if (this.Television.Active === undefined) {
392
- await this.debugLog(`Active: ${this.Television.Active}`);
393
- } else {
394
- this.accessory.context.Active = this.Television.Active;
395
- this.Television.Service.updateCharacteristic(this.hap.Characteristic.Active, this.Television.Active);
396
- await this.debugLog(`updateCharacteristic Active: ${this.Television.Active}`);
397
- }
391
+ await this.updateCharacteristic(this.Television.Service, this.hap.Characteristic.Active,
392
+ this.Television.Active, 'Active');
398
393
  // ActiveIdentifier
399
- if (this.Television.ActiveIdentifier === undefined) {
400
- await this.debugLog(`ActiveIdentifier: ${this.Television.ActiveIdentifier}`);
401
- } else {
402
- this.accessory.context.ActiveIdentifier = this.Television.ActiveIdentifier;
403
- this.Television.Service.updateCharacteristic(this.hap.Characteristic.ActiveIdentifier, this.Television.ActiveIdentifier);
404
- await this.debugLog('updateCharacteristic'
405
- + ` ActiveIdentifier: ${this.Television.ActiveIdentifier}`);
406
- }
394
+ await this.updateCharacteristic(this.Television.Service, this.hap.Characteristic.ActiveIdentifier,
395
+ this.Television.ActiveIdentifier, 'ActiveIdentifier');
407
396
  }
408
397
 
409
398
  async apiError(e: any): Promise<void> {
@@ -103,7 +103,7 @@ export class VacuumCleaner extends irdeviceBase {
103
103
  const { body, statusCode } = await this.pushChangeRequest(bodyChange);
104
104
  const deviceStatus: any = await body.json();
105
105
  await this.pushStatusCodes(statusCode, deviceStatus);
106
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
106
+ if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
107
107
  await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
108
108
  await this.updateHomeKitCharacteristics();
109
109
  } else {
@@ -122,13 +122,8 @@ export class VacuumCleaner extends irdeviceBase {
122
122
  async updateHomeKitCharacteristics(): Promise<void> {
123
123
  await this.debugLog('updateHomeKitCharacteristics');
124
124
  // On
125
- if (this.Switch.On === undefined) {
126
- await this.debugLog(`On: ${this.Switch.On}`);
127
- } else {
128
- this.accessory.context.On = this.Switch.On;
129
- this.Switch.Service.updateCharacteristic(this.hap.Characteristic.On, this.Switch.On);
130
- await this.debugLog(`updateCharacteristic On: ${this.Switch.On}`);
131
- }
125
+ await this.updateCharacteristic(this.Switch.Service, this.hap.Characteristic.On,
126
+ this.Switch.On, 'On');
132
127
  }
133
128
 
134
129
  async apiError(e: any): Promise<void> {
@@ -105,7 +105,7 @@ export class WaterHeater extends irdeviceBase {
105
105
  const { body, statusCode } = await this.pushChangeRequest(bodyChange);
106
106
  const deviceStatus: any = await body.json();
107
107
  await this.pushStatusCodes(statusCode, deviceStatus);
108
- if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
108
+ if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
109
109
  await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
110
110
  await this.updateHomeKitCharacteristics();
111
111
  } else {
@@ -124,13 +124,8 @@ export class WaterHeater extends irdeviceBase {
124
124
  async updateHomeKitCharacteristics(): Promise<void> {
125
125
  await this.debugLog('updateHomeKitCharacteristics');
126
126
  // Active
127
- if (this.Valve.Active === undefined) {
128
- await this.debugLog(`Active: ${this.Valve.Active}`);
129
- } else {
130
- this.accessory.context.Active = this.Valve.Active;
131
- this.Valve.Service.updateCharacteristic(this.hap.Characteristic.Active, this.Valve.Active);
132
- await this.debugLog(`updateCharacteristic Active: ${this.Valve.Active}`);
133
- }
127
+ await this.updateCharacteristic(this.Valve.Service, this.hap.Characteristic.Active,
128
+ this.Valve.Active, 'Active');
134
129
  }
135
130
 
136
131
  async apiError({ e }: { e: any }): Promise<void> {
package/src/platform.ts CHANGED
@@ -33,21 +33,17 @@ import { AirConditioner } from './irdevice/airconditioner.js';
33
33
 
34
34
  import { Buffer } from 'buffer';
35
35
  import { request } from 'undici';
36
- import asyncmqtt from 'async-mqtt';
37
- import { createServer } from 'http';
38
36
  import { queueScheduler } from 'rxjs';
39
37
  import fakegato from 'fakegato-history';
40
38
  import crypto, { randomUUID } from 'crypto';
41
39
  import { readFileSync, writeFileSync } from 'fs';
42
40
  import { EveHomeKitTypes } from 'homebridge-lib/EveHomeKitTypes';
41
+ import { PLATFORM_NAME, PLUGIN_NAME, Devices } from './settings.js';
43
42
  import { isBlindTiltDevice, isCurtainDevice, sleep } from './utils.js';
44
- import { PLATFORM_NAME, PLUGIN_NAME, Devices, setupWebhook, updateWebhook, deleteWebhook, queryWebhook } from './settings.js';
45
43
 
46
44
  import type { UrlObject } from 'url';
47
- import type { MqttClient } from 'mqtt';
48
45
  import type { Dispatcher } from 'undici';
49
46
  import type { irdevice } from './types/irdevicelist.js';
50
- import type { Server, IncomingMessage, ServerResponse } from 'http';
51
47
  import type { blindTilt, curtain, curtain3, device } from './types/devicelist.js';
52
48
  import type { API, DynamicPlatformPlugin, Logging, PlatformAccessory } from 'homebridge';
53
49
  import type { SwitchBotPlatformConfig, devicesConfig, irDevicesConfig } from './settings.js';
@@ -71,12 +67,8 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
71
67
  platformLogging!: SwitchBotPlatformConfig['logging'];
72
68
  config!: SwitchBotPlatformConfig;
73
69
 
74
- webhookEventListener: Server | null = null;
75
- mqttClient: MqttClient | null = null;
76
-
77
70
  public readonly fakegatoAPI: any;
78
71
  public readonly eve: any;
79
- public readonly webhookEventHandler: { [x: string]: (context: any) => void } = {};
80
72
 
81
73
  constructor(
82
74
  log: Logging,
@@ -144,171 +136,6 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
144
136
  await this.debugErrorLog(`Failed to Discover, Error: ${e}`);
145
137
  }
146
138
  });
147
-
148
- this.setupMqtt();
149
- this.setupwebhook();
150
- }
151
-
152
- async setupMqtt(): Promise<void> {
153
- if (this.config.options?.mqttURL) {
154
- try {
155
- const { connectAsync } = asyncmqtt;
156
- this.mqttClient = await connectAsync(this.config.options?.mqttURL, this.config.options.mqttOptions || {});
157
- await this.debugLog('MQTT connection has been established successfully.');
158
- this.mqttClient.on('error', async (e: Error) => {
159
- await this.errorLog(`Failed to publish MQTT messages. ${e}`);
160
- });
161
- if (!this.config.options?.webhookURL) {
162
- // receive webhook events via MQTT
163
- await this.infoLog(`Webhook is configured to be received through ${this.config.options.mqttURL}/homebridge-switchbot/webhook.`);
164
- this.mqttClient.subscribe('homebridge-switchbot/webhook/+');
165
- this.mqttClient.on('message', async (topic: string, message) => {
166
- try {
167
- await await this.debugLog(`Received Webhook via MQTT: ${topic}=${message}`);
168
- const context = JSON.parse(message.toString());
169
- this.webhookEventHandler[context.deviceMac]?.(context);
170
- } catch (e: any) {
171
- await this.errorLog(`Failed to handle webhook event. Error:${e}`);
172
- }
173
- });
174
- }
175
- } catch (e) {
176
- this.mqttClient = null;
177
- await this.errorLog(`Failed to establish MQTT connection. ${e}`);
178
- }
179
- }
180
- }
181
-
182
- async setupwebhook() {
183
- //webhook configuration
184
- if (this.config.options?.webhookURL) {
185
- const url = this.config.options?.webhookURL;
186
-
187
- try {
188
- const xurl = new URL(url);
189
- const port = Number(xurl.port);
190
- const path = xurl.pathname;
191
- this.webhookEventListener = createServer((request: IncomingMessage, response: ServerResponse) => {
192
- try {
193
- if (request.url === path && request.method === 'POST') {
194
- request.on('data', async (data) => {
195
- try {
196
- const body = JSON.parse(data);
197
- await this.debugLog(`Received Webhook: ${JSON.stringify(body)}`);
198
- if (this.config.options?.mqttURL) {
199
- const mac = body.context.deviceMac
200
- ?.toLowerCase()
201
- .match(/[\s\S]{1,2}/g)
202
- ?.join(':');
203
- const options = this.config.options?.mqttPubOptions || {};
204
- this.mqttClient?.publish(`homebridge-switchbot/webhook/${mac}`, `${JSON.stringify(body.context)}`, options);
205
- }
206
- this.webhookEventHandler[body.context.deviceMac]?.(body.context);
207
- } catch (e: any) {
208
- this.errorLog(`Failed to handle webhook event. Error:${e}`);
209
- }
210
- });
211
- response.writeHead(200, { 'Content-Type': 'text/plain' });
212
- response.end('OK');
213
- }
214
- // else {
215
- // response.writeHead(403, {'Content-Type': 'text/plain'});
216
- // response.end(`NG`);
217
- // }
218
- } catch (e: any) {
219
- this.errorLog(`Failed to handle webhook event. Error:${e}`);
220
- }
221
- }).listen(port ? port : 80);
222
- } catch (e: any) {
223
- this.errorLog(`Failed to create webhook listener. Error:${e.message}`);
224
- return;
225
- }
226
-
227
- try {
228
- const { body, statusCode } = await request(setupWebhook, {
229
- method: 'POST',
230
- headers: this.generateHeaders(),
231
- body: JSON.stringify({
232
- 'action': 'setupWebhook',
233
- 'url': url,
234
- 'deviceList': 'ALL',
235
- }),
236
- });
237
- const response: any = await body.json();
238
- await this.debugLog(`setupWebhook: url:${url}`);
239
- await this.debugLog(`setupWebhook: body:${JSON.stringify(response)}`);
240
- await this.debugLog(`setupWebhook: statusCode:${statusCode}`);
241
- if (statusCode !== 200 || response?.statusCode !== 100) {
242
- this.errorLog(`Failed to configure webhook. Existing webhook well be overridden. HTTP:${statusCode} API:${response?.statusCode} `
243
- + `message:${response?.message}`);
244
- }
245
- } catch (e: any) {
246
- this.errorLog(`Failed to configure webhook. Error: ${e.message}`);
247
- }
248
-
249
- try {
250
- const { body, statusCode } = await request(updateWebhook, {
251
- method: 'POST', headers: this.generateHeaders(), body: JSON.stringify({
252
- 'action': 'updateWebhook',
253
- 'config': {
254
- 'url': url,
255
- 'enable': true,
256
- },
257
- }),
258
- });
259
- const response: any = await body.json();
260
- await this.debugLog(`updateWebhook: url:${url}`);
261
- await this.debugLog(`updateWebhook: body:${JSON.stringify(response)}`);
262
- await this.debugLog(`updateWebhook: statusCode:${statusCode}`);
263
- if (statusCode !== 200 || response?.statusCode !== 100) {
264
- this.errorLog(`Failed to update webhook. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`);
265
- }
266
- } catch (e: any) {
267
- this.errorLog(`Failed to update webhook. Error:${e.message}`);
268
- }
269
-
270
- try {
271
- const { body, statusCode } = await request(queryWebhook, {
272
- method: 'POST',
273
- headers: this.generateHeaders(),
274
- body: JSON.stringify({
275
- 'action': 'queryUrl',
276
- }),
277
- });
278
- const response: any = await body.json();
279
- await this.debugLog(`queryWebhook: body:${JSON.stringify(response)}`);
280
- await this.debugLog(`queryWebhook: statusCode:${statusCode}`);
281
- if (statusCode !== 200 || response?.statusCode !== 100) {
282
- this.errorLog(`Failed to query webhook. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`);
283
- } else {
284
- this.infoLog(`Listening webhook on ${response?.body?.urls[0]}`);
285
- }
286
- } catch (e: any) {
287
- this.errorLog(`Failed to query webhook. Error:${e}`);
288
- }
289
-
290
- this.api.on('shutdown', async () => {
291
- try {
292
- const { body, statusCode } = await request(deleteWebhook, {
293
- method: 'POST',
294
- headers: this.generateHeaders(),
295
- body: JSON.stringify({
296
- 'action': 'deleteWebhook',
297
- 'url': url,
298
- }),
299
- });
300
- const response: any = await body.json();
301
- await this.debugLog(`deleteWebhook: url:${url}, body:${JSON.stringify(response)}, statusCode:${statusCode}`);
302
- if (statusCode !== 200 || response?.statusCode !== 100) {
303
- this.errorLog(`Failed to delete webhook. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`);
304
- } else {
305
- this.infoLog('Unregistered webhook to close listening.');
306
- }
307
- } catch (e: any) {
308
- this.errorLog(`Failed to delete webhook. Error:${e.message}`);
309
- }
310
- });
311
- }
312
139
  }
313
140
 
314
141
  /**
@@ -2678,10 +2505,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2678
2505
  await this.errorLog(`Requests reached the daily limit, statusCode: ${statusCode}`);
2679
2506
  break;
2680
2507
  case 100:
2681
- await await this.debugLog(`Command successfully sent, statusCode: ${statusCode}`);
2508
+ await this.debugLog(`Command successfully sent, statusCode: ${statusCode}`);
2682
2509
  break;
2683
2510
  case 200:
2684
- await await this.debugLog(`Request successful, statusCode: ${statusCode}`);
2511
+ await this.debugLog(`Request successful, statusCode: ${statusCode}`);
2685
2512
  break;
2686
2513
  case 400:
2687
2514
  await this.errorLog('Bad Request, The client has issued an invalid request. This is commonly used to specify validation errors in a request '
@@ -2735,13 +2562,13 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2735
2562
  if (statusCode === 200 || statusCode === 100) {
2736
2563
  return { body, statusCode };
2737
2564
  } else {
2738
- await await this.debugLog(`Received status code: ${statusCode}`);
2565
+ await this.debugLog(`Received status code: ${statusCode}`);
2739
2566
  }
2740
2567
  } catch (error: any) {
2741
2568
  await this.errorLog(`Error making request: ${error.message}`);
2742
2569
  }
2743
2570
  retryCount++;
2744
- await await this.debugLog(`Retry attempt ${retryCount} of ${maxRetries}`);
2571
+ await this.debugLog(`Retry attempt ${retryCount} of ${maxRetries}`);
2745
2572
  await sleep(delayBetweenRetries);
2746
2573
  }
2747
2574
  return { body: null, statusCode: -1 };
@@ -2753,7 +2580,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2753
2580
  try {
2754
2581
  const SwitchBot = (await import('node-switchbot')).SwitchBot;
2755
2582
  queueScheduler.schedule(() => (switchbot = new SwitchBot()));
2756
- await await this.debugLog(`${device.deviceType}: ${accessory.displayName} 'node-switchbot' found: ${switchbot}`);
2583
+ await this.debugLog(`${device.deviceType}: ${accessory.displayName} 'node-switchbot' found: ${switchbot}`);
2757
2584
  } catch (e: any) {
2758
2585
  switchbot = false;
2759
2586
  await this.errorLog(`${device.deviceType}: ${accessory.displayName} 'node-switchbot' found: ${switchbot}, Error: ${e}`);
@@ -2768,7 +2595,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2768
2595
  'utf-8',
2769
2596
  ),
2770
2597
  );
2771
- await await this.debugLog(`Plugin Version: ${json.version}`);
2598
+ await this.debugLog(`Plugin Version: ${json.version}`);
2772
2599
  this.version = json.version;
2773
2600
  }
2774
2601
 
@@ -2804,7 +2631,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2804
2631
  platformConfig.delayBetweenRetries = this.delayBetweenRetries / 1000;
2805
2632
  }
2806
2633
  if (Object.entries(platformConfig).length !== 0) {
2807
- await await this.debugLog(`Platform Config: ${JSON.stringify(platformConfig)}`);
2634
+ await this.debugLog(`Platform Config: ${JSON.stringify(platformConfig)}`);
2808
2635
  }
2809
2636
  this.platformConfig = platformConfig;
2810
2637
  }
@@ -2814,13 +2641,13 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2814
2641
  this.debugMode = process.argv.includes('-D') || process.argv.includes('--debug');
2815
2642
  if (this.config.options?.logging === 'debug' || this.config.options?.logging === 'standard' || this.config.options?.logging === 'none') {
2816
2643
  this.platformLogging = this.config.options.logging;
2817
- await await this.debugWarnLog(`Using Config Logging: ${this.platformLogging}`);
2644
+ await this.debugWarnLog(`Using Config Logging: ${this.platformLogging}`);
2818
2645
  } else if (this.debugMode) {
2819
2646
  this.platformLogging = 'debugMode';
2820
- await await this.debugWarnLog(`Using ${this.platformLogging} Logging`);
2647
+ await this.debugWarnLog(`Using ${this.platformLogging} Logging`);
2821
2648
  } else {
2822
2649
  this.platformLogging = 'standard';
2823
- await await this.debugWarnLog(`Using ${this.platformLogging} Logging`);
2650
+ await this.debugWarnLog(`Using ${this.platformLogging} Logging`);
2824
2651
  }
2825
2652
  }
2826
2653