@switchbot/homebridge-switchbot 2.0.0-beta.2 → 2.0.0-beta.21

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 (113) hide show
  1. package/CHANGELOG.md +8 -1
  2. package/README.md +1 -2
  3. package/config.schema.json +75 -20
  4. package/dist/device/bot.d.ts +32 -28
  5. package/dist/device/bot.d.ts.map +1 -1
  6. package/dist/device/bot.js +646 -648
  7. package/dist/device/bot.js.map +1 -1
  8. package/dist/device/colorbulb.d.ts +34 -19
  9. package/dist/device/colorbulb.d.ts.map +1 -1
  10. package/dist/device/colorbulb.js +429 -304
  11. package/dist/device/colorbulb.js.map +1 -1
  12. package/dist/device/contact.d.ts +16 -7
  13. package/dist/device/contact.d.ts.map +1 -1
  14. package/dist/device/contact.js +288 -230
  15. package/dist/device/contact.js.map +1 -1
  16. package/dist/device/curtain.d.ts +21 -16
  17. package/dist/device/curtain.d.ts.map +1 -1
  18. package/dist/device/curtain.js +519 -489
  19. package/dist/device/curtain.js.map +1 -1
  20. package/dist/device/humidifier.d.ts +22 -18
  21. package/dist/device/humidifier.d.ts.map +1 -1
  22. package/dist/device/humidifier.js +415 -360
  23. package/dist/device/humidifier.js.map +1 -1
  24. package/dist/device/lock.d.ts +22 -8
  25. package/dist/device/lock.d.ts.map +1 -1
  26. package/dist/device/lock.js +253 -147
  27. package/dist/device/lock.js.map +1 -1
  28. package/dist/device/meter.d.ts +21 -16
  29. package/dist/device/meter.d.ts.map +1 -1
  30. package/dist/device/meter.js +325 -255
  31. package/dist/device/meter.js.map +1 -1
  32. package/dist/device/meterplus.d.ts +23 -12
  33. package/dist/device/meterplus.d.ts.map +1 -1
  34. package/dist/device/meterplus.js +346 -208
  35. package/dist/device/meterplus.js.map +1 -1
  36. package/dist/device/motion.d.ts +17 -8
  37. package/dist/device/motion.d.ts.map +1 -1
  38. package/dist/device/motion.js +261 -209
  39. package/dist/device/motion.js.map +1 -1
  40. package/dist/device/plug.d.ts +24 -16
  41. package/dist/device/plug.d.ts.map +1 -1
  42. package/dist/device/plug.js +267 -242
  43. package/dist/device/plug.js.map +1 -1
  44. package/dist/device/striplight.d.ts +51 -16
  45. package/dist/device/striplight.d.ts.map +1 -1
  46. package/dist/device/striplight.js +527 -185
  47. package/dist/device/striplight.js.map +1 -1
  48. package/dist/irdevice/airconditioner.d.ts +7 -12
  49. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  50. package/dist/irdevice/airconditioner.js +261 -230
  51. package/dist/irdevice/airconditioner.js.map +1 -1
  52. package/dist/irdevice/airpurifier.d.ts +3 -3
  53. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  54. package/dist/irdevice/airpurifier.js +137 -104
  55. package/dist/irdevice/airpurifier.js.map +1 -1
  56. package/dist/irdevice/camera.d.ts +9 -8
  57. package/dist/irdevice/camera.d.ts.map +1 -1
  58. package/dist/irdevice/camera.js +116 -86
  59. package/dist/irdevice/camera.js.map +1 -1
  60. package/dist/irdevice/fan.d.ts +8 -7
  61. package/dist/irdevice/fan.d.ts.map +1 -1
  62. package/dist/irdevice/fan.js +143 -109
  63. package/dist/irdevice/fan.js.map +1 -1
  64. package/dist/irdevice/light.d.ts +9 -8
  65. package/dist/irdevice/light.d.ts.map +1 -1
  66. package/dist/irdevice/light.js +120 -103
  67. package/dist/irdevice/light.js.map +1 -1
  68. package/dist/irdevice/other.d.ts +9 -8
  69. package/dist/irdevice/other.d.ts.map +1 -1
  70. package/dist/irdevice/other.js +128 -98
  71. package/dist/irdevice/other.js.map +1 -1
  72. package/dist/irdevice/tv.d.ts +10 -9
  73. package/dist/irdevice/tv.d.ts.map +1 -1
  74. package/dist/irdevice/tv.js +126 -93
  75. package/dist/irdevice/tv.js.map +1 -1
  76. package/dist/irdevice/vacuumcleaner.d.ts +7 -10
  77. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  78. package/dist/irdevice/vacuumcleaner.js +115 -89
  79. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  80. package/dist/irdevice/waterheater.d.ts +6 -9
  81. package/dist/irdevice/waterheater.d.ts.map +1 -1
  82. package/dist/irdevice/waterheater.js +115 -89
  83. package/dist/irdevice/waterheater.js.map +1 -1
  84. package/dist/platform.d.ts +5 -5
  85. package/dist/platform.d.ts.map +1 -1
  86. package/dist/platform.js +227 -199
  87. package/dist/platform.js.map +1 -1
  88. package/dist/settings.d.ts +15 -11
  89. package/dist/settings.d.ts.map +1 -1
  90. package/dist/settings.js.map +1 -1
  91. package/package.json +12 -10
  92. package/src/device/bot.ts +641 -657
  93. package/src/device/colorbulb.ts +440 -339
  94. package/src/device/contact.ts +289 -233
  95. package/src/device/curtain.ts +523 -503
  96. package/src/device/humidifier.ts +421 -396
  97. package/src/device/lock.ts +257 -147
  98. package/src/device/meter.ts +335 -268
  99. package/src/device/meterplus.ts +354 -213
  100. package/src/device/motion.ts +264 -213
  101. package/src/device/plug.ts +270 -251
  102. package/src/device/striplight.ts +552 -207
  103. package/src/irdevice/airconditioner.ts +263 -241
  104. package/src/irdevice/airpurifier.ts +132 -103
  105. package/src/irdevice/camera.ts +112 -85
  106. package/src/irdevice/fan.ts +138 -106
  107. package/src/irdevice/light.ts +116 -103
  108. package/src/irdevice/other.ts +124 -97
  109. package/src/irdevice/tv.ts +123 -93
  110. package/src/irdevice/vacuumcleaner.ts +112 -89
  111. package/src/irdevice/waterheater.ts +111 -89
  112. package/src/platform.ts +216 -214
  113. package/src/settings.ts +15 -11
@@ -8,6 +8,7 @@ const https_1 = __importDefault(require("https"));
8
8
  const crypto_1 = __importDefault(require("crypto"));
9
9
  const rxjs_1 = require("rxjs");
10
10
  const operators_1 = require("rxjs/operators");
11
+ const super_stringify_1 = __importDefault(require("super-stringify"));
11
12
  const settings_1 = require("../settings");
12
13
  /**
13
14
  * Platform Accessory
@@ -19,12 +20,15 @@ class Motion {
19
20
  this.platform = platform;
20
21
  this.accessory = accessory;
21
22
  this.device = device;
23
+ // Connection
24
+ this.BLE = (this.device.connectionType === 'BLE' || this.device.connectionType === 'Both');
25
+ this.OpenAPI = (this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'Both');
22
26
  // default placeholders
23
27
  this.logs(device);
24
28
  this.scan(device);
25
29
  this.refreshRate(device);
26
30
  this.config(device);
27
- this.MotionDetected = false;
31
+ this.context();
28
32
  // this is subject we use to track when we need to POST changes to the SwitchBot API
29
33
  this.doMotionUpdate = new rxjs_1.Subject();
30
34
  this.motionUbpdateInProgress = false;
@@ -53,34 +57,34 @@ class Motion {
53
57
  // see https://developers.homebridge.io/#/service/MotionSensor
54
58
  // Light Sensor Service
55
59
  if (device.motion?.hide_lightsensor) {
56
- this.debugLog(`Motion Sensor: ${accessory.displayName} Removing Light Sensor Service`);
60
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Light Sensor Service`);
57
61
  this.lightSensorService = this.accessory.getService(this.platform.Service.LightSensor);
58
62
  accessory.removeService(this.lightSensorService);
59
63
  }
60
64
  else if (!this.lightSensorService) {
61
- this.debugLog(`Motion Sensor: ${accessory.displayName} Add Light Sensor Service`);
65
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Light Sensor Service`);
62
66
  (this.lightSensorService =
63
67
  this.accessory.getService(this.platform.Service.LightSensor) || this.accessory.addService(this.platform.Service.LightSensor)),
64
68
  `${accessory.displayName} Light Sensor`;
65
69
  this.lightSensorService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Light Sensor`);
66
70
  }
67
71
  else {
68
- this.debugLog(`Motion Sensor: ${accessory.displayName} Light Sensor Service Not Added`);
72
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Light Sensor Service Not Added`);
69
73
  }
70
74
  // Battery Service
71
- if (!device.ble) {
72
- this.debugLog(`Motion Sensor: ${accessory.displayName} Removing Battery Service`);
75
+ if (!this.BLE) {
76
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Battery Service`);
73
77
  this.batteryService = this.accessory.getService(this.platform.Service.Battery);
74
78
  accessory.removeService(this.batteryService);
75
79
  }
76
- else if (device.ble && !this.batteryService) {
77
- this.debugLog(`Motion Sensor: ${accessory.displayName} Add Battery Service`);
80
+ else if (this.BLE && !this.batteryService) {
81
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Battery Service`);
78
82
  (this.batteryService = this.accessory.getService(this.platform.Service.Battery) || this.accessory.addService(this.platform.Service.Battery)),
79
83
  `${accessory.displayName} Battery`;
80
84
  this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
81
85
  }
82
86
  else {
83
- this.debugLog(`Motion Sensor: ${accessory.displayName} Battery Service Not Added`);
87
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Battery Service Not Added`);
84
88
  }
85
89
  // Retrieve initial values and updateHomekit
86
90
  this.updateHomeKitCharacteristics();
@@ -95,18 +99,23 @@ class Motion {
95
99
  * Parse the device status from the SwitchBot api
96
100
  */
97
101
  async parseStatus() {
98
- if (this.SwitchToOpenAPI || !this.device.ble) {
102
+ if (this.BLE && !this.SwitchToOpenAPI) {
103
+ await this.BLEparseStatus();
104
+ }
105
+ else if (this.OpenAPI && this.platform.config.credentials?.token) {
106
+ this.SwitchToOpenAPI = false;
99
107
  await this.openAPIparseStatus();
100
108
  }
101
109
  else {
102
- await this.BLEparseStatus();
110
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
111
+ + ` ${this.device.connectionType}, parseStatus will not happen.`);
103
112
  }
104
113
  }
105
114
  async BLEparseStatus() {
106
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} BLE parseStatus`);
115
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
107
116
  // Movement
108
117
  this.MotionDetected = this.movement;
109
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
118
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
110
119
  // Light Level
111
120
  if (!this.device.motion?.hide_lightsensor) {
112
121
  this.set_minLux = this.minLux();
@@ -119,7 +128,7 @@ class Motion {
119
128
  default:
120
129
  this.CurrentAmbientLightLevel = this.set_maxLux;
121
130
  }
122
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} LightLevel: ${this.lightLevel},` +
131
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel},` +
123
132
  ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
124
133
  }
125
134
  // Battery
@@ -133,46 +142,46 @@ class Motion {
133
142
  else {
134
143
  this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
135
144
  }
136
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
145
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
146
+ + ` StatusLowBattery: ${this.StatusLowBattery}`);
137
147
  }
138
148
  async openAPIparseStatus() {
139
- if (this.device.ble) {
140
- this.SwitchToOpenAPI = false;
141
- }
142
- if (this.platform.config.credentials?.token) {
143
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} OpenAPI parseStatus`);
144
- // Motion State
145
- this.MotionDetected = this.moveDetected;
146
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
147
- // Light Level
148
- if (!this.device.motion?.hide_lightsensor) {
149
- this.set_minLux = this.minLux();
150
- this.set_maxLux = this.maxLux();
151
- switch (this.brightness) {
152
- case 'dim':
153
- this.CurrentAmbientLightLevel = this.set_minLux;
154
- break;
155
- case 'bright':
156
- default:
157
- this.CurrentAmbientLightLevel = this.set_maxLux;
158
- }
159
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
149
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
150
+ // Motion State
151
+ this.MotionDetected = this.moveDetected;
152
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
153
+ // Light Level
154
+ if (!this.device.motion?.hide_lightsensor) {
155
+ this.set_minLux = this.minLux();
156
+ this.set_maxLux = this.maxLux();
157
+ switch (this.brightness) {
158
+ case 'dim':
159
+ this.CurrentAmbientLightLevel = this.set_minLux;
160
+ break;
161
+ case 'bright':
162
+ default:
163
+ this.CurrentAmbientLightLevel = this.set_maxLux;
160
164
  }
165
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
161
166
  }
162
167
  }
163
168
  /**
164
169
  * Asks the SwitchBot API for the latest device information
165
170
  */
166
171
  async refreshStatus() {
167
- if (this.device.ble) {
172
+ if (this.BLE) {
168
173
  await this.BLERefreshStatus();
169
174
  }
170
- else {
175
+ else if (this.OpenAPI && this.platform.config.credentials?.token) {
171
176
  await this.openAPIRefreshStatus();
172
177
  }
178
+ else {
179
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
180
+ + ` ${this.device.connectionType}, refreshStatus will not happen.`);
181
+ }
173
182
  }
174
183
  async BLERefreshStatus() {
175
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} BLE RefreshStatus`);
184
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
176
185
  const switchbot = await this.platform.connectBLE();
177
186
  // Convert to BLE Address
178
187
  this.device.bleMac =
@@ -181,7 +190,7 @@ class Motion {
181
190
  .deviceId.match(/.{1,2}/g)
182
191
  .join(':')
183
192
  .toLowerCase();
184
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
193
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
185
194
  this.getCustomBLEAddress(switchbot);
186
195
  // Start to monitor advertisement packets
187
196
  if (switchbot !== false) {
@@ -197,23 +206,23 @@ class Motion {
197
206
  if (this.deviceLogging.includes('debug')) {
198
207
  this.infoLog(this.address);
199
208
  this.infoLog(this.device.bleMac);
200
- this.infoLog(`Motion Sensor: ${this.accessory.displayName} BLE Address Found: ${this.address}`);
201
- this.infoLog(`Motion Sensor: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac}`);
209
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address Found: ${this.address}`);
210
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac}`);
202
211
  }
203
212
  this.serviceData = ad.serviceData;
204
213
  this.movement = ad.serviceData.movement;
205
214
  this.battery = ad.serviceData.battery;
206
215
  this.lightLevel = ad.serviceData.lightLevel;
207
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
208
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} movement: ${ad.serviceData.movement}, lightLevel: ` +
216
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${(0, super_stringify_1.default)(ad.serviceData)}`);
217
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} movement: ${ad.serviceData.movement}, lightLevel: ` +
209
218
  `${ad.serviceData.lightLevel}, battery: ${ad.serviceData.battery}`);
210
219
  if (this.serviceData) {
211
220
  this.connected = true;
212
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} connected: ${this.connected}`);
221
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
213
222
  }
214
223
  else {
215
224
  this.connected = false;
216
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} connected: ${this.connected}`);
225
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
217
226
  }
218
227
  };
219
228
  // Wait 10 seconds
@@ -231,105 +240,69 @@ class Motion {
231
240
  }
232
241
  })
233
242
  .catch(async (e) => {
234
- this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
235
- if (this.deviceLogging.includes('debug')) {
236
- this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` +
237
- ` Error Message: ${JSON.stringify(e.message)}`);
238
- }
239
- if (this.platform.config.credentials?.token) {
240
- this.warnLog(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
241
- this.SwitchToOpenAPI = true;
242
- await this.openAPIRefreshStatus();
243
- }
244
243
  this.apiError(e);
244
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
245
+ + ` Connection, Error Message: ${(0, super_stringify_1.default)(e.message)}`);
246
+ await this.BLEconnection(switchbot);
245
247
  });
246
248
  }
247
249
  else {
248
250
  await this.BLEconnection(switchbot);
249
251
  }
250
252
  }
251
- async getCustomBLEAddress(switchbot) {
252
- if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
253
- (async () => {
254
- // Start to monitor advertisement packets
255
- await switchbot.startScan({
256
- model: 's',
257
- });
258
- // Set an event handler
259
- switchbot.onadvertisement = (ad) => {
260
- this.warnLog(`Motion Sensor: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
261
- };
262
- await switchbot.wait(10000);
263
- // Stop to monitor
264
- switchbot.stopScan();
265
- })();
266
- }
267
- }
268
- async BLEconnection(switchbot) {
269
- this.errorLog(`Motion Sensor: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
270
- if (this.platform.config.credentials?.token) {
271
- this.warnLog(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
272
- this.SwitchToOpenAPI = true;
273
- await this.openAPIRefreshStatus();
274
- }
275
- }
276
253
  async openAPIRefreshStatus() {
277
- if (this.platform.config.credentials?.token) {
278
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} OpenAPI RefreshStatus`);
279
- try {
280
- const t = Date.now();
281
- const nonce = 'requestID';
282
- const data = this.platform.config.credentials?.token + t + nonce;
283
- const signTerm = crypto_1.default.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
284
- const sign = signTerm.toString('base64');
285
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} sign: ${sign}`);
286
- const options = {
287
- hostname: settings_1.HostDomain,
288
- port: 443,
289
- path: `${settings_1.DevicePath}/${this.device.deviceId}/status`,
290
- method: 'GET',
291
- headers: {
292
- Authorization: this.platform.config.credentials?.token,
293
- sign: sign,
294
- nonce: nonce,
295
- t: t,
296
- 'Content-Type': 'application/json',
297
- },
298
- };
299
- const req = https_1.default.request(options, (res) => {
300
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
301
- let rawData = '';
302
- res.on('data', (d) => {
303
- rawData += d;
304
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} d: ${d}`);
305
- });
306
- res.on('end', () => {
307
- try {
308
- this.deviceStatus = JSON.parse(rawData);
309
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
310
- this.moveDetected = this.deviceStatus.body.moveDetected;
311
- this.brightness = this.deviceStatus.body.brightness;
312
- this.parseStatus();
313
- this.updateHomeKitCharacteristics();
314
- }
315
- catch (e) {
316
- this.errorLog(`Motion Sensor: ${this.accessory.displayName} error message: ${e.message}`);
317
- }
318
- });
254
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
255
+ try {
256
+ const t = Date.now();
257
+ const nonce = 'requestID';
258
+ const data = this.platform.config.credentials?.token + t + nonce;
259
+ const signTerm = crypto_1.default.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
260
+ const sign = signTerm.toString('base64');
261
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
262
+ const options = {
263
+ hostname: settings_1.HostDomain,
264
+ port: 443,
265
+ path: `${settings_1.DevicePath}/${this.device.deviceId}/status`,
266
+ method: 'GET',
267
+ headers: {
268
+ Authorization: this.platform.config.credentials?.token,
269
+ sign: sign,
270
+ nonce: nonce,
271
+ t: t,
272
+ 'Content-Type': 'application/json',
273
+ },
274
+ };
275
+ const req = https_1.default.request(options, (res) => {
276
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
277
+ this.statusCode({ res });
278
+ let rawData = '';
279
+ res.on('data', (d) => {
280
+ rawData += d;
281
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
319
282
  });
320
- req.on('error', (e) => {
321
- this.errorLog(`Motion Sensor: ${this.accessory.displayName} error message: ${e.message}`);
283
+ res.on('end', () => {
284
+ try {
285
+ this.deviceStatus = JSON.parse(rawData);
286
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${(0, super_stringify_1.default)(this.deviceStatus)}`);
287
+ this.moveDetected = this.deviceStatus.body.moveDetected;
288
+ this.brightness = this.deviceStatus.body.brightness;
289
+ this.parseStatus();
290
+ this.updateHomeKitCharacteristics();
291
+ }
292
+ catch (e) {
293
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
294
+ }
322
295
  });
323
- req.end();
324
- }
325
- catch (e) {
326
- this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
327
- if (this.deviceLogging.includes('debug')) {
328
- this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,` +
329
- ` Error Message: ${JSON.stringify(e.message)}`);
330
- }
331
- this.apiError(e);
332
- }
296
+ });
297
+ req.on('error', (e) => {
298
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
299
+ });
300
+ req.end();
301
+ }
302
+ catch (e) {
303
+ this.apiError(e);
304
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
305
+ + ` Connection, Error Message: ${(0, super_stringify_1.default)(e.message)}`);
333
306
  }
334
307
  }
335
308
  /**
@@ -337,116 +310,153 @@ class Motion {
337
310
  */
338
311
  async updateHomeKitCharacteristics() {
339
312
  if (this.MotionDetected === undefined) {
340
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
313
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
341
314
  }
342
315
  else {
316
+ this.accessory.context.MotionDetected = this.MotionDetected;
343
317
  this.motionSensorService.updateCharacteristic(this.platform.Characteristic.MotionDetected, this.MotionDetected);
344
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} updateCharacteristic MotionDetected: ${this.MotionDetected}`);
318
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic MotionDetected: ${this.MotionDetected}`);
345
319
  }
346
- if (this.device.ble) {
320
+ if (this.BLE) {
347
321
  if (this.BatteryLevel === undefined) {
348
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
322
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
349
323
  }
350
324
  else {
325
+ this.accessory.context.BatteryLevel = this.BatteryLevel;
351
326
  this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
352
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
327
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
353
328
  }
354
329
  if (this.StatusLowBattery === undefined) {
355
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
330
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
356
331
  }
357
332
  else {
333
+ this.accessory.context.StatusLowBattery = this.StatusLowBattery;
358
334
  this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
359
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
335
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
360
336
  }
361
337
  if (this.CurrentAmbientLightLevel === undefined) {
362
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
338
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
363
339
  }
364
340
  else {
341
+ this.accessory.context.CurrentAmbientLightLevel = this.CurrentAmbientLightLevel;
365
342
  this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
366
- this.debugLog(`Motion Sensor: ${this.accessory.displayName}` + ` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
343
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
344
+ + ` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
367
345
  }
368
346
  }
369
347
  }
370
- async apiError(e) {
371
- this.motionSensorService.updateCharacteristic(this.platform.Characteristic.MotionDetected, e);
372
- if (this.device.ble) {
373
- this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
374
- this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
375
- this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, e);
348
+ async getCustomBLEAddress(switchbot) {
349
+ if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
350
+ (async () => {
351
+ // Start to monitor advertisement packets
352
+ await switchbot.startScan({
353
+ model: 's',
354
+ });
355
+ // Set an event handler
356
+ switchbot.onadvertisement = (ad) => {
357
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${(0, super_stringify_1.default)(ad, null, ' ')}`);
358
+ };
359
+ await switchbot.wait(10000);
360
+ // Stop to monitor
361
+ switchbot.stopScan();
362
+ })();
376
363
  }
377
- //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
378
364
  }
379
- async config(device) {
380
- let config = {};
381
- if (device.motion) {
382
- config = device.motion;
383
- }
384
- if (device.ble !== undefined) {
385
- config['ble'] = device.ble;
386
- }
387
- if (device.logging !== undefined) {
388
- config['logging'] = device.logging;
389
- }
390
- if (device.refreshRate !== undefined) {
391
- config['refreshRate'] = device.refreshRate;
392
- }
393
- if (device.scanDuration !== undefined) {
394
- config['scanDuration'] = device.scanDuration;
365
+ async BLEconnection(switchbot) {
366
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
367
+ if (this.platform.config.credentials?.token && this.device.connectionType !== 'Both') {
368
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection`);
369
+ this.SwitchToOpenAPI = true;
370
+ await this.openAPIRefreshStatus();
395
371
  }
396
- if (device.offline !== undefined) {
397
- config['offline'] = device.offline;
372
+ }
373
+ minLux() {
374
+ if (this.device.motion?.set_minLux) {
375
+ this.set_minLux = this.device.motion.set_minLux;
398
376
  }
399
- if (Object.entries(config).length !== 0) {
400
- this.infoLog(`Motion Sensor: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
377
+ else {
378
+ this.set_minLux = 1;
401
379
  }
380
+ return this.set_minLux;
402
381
  }
403
- async refreshRate(device) {
404
- if (device.refreshRate) {
405
- this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
406
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
382
+ maxLux() {
383
+ if (this.device.motion?.set_maxLux) {
384
+ this.set_maxLux = this.device.motion.set_maxLux;
407
385
  }
408
- else if (this.platform.config.options.refreshRate) {
409
- this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options.refreshRate;
410
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
386
+ else {
387
+ this.set_maxLux = 6001;
411
388
  }
389
+ return this.set_maxLux;
412
390
  }
413
391
  async scan(device) {
414
392
  if (device.scanDuration) {
415
393
  this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
416
- if (device.ble) {
417
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
394
+ if (this.BLE) {
395
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
418
396
  }
419
397
  }
420
398
  else {
421
399
  this.scanDuration = this.accessory.context.scanDuration = 1;
422
- if (this.device.ble) {
423
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
400
+ if (this.BLE) {
401
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
424
402
  }
425
403
  }
426
404
  }
427
- async logs(device) {
428
- if (this.platform.debugMode) {
429
- this.deviceLogging = this.accessory.context.logging = 'debugMode';
430
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
431
- }
432
- else if (device.logging) {
433
- this.deviceLogging = this.accessory.context.logging = device.logging;
434
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
405
+ async statusCode({ res }) {
406
+ switch (res.statusCode) {
407
+ case 151:
408
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this device type.`);
409
+ break;
410
+ case 152:
411
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found.`);
412
+ break;
413
+ case 160:
414
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported.`);
415
+ break;
416
+ case 161:
417
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline.`);
418
+ this.offlineOff();
419
+ break;
420
+ case 171:
421
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} is offline. Hub: ${this.device.hubDeviceId}`);
422
+ this.offlineOff();
423
+ break;
424
+ case 190:
425
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
426
+ ` Or command: ${(0, super_stringify_1.default)(res)} format is invalid`);
427
+ break;
428
+ case 100:
429
+ if (this.platform.debugMode) {
430
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent.`);
431
+ }
432
+ break;
433
+ default:
434
+ if (this.platform.debugMode) {
435
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode.`);
436
+ }
435
437
  }
436
- else if (this.platform.config.options?.logging) {
437
- this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
438
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
438
+ }
439
+ async offlineOff() {
440
+ if (this.device.offline) {
441
+ this.MotionDetected = false;
442
+ this.motionSensorService.getCharacteristic(this.platform.Characteristic.MotionDetected).updateValue(this.MotionDetected);
443
+ await this.updateHomeKitCharacteristics();
439
444
  }
440
- else {
441
- this.deviceLogging = this.accessory.context.logging = 'standard';
442
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
445
+ }
446
+ async apiError(e) {
447
+ this.motionSensorService.updateCharacteristic(this.platform.Characteristic.MotionDetected, e);
448
+ if (this.BLE) {
449
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
450
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
451
+ this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, e);
443
452
  }
444
453
  }
445
454
  FirmwareRevision(accessory, device) {
446
455
  let FirmwareRevision;
447
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
448
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
449
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
456
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
457
+ + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
458
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
459
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
450
460
  if (accessory.context.FirmwareRevision) {
451
461
  FirmwareRevision = accessory.context.FirmwareRevision;
452
462
  }
@@ -458,23 +468,65 @@ class Motion {
458
468
  }
459
469
  return FirmwareRevision;
460
470
  }
461
- minLux() {
462
- if (this.device.motion?.set_minLux) {
463
- this.set_minLux = this.device.motion.set_minLux;
471
+ async context() {
472
+ if (this.MotionDetected === undefined) {
473
+ this.MotionDetected = false;
464
474
  }
465
475
  else {
466
- this.set_minLux = 1;
476
+ this.MotionDetected = this.accessory.context.MotionDetected;
467
477
  }
468
- return this.set_minLux;
469
478
  }
470
- maxLux() {
471
- if (this.device.motion?.set_maxLux) {
472
- this.set_maxLux = this.device.motion.set_maxLux;
479
+ async refreshRate(device) {
480
+ if (device.refreshRate) {
481
+ this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
482
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
483
+ }
484
+ else if (this.platform.config.options.refreshRate) {
485
+ this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options.refreshRate;
486
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
487
+ }
488
+ }
489
+ async config(device) {
490
+ let config = {};
491
+ if (device.motion) {
492
+ config = device.motion;
493
+ }
494
+ if (device.connectionType !== undefined) {
495
+ config['connectionType'] = device.connectionType;
496
+ }
497
+ if (device.logging !== undefined) {
498
+ config['logging'] = device.logging;
499
+ }
500
+ if (device.refreshRate !== undefined) {
501
+ config['refreshRate'] = device.refreshRate;
502
+ }
503
+ if (device.scanDuration !== undefined) {
504
+ config['scanDuration'] = device.scanDuration;
505
+ }
506
+ if (device.offline !== undefined) {
507
+ config['offline'] = device.offline;
508
+ }
509
+ if (Object.entries(config).length !== 0) {
510
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${(0, super_stringify_1.default)(config)}`);
511
+ }
512
+ }
513
+ async logs(device) {
514
+ if (this.platform.debugMode) {
515
+ this.deviceLogging = this.accessory.context.logging = 'debugMode';
516
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
517
+ }
518
+ else if (device.logging) {
519
+ this.deviceLogging = this.accessory.context.logging = device.logging;
520
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
521
+ }
522
+ else if (this.platform.config.options?.logging) {
523
+ this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
524
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
473
525
  }
474
526
  else {
475
- this.set_maxLux = 6001;
527
+ this.deviceLogging = this.accessory.context.logging = 'standard';
528
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
476
529
  }
477
- return this.set_maxLux;
478
530
  }
479
531
  /**
480
532
  * Logging for Device