@switchbot/homebridge-switchbot 3.5.0-beta.9 → 3.5.1-beta.0

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 (177) hide show
  1. package/.vscode/settings.json +4 -1
  2. package/CHANGELOG.md +4 -1
  3. package/config.schema.json +164 -22
  4. package/dist/device/blindtilt.d.ts +21 -96
  5. package/dist/device/blindtilt.d.ts.map +1 -1
  6. package/dist/device/blindtilt.js +457 -866
  7. package/dist/device/blindtilt.js.map +1 -1
  8. package/dist/device/bot.d.ts +27 -72
  9. package/dist/device/bot.d.ts.map +1 -1
  10. package/dist/device/bot.js +851 -913
  11. package/dist/device/bot.js.map +1 -1
  12. package/dist/device/ceilinglight.d.ts +15 -69
  13. package/dist/device/ceilinglight.d.ts.map +1 -1
  14. package/dist/device/ceilinglight.js +316 -742
  15. package/dist/device/ceilinglight.js.map +1 -1
  16. package/dist/device/colorbulb.d.ts +15 -76
  17. package/dist/device/colorbulb.d.ts.map +1 -1
  18. package/dist/device/colorbulb.js +380 -833
  19. package/dist/device/colorbulb.js.map +1 -1
  20. package/dist/device/contact.d.ts +14 -66
  21. package/dist/device/contact.d.ts.map +1 -1
  22. package/dist/device/contact.js +267 -602
  23. package/dist/device/contact.js.map +1 -1
  24. package/dist/device/curtain.d.ts +18 -89
  25. package/dist/device/curtain.d.ts.map +1 -1
  26. package/dist/device/curtain.js +469 -897
  27. package/dist/device/curtain.js.map +1 -1
  28. package/dist/device/device.d.ts +76 -0
  29. package/dist/device/device.d.ts.map +1 -0
  30. package/dist/device/device.js +846 -0
  31. package/dist/device/device.js.map +1 -0
  32. package/dist/device/fan.d.ts +63 -0
  33. package/dist/device/fan.d.ts.map +1 -0
  34. package/dist/device/fan.js +645 -0
  35. package/dist/device/fan.js.map +1 -0
  36. package/dist/device/hub.d.ts +19 -58
  37. package/dist/device/hub.d.ts.map +1 -1
  38. package/dist/device/hub.js +304 -640
  39. package/dist/device/hub.js.map +1 -1
  40. package/dist/device/humidifier.d.ts +11 -66
  41. package/dist/device/humidifier.d.ts.map +1 -1
  42. package/dist/device/humidifier.js +300 -710
  43. package/dist/device/humidifier.js.map +1 -1
  44. package/dist/device/iosensor.d.ts +12 -64
  45. package/dist/device/iosensor.d.ts.map +1 -1
  46. package/dist/device/iosensor.js +225 -643
  47. package/dist/device/iosensor.js.map +1 -1
  48. package/dist/device/lightstrip.d.ts +12 -70
  49. package/dist/device/lightstrip.d.ts.map +1 -1
  50. package/dist/device/lightstrip.js +371 -742
  51. package/dist/device/lightstrip.js.map +1 -1
  52. package/dist/device/lock.d.ts +17 -63
  53. package/dist/device/lock.d.ts.map +1 -1
  54. package/dist/device/lock.js +309 -642
  55. package/dist/device/lock.js.map +1 -1
  56. package/dist/device/meter.d.ts +15 -64
  57. package/dist/device/meter.d.ts.map +1 -1
  58. package/dist/device/meter.js +223 -638
  59. package/dist/device/meter.js.map +1 -1
  60. package/dist/device/meterplus.d.ts +15 -65
  61. package/dist/device/meterplus.d.ts.map +1 -1
  62. package/dist/device/meterplus.js +216 -644
  63. package/dist/device/meterplus.js.map +1 -1
  64. package/dist/device/motion.d.ts +12 -69
  65. package/dist/device/motion.d.ts.map +1 -1
  66. package/dist/device/motion.js +209 -588
  67. package/dist/device/motion.js.map +1 -1
  68. package/dist/device/plug.d.ts +10 -57
  69. package/dist/device/plug.d.ts.map +1 -1
  70. package/dist/device/plug.js +141 -532
  71. package/dist/device/plug.js.map +1 -1
  72. package/dist/device/robotvacuumcleaner.d.ts +13 -63
  73. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  74. package/dist/device/robotvacuumcleaner.js +252 -609
  75. package/dist/device/robotvacuumcleaner.js.map +1 -1
  76. package/dist/device/waterdetector.d.ts +11 -63
  77. package/dist/device/waterdetector.d.ts.map +1 -1
  78. package/dist/device/waterdetector.js +179 -521
  79. package/dist/device/waterdetector.js.map +1 -1
  80. package/dist/homebridge-ui/public/index.html +22 -16
  81. package/dist/homebridge-ui/server.js +1 -1
  82. package/dist/homebridge-ui/server.js.map +1 -1
  83. package/dist/index.d.ts +1 -1
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +2 -2
  86. package/dist/index.js.map +1 -1
  87. package/dist/irdevice/airconditioner.d.ts +10 -50
  88. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  89. package/dist/irdevice/airconditioner.js +337 -482
  90. package/dist/irdevice/airconditioner.js.map +1 -1
  91. package/dist/irdevice/airpurifier.d.ts +8 -39
  92. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  93. package/dist/irdevice/airpurifier.js +108 -333
  94. package/dist/irdevice/airpurifier.js.map +1 -1
  95. package/dist/irdevice/camera.d.ts +7 -36
  96. package/dist/irdevice/camera.d.ts.map +1 -1
  97. package/dist/irdevice/camera.js +47 -299
  98. package/dist/irdevice/camera.js.map +1 -1
  99. package/dist/irdevice/fan.d.ts +7 -43
  100. package/dist/irdevice/fan.d.ts.map +1 -1
  101. package/dist/irdevice/fan.js +95 -364
  102. package/dist/irdevice/fan.js.map +1 -1
  103. package/dist/irdevice/irdevice.d.ts +46 -0
  104. package/dist/irdevice/irdevice.d.ts.map +1 -0
  105. package/dist/irdevice/irdevice.js +393 -0
  106. package/dist/irdevice/irdevice.js.map +1 -0
  107. package/dist/irdevice/light.d.ts +12 -45
  108. package/dist/irdevice/light.d.ts.map +1 -1
  109. package/dist/irdevice/light.js +121 -376
  110. package/dist/irdevice/light.js.map +1 -1
  111. package/dist/irdevice/other.d.ts +19 -48
  112. package/dist/irdevice/other.d.ts.map +1 -1
  113. package/dist/irdevice/other.js +441 -584
  114. package/dist/irdevice/other.js.map +1 -1
  115. package/dist/irdevice/tv.d.ts +8 -40
  116. package/dist/irdevice/tv.d.ts.map +1 -1
  117. package/dist/irdevice/tv.js +94 -353
  118. package/dist/irdevice/tv.js.map +1 -1
  119. package/dist/irdevice/vacuumcleaner.d.ts +7 -36
  120. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  121. package/dist/irdevice/vacuumcleaner.js +48 -299
  122. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  123. package/dist/irdevice/waterheater.d.ts +7 -36
  124. package/dist/irdevice/waterheater.d.ts.map +1 -1
  125. package/dist/irdevice/waterheater.js +50 -305
  126. package/dist/irdevice/waterheater.js.map +1 -1
  127. package/dist/platform.d.ts +22 -8
  128. package/dist/platform.d.ts.map +1 -1
  129. package/dist/platform.js +342 -191
  130. package/dist/platform.js.map +1 -1
  131. package/dist/settings.d.ts +66 -18
  132. package/dist/settings.d.ts.map +1 -1
  133. package/dist/settings.js +16 -552
  134. package/dist/settings.js.map +1 -1
  135. package/dist/utils.d.ts +95 -0
  136. package/dist/utils.d.ts.map +1 -1
  137. package/dist/utils.js +657 -1
  138. package/dist/utils.js.map +1 -1
  139. package/eslint.config.js +96 -0
  140. package/package.json +20 -16
  141. package/src/custom.d.ts +2 -1
  142. package/src/device/blindtilt.ts +488 -937
  143. package/src/device/bot.ts +907 -1016
  144. package/src/device/ceilinglight.ts +330 -798
  145. package/src/device/colorbulb.ts +394 -904
  146. package/src/device/contact.ts +298 -637
  147. package/src/device/curtain.ts +496 -954
  148. package/src/device/device.ts +872 -0
  149. package/src/device/fan.ts +692 -0
  150. package/src/device/hub.ts +338 -671
  151. package/src/device/humidifier.ts +330 -777
  152. package/src/device/iosensor.ts +258 -671
  153. package/src/device/lightstrip.ts +394 -809
  154. package/src/device/lock.ts +345 -700
  155. package/src/device/meter.ts +256 -666
  156. package/src/device/meterplus.ts +248 -672
  157. package/src/device/motion.ts +234 -622
  158. package/src/device/plug.ts +152 -572
  159. package/src/device/robotvacuumcleaner.ts +273 -653
  160. package/src/device/waterdetector.ts +198 -549
  161. package/src/homebridge-ui/public/index.html +22 -16
  162. package/src/homebridge-ui/server.ts +1 -1
  163. package/src/index.ts +4 -3
  164. package/src/irdevice/airconditioner.ts +368 -540
  165. package/src/irdevice/airpurifier.ts +134 -369
  166. package/src/irdevice/camera.ts +60 -324
  167. package/src/irdevice/fan.ts +111 -392
  168. package/src/irdevice/irdevice.ts +406 -0
  169. package/src/irdevice/light.ts +159 -425
  170. package/src/irdevice/other.ts +509 -661
  171. package/src/irdevice/tv.ts +123 -388
  172. package/src/irdevice/vacuumcleaner.ts +61 -324
  173. package/src/irdevice/waterheater.ts +63 -333
  174. package/src/platform.ts +395 -259
  175. package/src/settings.ts +120 -610
  176. package/src/utils.ts +661 -1
  177. package/src/device/waterdetector.json +0 -11
@@ -1,298 +1,248 @@
1
- import { request } from 'undici';
2
- import { sleep } from '../utils.js';
1
+ /* Copyright(C) 2021-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved.
2
+ *
3
+ * contact.ts: @switchbot/homebridge-switchbot.
4
+ */
5
+ import { deviceBase } from './device.js';
3
6
  import { interval, Subject } from 'rxjs';
4
7
  import { skipWhile } from 'rxjs/operators';
5
- import { Devices } from '../settings.js';
6
8
  /**
7
9
  * Platform Accessory
8
10
  * An instance of this class is created for each accessory your platform registers
9
11
  * Each accessory may expose multiple services of different service types.
10
12
  */
11
- export class Contact {
13
+ export class Contact extends deviceBase {
12
14
  platform;
13
- accessory;
14
- device;
15
- api;
16
- log;
17
- config;
18
- hap;
19
15
  // Services
20
- motionService;
21
- batteryService;
22
- lightSensorService;
23
- contactSensorservice;
24
- // Characteristic Values
25
- BatteryLevel;
26
- MotionDetected;
27
- StatusLowBattery;
28
- FirmwareRevision;
29
- ContactSensorState;
30
- CurrentAmbientLightLevel;
31
- // OpenAPI Status
32
- OpenAPI_BatteryLevel;
33
- OpenAPI_FirmwareRevision;
34
- OpenAPI_MotionDetected;
35
- OpenAPI_ContactSensorState;
36
- OpenAPI_CurrentAmbientLightLevel;
37
- // BLE Status
38
- BLE_BatteryLevel;
39
- BLE_MotionDetected;
40
- BLE_ContactSensorState;
41
- BLE_CurrentAmbientLightLevel;
42
- // BLE Others
43
- scanning;
44
- BLE_IsConnected;
45
- // Config
46
- set_minLux;
47
- set_maxLux;
48
- scanDuration;
49
- deviceLogging;
50
- deviceRefreshRate;
16
+ ContactSensor;
17
+ Battery;
18
+ MotionSensor;
19
+ LightSensor;
51
20
  // Updates
52
- contactUbpdateInProgress;
21
+ contactUpdateInProgress;
53
22
  doContactUpdate;
54
- // Connection
55
- OpenAPI;
56
- BLE;
57
23
  constructor(platform, accessory, device) {
24
+ super(platform, accessory, device);
58
25
  this.platform = platform;
59
- this.accessory = accessory;
60
- this.device = device;
61
- this.api = this.platform.api;
62
- this.log = this.platform.log;
63
- this.config = this.platform.config;
64
- this.hap = this.api.hap;
65
- // Connection
66
- this.BLE = this.device.connectionType === 'BLE' || this.device.connectionType === 'BLE/OpenAPI';
67
- this.OpenAPI = this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'BLE/OpenAPI';
68
- // default placeholders
69
- this.deviceLogs(device);
70
- this.scan(device);
71
- this.refreshRate(device);
72
- this.deviceContext();
73
- this.deviceConfig(device);
74
26
  // this is subject we use to track when we need to POST changes to the SwitchBot API
75
27
  this.doContactUpdate = new Subject();
76
- this.contactUbpdateInProgress = false;
77
- // Retrieve initial values and updateHomekit
78
- this.refreshStatus();
79
- // set accessory information
80
- accessory
81
- .getService(this.hap.Service.AccessoryInformation)
82
- .setCharacteristic(this.hap.Characteristic.Manufacturer, 'SwitchBot')
83
- .setCharacteristic(this.hap.Characteristic.Model, 'W1201500')
84
- .setCharacteristic(this.hap.Characteristic.SerialNumber, device.deviceId)
85
- .setCharacteristic(this.hap.Characteristic.FirmwareRevision, accessory.context.FirmwareRevision);
86
- // get the Contact service if it exists, otherwise create a new Contact service
87
- // you can create multiple services for each accessory
88
- const contactSensorservice = `${accessory.displayName} Contact Sensor`;
89
- (this.contactSensorservice = accessory.getService(this.hap.Service.ContactSensor)
90
- || accessory.addService(this.hap.Service.ContactSensor)), contactSensorservice;
91
- this.contactSensorservice.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
92
- if (!this.contactSensorservice.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
93
- this.contactSensorservice.addCharacteristic(this.hap.Characteristic.ConfiguredName, accessory.displayName);
94
- }
95
- // Motion Sensor Service
96
- if (device.contact?.hide_motionsensor) {
97
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Motion Sensor Service`);
98
- this.motionService = this.accessory.getService(this.hap.Service.MotionSensor);
99
- accessory.removeService(this.motionService);
100
- }
101
- else if (!this.motionService) {
102
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Motion Sensor Service`);
103
- const motionService = `${accessory.displayName} Motion Sensor`;
104
- (this.motionService = this.accessory.getService(this.hap.Service.MotionSensor)
105
- || this.accessory.addService(this.hap.Service.MotionSensor)), motionService;
106
- this.motionService.setCharacteristic(this.hap.Characteristic.Name, `${accessory.displayName} Motion Sensor`);
107
- this.motionService.setCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Motion Sensor`);
28
+ this.contactUpdateInProgress = false;
29
+ // Initialize Contact Sensor Service
30
+ accessory.context.ContactSensor = accessory.context.ContactSensor ?? {};
31
+ this.ContactSensor = {
32
+ Name: accessory.context.ContactSensor.Name ?? accessory.displayName,
33
+ Service: accessory.getService(this.hap.Service.ContactSensor) ?? accessory.addService(this.hap.Service.ContactSensor),
34
+ ContactSensorState: accessory.context.ContactSensorState ?? this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED,
35
+ };
36
+ accessory.context.ContactSensor = this.ContactSensor;
37
+ // Initialize ContactSensor Characteristics
38
+ this.ContactSensor.Service
39
+ .setCharacteristic(this.hap.Characteristic.Name, this.ContactSensor.Name)
40
+ .setCharacteristic(this.hap.Characteristic.StatusActive, true)
41
+ .getCharacteristic(this.hap.Characteristic.ContactSensorState)
42
+ .onGet(() => {
43
+ return this.ContactSensor.ContactSensorState;
44
+ });
45
+ // Initialize Battery Service
46
+ accessory.context.Battery = accessory.context.Battery ?? {};
47
+ this.Battery = {
48
+ Name: accessory.context.Battery.Name ?? `${accessory.displayName} Battery`,
49
+ Service: accessory.getService(this.hap.Service.Battery) ?? accessory.addService(this.hap.Service.Battery),
50
+ BatteryLevel: accessory.context.BatteryLevel ?? 100,
51
+ StatusLowBattery: accessory.context.StatusLowBattery ?? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
52
+ };
53
+ accessory.context.Battery = this.Battery;
54
+ // Initialize Battery Characteristics
55
+ this.Battery.Service
56
+ .setCharacteristic(this.hap.Characteristic.Name, this.Battery.Name)
57
+ .setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE)
58
+ .getCharacteristic(this.hap.Characteristic.BatteryLevel)
59
+ .onGet(() => {
60
+ return this.Battery.BatteryLevel;
61
+ });
62
+ this.Battery.Service
63
+ .setCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery)
64
+ .getCharacteristic(this.hap.Characteristic.StatusLowBattery)
65
+ .onGet(() => {
66
+ return this.Battery.StatusLowBattery;
67
+ });
68
+ // Initialize Motion Sensor Service
69
+ if (this.device.contact?.hide_motionsensor) {
70
+ if (this.MotionSensor) {
71
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} Removing Motion Sensor Service`);
72
+ this.MotionSensor.Service = accessory.getService(this.hap.Service.MotionSensor);
73
+ accessory.removeService(this.MotionSensor.Service);
74
+ }
108
75
  }
109
76
  else {
110
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Motion Sensor Service Not Added`);
77
+ accessory.context.MotionSensor = accessory.context.MotionSensor ?? {};
78
+ this.MotionSensor = {
79
+ Name: accessory.context.MotionSensor.Name ?? `${accessory.displayName} Motion Sensor`,
80
+ Service: accessory.getService(this.hap.Service.MotionSensor) ?? accessory.addService(this.hap.Service.MotionSensor),
81
+ MotionDetected: accessory.context.MotionDetected ?? false,
82
+ };
83
+ accessory.context.MotionSensor = this.MotionSensor;
84
+ // Motion Sensor Characteristics
85
+ this.MotionSensor.Service
86
+ .setCharacteristic(this.hap.Characteristic.Name, this.MotionSensor.Name)
87
+ .setCharacteristic(this.hap.Characteristic.StatusActive, true)
88
+ .getCharacteristic(this.hap.Characteristic.MotionDetected)
89
+ .onGet(() => {
90
+ return this.MotionSensor.MotionDetected;
91
+ });
111
92
  }
112
- // Light Sensor Service
93
+ // Initialize Light Sensor Service
113
94
  if (device.contact?.hide_lightsensor) {
114
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Light Sensor Service`);
115
- this.lightSensorService = this.accessory.getService(this.hap.Service.LightSensor);
116
- accessory.removeService(this.lightSensorService);
117
- }
118
- else if (!this.lightSensorService) {
119
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Light Sensor Service`);
120
- const lightSensorService = `${accessory.displayName} Light Sensor`;
121
- (this.lightSensorService = this.accessory.getService(this.hap.Service.LightSensor)
122
- || this.accessory.addService(this.hap.Service.LightSensor)), lightSensorService;
123
- this.lightSensorService.setCharacteristic(this.hap.Characteristic.Name, `${accessory.displayName} Light Sensor`);
124
- this.lightSensorService.setCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Light Sensor`);
95
+ if (this.LightSensor) {
96
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Light Sensor Service`);
97
+ this.LightSensor.Service = accessory.getService(this.hap.Service.LightSensor);
98
+ accessory.removeService(this.LightSensor.Service);
99
+ }
125
100
  }
126
101
  else {
127
- this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Light Sensor Service Not Added`);
128
- }
129
- // Battery Service
130
- const batteryService = `${accessory.displayName} Battery`;
131
- (this.batteryService = this.accessory.getService(this.hap.Service.Battery)
132
- || accessory.addService(this.hap.Service.Battery)), batteryService;
133
- this.batteryService.setCharacteristic(this.hap.Characteristic.Name, `${accessory.displayName} Battery`);
134
- if (!this.batteryService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
135
- this.batteryService.addCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Battery`);
102
+ accessory.context.LightSensor = accessory.context.LightSensor ?? {};
103
+ this.LightSensor = {
104
+ Name: accessory.context.LightSensor.Name ?? `${accessory.displayName} Light Sensor`,
105
+ Service: accessory.getService(this.hap.Service.LightSensor) ?? accessory.addService(this.hap.Service.LightSensor),
106
+ CurrentAmbientLightLevel: accessory.context.CurrentAmbientLightLevel ?? 0.0001,
107
+ };
108
+ accessory.context.LightSensor = this.LightSensor;
109
+ // Light Sensor Characteristics
110
+ this.LightSensor.Service
111
+ .setCharacteristic(this.hap.Characteristic.Name, this.LightSensor.Name)
112
+ .setCharacteristic(this.hap.Characteristic.StatusActive, true)
113
+ .getCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel)
114
+ .onGet(() => {
115
+ return this.LightSensor.CurrentAmbientLightLevel;
116
+ });
136
117
  }
137
- this.batteryService.setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE);
118
+ // Retrieve initial values and updateHomekit
119
+ this.refreshStatus();
138
120
  // Retrieve initial values and updateHomekit
139
121
  this.updateHomeKitCharacteristics();
140
122
  // Start an update interval
141
123
  interval(this.deviceRefreshRate * 1000)
142
- .pipe(skipWhile(() => this.contactUbpdateInProgress))
124
+ .pipe(skipWhile(() => this.contactUpdateInProgress))
143
125
  .subscribe(async () => {
144
126
  await this.refreshStatus();
145
127
  });
146
128
  //regisiter webhook event handler
147
- if (this.device.webhook) {
148
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} is listening webhook.`);
149
- this.platform.webhookEventHandler[this.device.deviceId] = async (context) => {
150
- try {
151
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
152
- const { detectionState, brightness, openState } = context;
153
- const { MotionDetected, CurrentAmbientLightLevel, ContactSensorState } = this;
154
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ` +
155
- '(detectionState, brightness, openState) = ' +
156
- `Webhook:(${detectionState}, ${brightness}, ${openState}), ` +
157
- `current:(${MotionDetected}, ${CurrentAmbientLightLevel}, ${ContactSensorState})`);
158
- this.set_minLux = this.minLux();
159
- this.set_maxLux = this.maxLux();
160
- this.MotionDetected = detectionState === 'DETECTED' ? true : false;
161
- this.CurrentAmbientLightLevel = brightness === 'bright' ? this.set_maxLux : this.set_minLux;
162
- this.ContactSensorState = openState === 'open' ? 1 : 0;
163
- this.updateHomeKitCharacteristics();
164
- }
165
- catch (e) {
166
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
167
- + `failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
168
- }
169
- };
170
- }
129
+ this.registerWebhook(accessory, device);
171
130
  }
172
- /**
173
- * Parse the device status from the SwitchBot api
174
- */
175
- async parseStatus() {
176
- if (!this.device.enableCloudService && this.OpenAPI) {
177
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} parseStatus enableCloudService: ${this.device.enableCloudService}`);
178
- }
179
- else if (this.BLE) {
180
- await this.BLEparseStatus();
181
- }
182
- else if (this.OpenAPI && this.platform.config.credentials?.token) {
183
- await this.openAPIparseStatus();
184
- }
185
- else {
186
- await this.offlineOff();
187
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:` + ` ${this.device.connectionType}, parseStatus will not happen.`);
188
- }
189
- }
190
- async BLEparseStatus() {
131
+ async BLEparseStatus(serviceData) {
191
132
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
192
133
  // Door State
193
- switch (this.BLE_ContactSensorState) {
134
+ switch (serviceData.doorState) {
194
135
  case 'open':
195
136
  case 1:
196
- this.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
137
+ this.ContactSensor.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
197
138
  break;
198
139
  case 'close':
199
140
  case 0:
200
- this.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED;
141
+ this.ContactSensor.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED;
201
142
  break;
202
143
  default:
203
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} timeout no closed, doorstate: ${this.BLE_ContactSensorState}`);
144
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} timeout no closed, doorstate: ${serviceData.doorState}`);
204
145
  }
205
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
206
- if (this.ContactSensorState !== this.accessory.context.ContactSensorState &&
146
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensor.ContactSensorState}`);
147
+ if (this.ContactSensor.ContactSensorState !== this.accessory.context.ContactSensorState &&
207
148
  this.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED) {
208
149
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Opened`);
209
150
  }
210
151
  // Movement
211
152
  if (!this.device.contact?.hide_motionsensor) {
212
- this.MotionDetected = Boolean(this.BLE_MotionDetected);
213
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
214
- if (this.MotionDetected !== this.accessory.context.MotionDetected && this.MotionDetected) {
153
+ this.MotionSensor.MotionDetected = Boolean(serviceData.movement);
154
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionSensor.MotionDetected}`);
155
+ if (this.MotionSensor.MotionDetected !== this.accessory.context.MotionDetected && this.MotionSensor.MotionDetected) {
215
156
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Detected Motion`);
216
157
  }
217
158
  }
218
159
  // Light Level
219
160
  if (!this.device.contact?.hide_lightsensor) {
220
- this.set_minLux = this.minLux();
221
- this.set_maxLux = this.maxLux();
222
- switch (this.BLE_CurrentAmbientLightLevel) {
161
+ const set_minLux = this.device.contact?.set_minLux ?? 1;
162
+ const set_maxLux = this.device.contact?.set_maxLux ?? 6001;
163
+ switch (serviceData.lightLevel) {
223
164
  case true:
224
- this.CurrentAmbientLightLevel = this.set_minLux;
165
+ this.LightSensor.CurrentAmbientLightLevel = set_minLux;
225
166
  break;
226
167
  default:
227
- this.CurrentAmbientLightLevel = this.set_maxLux;
168
+ this.LightSensor.CurrentAmbientLightLevel = set_maxLux;
228
169
  }
229
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.BLE_CurrentAmbientLightLevel},` +
230
- ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
231
- if (this.CurrentAmbientLightLevel !== this.accessory.context.CurrentAmbientLightLevel) {
232
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
170
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel},`
171
+ + ` CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`);
172
+ if (this.LightSensor.CurrentAmbientLightLevel !== this.accessory.context.CurrentAmbientLightLevel) {
173
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName}`
174
+ + ` CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`);
233
175
  }
234
176
  }
235
177
  // Battery
236
- if (this.BLE_BatteryLevel === undefined) {
237
- this.BLE_BatteryLevel === 100;
238
- }
239
- this.BatteryLevel = Number(this.BLE_BatteryLevel);
240
- if (this.BatteryLevel < 10) {
241
- this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
178
+ this.Battery.BatteryLevel = Number(serviceData.battery);
179
+ if (this.Battery.BatteryLevel < 10) {
180
+ this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
242
181
  }
243
182
  else {
244
- this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
183
+ this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
245
184
  }
246
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, ` + `StatusLowBattery: ${this.StatusLowBattery}`);
185
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}, `
186
+ + `StatusLowBattery: ${this.Battery.StatusLowBattery}`);
247
187
  }
248
- async openAPIparseStatus() {
188
+ async openAPIparseStatus(deviceStatus) {
249
189
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
250
190
  // Contact State
251
- if (this.OpenAPI_ContactSensorState === 'open') {
252
- this.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
253
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
191
+ if (deviceStatus.body.openState === 'open') {
192
+ this.ContactSensor.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
193
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensor.ContactSensorState}`);
254
194
  }
255
- else if (this.OpenAPI_ContactSensorState === 'close') {
256
- this.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED;
257
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
195
+ else if (deviceStatus.body.openState === 'close') {
196
+ this.ContactSensor.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED;
197
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensor.ContactSensorState}`);
258
198
  }
259
199
  else {
260
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openState: ${this.OpenAPI_ContactSensorState}`);
200
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openState: ${deviceStatus.body.openState}`);
261
201
  }
262
202
  // Motion State
263
203
  if (!this.device.contact?.hide_motionsensor) {
264
- this.MotionDetected = this.OpenAPI_MotionDetected;
265
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
204
+ this.MotionSensor.MotionDetected = deviceStatus.body.moveDetected;
205
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionSensor.MotionDetected}`);
266
206
  }
267
207
  // Light Level
268
208
  if (!this.device.contact?.hide_lightsensor) {
269
- this.set_minLux = this.minLux();
270
- this.set_maxLux = this.maxLux();
271
- switch (this.OpenAPI_CurrentAmbientLightLevel) {
209
+ const set_minLux = this.device.contact?.set_minLux ?? 1;
210
+ const set_maxLux = this.device.contact?.set_maxLux ?? 6001;
211
+ switch (deviceStatus.body.brightness) {
272
212
  case 'dim':
273
- this.CurrentAmbientLightLevel = this.set_minLux;
213
+ this.LightSensor.CurrentAmbientLightLevel = set_minLux;
274
214
  break;
275
215
  case 'bright':
276
216
  default:
277
- this.CurrentAmbientLightLevel = this.set_maxLux;
217
+ this.LightSensor.CurrentAmbientLightLevel = set_maxLux;
278
218
  }
279
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
219
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
220
+ + ` CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`);
280
221
  }
281
222
  // Battery
282
- if (this.OpenAPI_BatteryLevel === undefined) {
283
- this.OpenAPI_BatteryLevel === 100;
284
- }
285
- this.BatteryLevel = Number(this.OpenAPI_BatteryLevel);
286
- if (this.BatteryLevel < 10) {
287
- this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
223
+ this.Battery.BatteryLevel = Number(deviceStatus.body.battery);
224
+ if (this.Battery.BatteryLevel < 10) {
225
+ this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
288
226
  }
289
227
  else {
290
- this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
228
+ this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
229
+ }
230
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}, `
231
+ + `StatusLowBattery: ${this.Battery.StatusLowBattery}`);
232
+ // Firmware Version
233
+ const version = deviceStatus.body.version?.toString();
234
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Firmware Version: ${version?.replace(/^V|-.*$/g, '')}`);
235
+ if (deviceStatus.body.version) {
236
+ const deviceVersion = version?.replace(/^V|-.*$/g, '') ?? '0.0.0';
237
+ this.accessory
238
+ .getService(this.hap.Service.AccessoryInformation)
239
+ .setCharacteristic(this.hap.Characteristic.HardwareRevision, deviceVersion)
240
+ .setCharacteristic(this.hap.Characteristic.FirmwareRevision, deviceVersion)
241
+ .getCharacteristic(this.hap.Characteristic.FirmwareRevision)
242
+ .updateValue(deviceVersion);
243
+ this.accessory.context.deviceVersion = deviceVersion;
244
+ this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceVersion: ${this.accessory.context.deviceVersion}`);
291
245
  }
292
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, ` + `StatusLowBattery: ${this.StatusLowBattery}`);
293
- // FirmwareRevision
294
- this.FirmwareRevision = this.OpenAPI_FirmwareRevision;
295
- this.accessory.context.FirmwareRevision = this.FirmwareRevision;
296
246
  }
297
247
  /**
298
248
  * Asks the SwitchBot API for the latest device information
@@ -309,211 +259,139 @@ export class Contact {
309
259
  }
310
260
  else {
311
261
  await this.offlineOff();
312
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:` +
313
- ` ${this.device.connectionType}, refreshStatus will not happen.`);
262
+ this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
263
+ + ` ${this.device.connectionType}, refreshStatus will not happen.`);
314
264
  }
315
265
  }
316
266
  async BLERefreshStatus() {
317
267
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
318
- const switchbot = await this.platform.connectBLE();
319
- // Convert to BLE Address
320
- this.device.bleMac =
321
- this.device.customBLEaddress ||
322
- this.device
323
- .deviceId.match(/.{1,2}/g)
324
- .join(':')
325
- .toLowerCase();
326
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
327
- this.getCustomBLEAddress(switchbot);
328
- // Start to monitor advertisement packets
329
- (async () => {
330
- await switchbot.startScan({
331
- model: 'd',
332
- id: this.device.bleMac,
333
- });
334
- // Set an event handler
335
- switchbot.onadvertisement = (ad) => {
336
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
337
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.serviceData.model}`);
338
- if (this.device.bleMac === ad.address && ad.serviceData.model === 'd') {
339
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
340
- this.BLE_MotionDetected = ad.serviceData.movement;
341
- this.BLE_BatteryLevel = ad.serviceData.battery;
342
- this.BLE_CurrentAmbientLightLevel = ad.serviceData.lightLevel;
268
+ const switchbot = await this.switchbotBLE();
269
+ if (switchbot === undefined) {
270
+ await this.BLERefreshConnection(switchbot);
271
+ }
272
+ else {
273
+ // Start to monitor advertisement packets
274
+ (async () => {
275
+ // Start to monitor advertisement packets
276
+ const serviceData = await this.monitorAdvertisementPackets(switchbot);
277
+ // Update HomeKit
278
+ if (serviceData.model !== '' && serviceData.modelName !== '') {
279
+ await this.BLEparseStatus(serviceData);
280
+ await this.updateHomeKitCharacteristics();
343
281
  }
344
282
  else {
345
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
346
- }
347
- };
348
- // Wait 1 seconds
349
- await switchbot.wait(this.scanDuration * 1000);
350
- // Stop to monitor
351
- await switchbot.stopScan();
352
- // Update HomeKit
353
- await this.BLEparseStatus();
354
- await this.updateHomeKitCharacteristics();
355
- })();
356
- /*if (switchbot !== false) {
357
- await switchbot
358
- .startScan({
359
- model: 'd',
360
- id: this.device.bleMac,
361
- })
362
- .then(async () => {
363
- // Set an event handler
364
- this.scanning = true;
365
- switchbot.onadvertisement = async (ad: ad) => {
366
- this.debugLog(
367
- `${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},` +
368
- ` BLE Address Found: ${ad.address}`,
369
- );
370
- this.BLE_MotionDetected = ad.serviceData.movement;
371
- this.BLE_BatteryLevel = ad.serviceData.battery;
372
- this.BLE_ContactSensorState = ad.serviceData.doorState;
373
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
374
- this.debugLog(
375
- `${this.device.deviceType}: ${this.accessory.displayName} movement: ${ad.serviceData.movement}, doorState: ` +
376
- `${ad.serviceData.doorState}, battery: ${ad.serviceData.battery}`,
377
- );
378
-
379
- if (ad.serviceData) {
380
- this.BLE_IsConnected = true;
381
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
382
- await this.stopScanning(switchbot);
383
- this.scanning = false;
384
- } else {
385
- this.BLE_IsConnected = false;
386
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
283
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
284
+ await this.BLERefreshConnection(switchbot);
387
285
  }
388
- };
389
- // Wait
390
- return await sleep(this.scanDuration * 1000);
391
- })
392
- .then(async () => {
393
- // Stop to monitor
394
- if (this.scanning) {
395
- await this.stopScanning(switchbot);
396
- }
397
- })
398
- .catch(async (e: any) => {
399
- this.apiError(e);
400
- this.errorLog(
401
- `${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}` +
402
- ` Connection, Error Message: ${JSON.stringify(e.message)}`,
403
- );
404
- await this.BLERefreshConnection(switchbot);
405
- });
406
- } else {
407
- await this.BLERefreshConnection(switchbot);
408
- }*/
286
+ })();
287
+ }
409
288
  }
410
289
  async openAPIRefreshStatus() {
411
290
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
412
291
  try {
413
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
414
- headers: this.platform.generateHeaders(),
415
- });
416
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
292
+ const { body, statusCode } = await this.deviceRefreshStatus();
417
293
  const deviceStatus = await body.json();
418
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
419
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
294
+ await this.refreshStatusCodes(statusCode, deviceStatus);
295
+ ;
420
296
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
421
- this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
422
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
423
- this.OpenAPI_ContactSensorState = deviceStatus.body.openState;
424
- this.OpenAPI_MotionDetected = deviceStatus.body.moveDetected;
425
- this.OpenAPI_CurrentAmbientLightLevel = deviceStatus.body.brightness;
426
- this.OpenAPI_BatteryLevel = deviceStatus.body.battery;
427
- this.OpenAPI_FirmwareRevision = deviceStatus.body.version;
428
- this.openAPIparseStatus();
429
- this.updateHomeKitCharacteristics();
297
+ await this.successfulRefreshStatus(statusCode, deviceStatus);
298
+ await this.openAPIparseStatus(deviceStatus);
299
+ await this.updateHomeKitCharacteristics();
430
300
  }
431
301
  else {
432
- this.statusCode(statusCode);
433
- this.statusCode(deviceStatus.statusCode);
302
+ await this.statusCodes(statusCode, deviceStatus);
434
303
  }
435
304
  }
436
305
  catch (e) {
437
306
  this.apiError(e);
438
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}` +
439
- ` Connection, Error Message: ${JSON.stringify(e.message)}`);
307
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
308
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
309
+ }
310
+ }
311
+ async registerWebhook(accessory, device) {
312
+ if (device.webhook) {
313
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} is listening webhook.`);
314
+ this.platform.webhookEventHandler[device.deviceId] = async (context) => {
315
+ try {
316
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
317
+ const { detectionState, brightness, openState } = context;
318
+ const { ContactSensorState } = this.ContactSensor;
319
+ const { CurrentAmbientLightLevel } = this.LightSensor ?? {};
320
+ const { MotionDetected } = this.MotionSensor ?? {};
321
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} (detectionState, brightness, openState) = Webhook:(${detectionState}, `
322
+ + `${brightness}, ${openState}), current:(${MotionDetected}, ${CurrentAmbientLightLevel}, ${ContactSensorState})`);
323
+ const set_minLux = this.device.contact?.set_minLux ?? 1;
324
+ const set_maxLux = this.device.contact?.set_maxLux ?? 6001;
325
+ this.ContactSensor.ContactSensorState = openState === 'open' ? 1 : 0;
326
+ if (!device.contact?.hide_motionsensor) {
327
+ this.MotionSensor.MotionDetected = detectionState === 'DETECTED' ? true : false;
328
+ }
329
+ if (!device.contact?.hide_lightsensor) {
330
+ this.LightSensor.CurrentAmbientLightLevel = brightness === 'bright' ? set_maxLux : set_minLux;
331
+ }
332
+ this.updateHomeKitCharacteristics();
333
+ }
334
+ catch (e) {
335
+ this.errorLog(`${device.deviceType}: ${accessory.displayName} failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
336
+ }
337
+ };
338
+ }
339
+ else {
340
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} is not listening webhook.`);
440
341
  }
441
342
  }
442
343
  /**
443
344
  * Updates the status for each of the HomeKit Characteristics
444
345
  */
445
346
  async updateHomeKitCharacteristics() {
446
- if (this.ContactSensorState === undefined) {
447
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
347
+ if (this.ContactSensor.ContactSensorState === undefined) {
348
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensor.ContactSensorState}`);
448
349
  }
449
350
  else {
450
- this.accessory.context.ContactSensorState = this.ContactSensorState;
451
- this.contactSensorservice.updateCharacteristic(this.hap.Characteristic.ContactSensorState, this.ContactSensorState);
452
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic ContactSensorState: ${this.ContactSensorState}`);
351
+ this.accessory.context.ContactSensorState = this.ContactSensor.ContactSensorState;
352
+ this.ContactSensor.Service.updateCharacteristic(this.hap.Characteristic.ContactSensorState, this.ContactSensor.ContactSensorState);
353
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
354
+ + ` ContactSensorState: ${this.ContactSensor.ContactSensorState}`);
453
355
  }
454
356
  if (!this.device.contact?.hide_motionsensor) {
455
- if (this.MotionDetected === undefined) {
456
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
357
+ if (this.MotionSensor.MotionDetected === undefined) {
358
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionSensor.MotionDetected}`);
457
359
  }
458
360
  else {
459
- this.accessory.context.MotionDetected = this.MotionDetected;
460
- this.motionService?.updateCharacteristic(this.hap.Characteristic.MotionDetected, this.MotionDetected);
461
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic MotionDetected: ${this.MotionDetected}`);
361
+ this.accessory.context.MotionDetected = this.MotionSensor.MotionDetected;
362
+ this.MotionSensor.Service.updateCharacteristic(this.hap.Characteristic.MotionDetected, this.MotionSensor.MotionDetected);
363
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
364
+ + ` MotionDetected: ${this.MotionSensor.MotionDetected}`);
462
365
  }
463
366
  }
464
367
  if (!this.device.contact?.hide_lightsensor) {
465
- if (this.CurrentAmbientLightLevel === undefined) {
466
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
368
+ if (this.LightSensor?.CurrentAmbientLightLevel === undefined) {
369
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
370
+ + ` CurrentAmbientLightLevel: ${this.LightSensor?.CurrentAmbientLightLevel}`);
467
371
  }
468
372
  else {
469
- this.accessory.context.CurrentAmbientLightLevel = this.CurrentAmbientLightLevel;
470
- this.lightSensorService?.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
471
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}` +
472
- ` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
373
+ this.accessory.context.CurrentAmbientLightLevel = this.LightSensor.CurrentAmbientLightLevel;
374
+ this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, this.LightSensor.CurrentAmbientLightLevel);
375
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
376
+ + ` updateCharacteristic CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`);
473
377
  }
474
378
  }
475
- if (this.BatteryLevel === undefined) {
476
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
477
- }
478
- else {
479
- this.accessory.context.BatteryLevel = this.BatteryLevel;
480
- this.batteryService?.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.BatteryLevel);
481
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
482
- }
483
- if (this.StatusLowBattery === undefined) {
484
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
379
+ if (this.Battery.BatteryLevel === undefined) {
380
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
485
381
  }
486
382
  else {
487
- this.accessory.context.StatusLowBattery = this.StatusLowBattery;
488
- this.batteryService?.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.StatusLowBattery);
489
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
383
+ this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
384
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
385
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.Battery.BatteryLevel}`);
490
386
  }
491
- }
492
- async stopScanning(switchbot) {
493
- switchbot.stopScan();
494
- if (this.BLE_IsConnected) {
495
- await this.BLEparseStatus();
496
- await this.updateHomeKitCharacteristics();
387
+ if (this.Battery.StatusLowBattery === undefined) {
388
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
497
389
  }
498
390
  else {
499
- await this.BLERefreshConnection(switchbot);
500
- }
501
- }
502
- async getCustomBLEAddress(switchbot) {
503
- if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
504
- (async () => {
505
- // Start to monitor advertisement packets
506
- await switchbot.startScan({
507
- model: 'd',
508
- });
509
- // Set an event handler
510
- switchbot.onadvertisement = (ad) => {
511
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
512
- };
513
- await sleep(10000);
514
- // Stop to monitor
515
- switchbot.stopScan();
516
- })();
391
+ this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
392
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
393
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
394
+ + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
517
395
  }
518
396
  }
519
397
  async BLERefreshConnection(switchbot) {
@@ -524,243 +402,30 @@ export class Contact {
524
402
  await this.openAPIRefreshStatus();
525
403
  }
526
404
  }
527
- minLux() {
528
- if (this.device.contact?.set_minLux) {
529
- this.set_minLux = this.device.contact.set_minLux;
530
- }
531
- else {
532
- this.set_minLux = 1;
533
- }
534
- return this.set_minLux;
535
- }
536
- maxLux() {
537
- if (this.device.contact?.set_maxLux) {
538
- this.set_maxLux = this.device.contact.set_maxLux;
539
- }
540
- else {
541
- this.set_maxLux = 6001;
542
- }
543
- return this.set_maxLux;
544
- }
545
- async scan(device) {
546
- if (device.scanDuration) {
547
- this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
548
- if (this.BLE) {
549
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
550
- }
551
- }
552
- else {
553
- this.scanDuration = this.accessory.context.scanDuration = 1;
554
- if (this.BLE) {
555
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
556
- }
557
- }
558
- }
559
- async statusCode(statusCode) {
560
- switch (statusCode) {
561
- case 151:
562
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
563
- break;
564
- case 152:
565
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
566
- break;
567
- case 160:
568
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
569
- break;
570
- case 161:
571
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
572
- this.offlineOff();
573
- break;
574
- case 171:
575
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. ` +
576
- `Hub: ${this.device.hubDeviceId}`);
577
- this.offlineOff();
578
- break;
579
- case 190:
580
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
581
- ` Or command format is invalid, statusCode: ${statusCode}`);
582
- break;
583
- case 100:
584
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
585
- break;
586
- case 200:
587
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
588
- break;
589
- case 400:
590
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Bad Request, The client has issued an invalid request. `
591
- + `This is commonly used to specify validation errors in a request payload, statusCode: ${statusCode}`);
592
- break;
593
- case 401:
594
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unauthorized, Authorization for the API is required, `
595
- + `but the request has not been authenticated, statusCode: ${statusCode}`);
596
- break;
597
- case 403:
598
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Forbidden, The request has been authenticated but does not `
599
- + `have appropriate permissions, or a requested resource is not found, statusCode: ${statusCode}`);
600
- break;
601
- case 404:
602
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Found, Specifies the requested path does not exist, `
603
- + `statusCode: ${statusCode}`);
604
- break;
605
- case 406:
606
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Acceptable, The client has requested a MIME type via `
607
- + `the Accept header for a value not supported by the server, statusCode: ${statusCode}`);
608
- break;
609
- case 415:
610
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unsupported Media Type, The client has defined a contentType `
611
- + `header that is not supported by the server, statusCode: ${statusCode}`);
612
- break;
613
- case 422:
614
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unprocessable Entity, The client has made a valid request, `
615
- + `but the server cannot process it. This is often used for APIs for which certain limits have been exceeded, statusCode: ${statusCode}`);
616
- break;
617
- case 429:
618
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Too Many Requests, The client has exceeded the number of `
619
- + `requests allowed for a given time window, statusCode: ${statusCode}`);
620
- break;
621
- case 500:
622
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Internal Server Error, An unexpected error on the SmartThings `
623
- + `servers has occurred. These errors should be rare, statusCode: ${statusCode}`);
624
- break;
625
- default:
626
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: ` +
627
- `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
628
- }
629
- }
630
405
  async offlineOff() {
631
406
  if (this.device.offline) {
632
- await this.deviceContext();
633
- await this.updateHomeKitCharacteristics();
407
+ this.ContactSensor.Service.updateCharacteristic(this.hap.Characteristic.ContactSensorState, this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED);
408
+ if (!this.device.contact?.hide_motionsensor) {
409
+ this.MotionSensor.Service.updateCharacteristic(this.hap.Characteristic.MotionDetected, false);
410
+ }
411
+ if (!this.device.contact?.hide_lightsensor) {
412
+ this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, 100);
413
+ }
634
414
  }
635
415
  }
636
416
  async apiError(e) {
637
- this.contactSensorservice.updateCharacteristic(this.hap.Characteristic.ContactSensorState, e);
417
+ this.ContactSensor.Service.updateCharacteristic(this.hap.Characteristic.ContactSensorState, e);
418
+ this.ContactSensor.Service.updateCharacteristic(this.hap.Characteristic.StatusActive, e);
638
419
  if (!this.device.contact?.hide_motionsensor) {
639
- this.motionService?.updateCharacteristic(this.hap.Characteristic.MotionDetected, e);
420
+ this.MotionSensor.Service.updateCharacteristic(this.hap.Characteristic.MotionDetected, e);
421
+ this.MotionSensor.Service.updateCharacteristic(this.hap.Characteristic.StatusActive, e);
640
422
  }
641
423
  if (!this.device.contact?.hide_lightsensor) {
642
- this.lightSensorService?.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e);
424
+ this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e);
425
+ this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.StatusActive, e);
643
426
  }
644
- this.batteryService?.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
645
- this.batteryService?.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
646
- }
647
- async deviceContext() {
648
- if (this.MotionDetected === undefined) {
649
- this.MotionDetected = false;
650
- }
651
- else {
652
- this.MotionDetected = this.accessory.context.MotionDetected;
653
- }
654
- if (this.ContactSensorState === undefined) {
655
- this.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED;
656
- }
657
- else {
658
- this.ContactSensorState = this.accessory.context.ContactSensorState;
659
- }
660
- if (this.FirmwareRevision === undefined) {
661
- this.FirmwareRevision = this.platform.version;
662
- this.accessory.context.FirmwareRevision = this.FirmwareRevision;
663
- }
664
- }
665
- async refreshRate(device) {
666
- if (device.refreshRate) {
667
- this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
668
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
669
- }
670
- else if (this.platform.config.options.refreshRate) {
671
- this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options.refreshRate;
672
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
673
- }
674
- }
675
- async deviceConfig(device) {
676
- let config = {};
677
- if (device.contact) {
678
- config = device.contact;
679
- }
680
- if (device.connectionType !== undefined) {
681
- config['connectionType'] = device.connectionType;
682
- }
683
- if (device.external !== undefined) {
684
- config['external'] = device.external;
685
- }
686
- if (device.logging !== undefined) {
687
- config['logging'] = device.logging;
688
- }
689
- if (device.refreshRate !== undefined) {
690
- config['refreshRate'] = device.refreshRate;
691
- }
692
- if (device.scanDuration !== undefined) {
693
- config['scanDuration'] = device.scanDuration;
694
- }
695
- if (device.webhook !== undefined) {
696
- config['webhook'] = device.webhook;
697
- }
698
- if (Object.entries(config).length !== 0) {
699
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
700
- }
701
- }
702
- async deviceLogs(device) {
703
- if (this.platform.debugMode) {
704
- this.deviceLogging = this.accessory.context.logging = 'debugMode';
705
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
706
- }
707
- else if (device.logging) {
708
- this.deviceLogging = this.accessory.context.logging = device.logging;
709
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
710
- }
711
- else if (this.platform.config.options?.logging) {
712
- this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
713
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
714
- }
715
- else {
716
- this.deviceLogging = this.accessory.context.logging = 'standard';
717
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
718
- }
719
- }
720
- /**
721
- * Logging for Device
722
- */
723
- infoLog(...log) {
724
- if (this.enablingDeviceLogging()) {
725
- this.platform.log.info(String(...log));
726
- }
727
- }
728
- warnLog(...log) {
729
- if (this.enablingDeviceLogging()) {
730
- this.platform.log.warn(String(...log));
731
- }
732
- }
733
- debugWarnLog(...log) {
734
- if (this.enablingDeviceLogging()) {
735
- if (this.deviceLogging?.includes('debug')) {
736
- this.platform.log.warn('[DEBUG]', String(...log));
737
- }
738
- }
739
- }
740
- errorLog(...log) {
741
- if (this.enablingDeviceLogging()) {
742
- this.platform.log.error(String(...log));
743
- }
744
- }
745
- debugErrorLog(...log) {
746
- if (this.enablingDeviceLogging()) {
747
- if (this.deviceLogging?.includes('debug')) {
748
- this.platform.log.error('[DEBUG]', String(...log));
749
- }
750
- }
751
- }
752
- debugLog(...log) {
753
- if (this.enablingDeviceLogging()) {
754
- if (this.deviceLogging === 'debug') {
755
- this.platform.log.info('[DEBUG]', String(...log));
756
- }
757
- else {
758
- this.platform.log.debug(String(...log));
759
- }
760
- }
761
- }
762
- enablingDeviceLogging() {
763
- return this.deviceLogging.includes('debug') || this.deviceLogging === 'standard';
427
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
428
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
764
429
  }
765
430
  }
766
431
  //# sourceMappingURL=contact.js.map