@switchbot/homebridge-switchbot 3.8.3-beta.3 → 3.8.3-beta.30
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.
- package/.github/workflows/beta-release.yml +7 -4
- package/.github/workflows/release.yml +7 -6
- package/dist/device/blindtilt.d.ts +1 -4
- package/dist/device/blindtilt.d.ts.map +1 -1
- package/dist/device/blindtilt.js +18 -19
- package/dist/device/blindtilt.js.map +1 -1
- package/dist/device/bot.d.ts +1 -4
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +15 -16
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +1 -4
- package/dist/device/ceilinglight.d.ts.map +1 -1
- package/dist/device/ceilinglight.js +35 -39
- package/dist/device/ceilinglight.js.map +1 -1
- package/dist/device/colorbulb.d.ts +1 -4
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +35 -39
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +1 -4
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +7 -7
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +1 -4
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +16 -17
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/device.d.ts +6 -6
- package/dist/device/device.d.ts.map +1 -1
- package/dist/device/device.js +30 -14
- package/dist/device/device.js.map +1 -1
- package/dist/device/fan.d.ts +1 -4
- package/dist/device/fan.d.ts.map +1 -1
- package/dist/device/fan.js +32 -34
- package/dist/device/fan.js.map +1 -1
- package/dist/device/hub.d.ts +1 -4
- package/dist/device/hub.d.ts.map +1 -1
- package/dist/device/hub.js +7 -7
- package/dist/device/hub.js.map +1 -1
- package/dist/device/humidifier.d.ts +1 -4
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +28 -31
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/iosensor.d.ts +1 -4
- package/dist/device/iosensor.d.ts.map +1 -1
- package/dist/device/iosensor.js +7 -7
- package/dist/device/iosensor.js.map +1 -1
- package/dist/device/lightstrip.d.ts +1 -4
- package/dist/device/lightstrip.d.ts.map +1 -1
- package/dist/device/lightstrip.js +28 -31
- package/dist/device/lightstrip.js.map +1 -1
- package/dist/device/lock.d.ts +1 -4
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +15 -16
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +1 -4
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +7 -7
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +1 -4
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +7 -7
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +1 -4
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +7 -7
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +1 -4
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +14 -15
- package/dist/device/plug.js.map +1 -1
- package/dist/device/robotvacuumcleaner.d.ts +1 -4
- package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
- package/dist/device/robotvacuumcleaner.js +21 -23
- package/dist/device/robotvacuumcleaner.js.map +1 -1
- package/dist/device/waterdetector.d.ts +1 -4
- package/dist/device/waterdetector.d.ts.map +1 -1
- package/dist/device/waterdetector.js +7 -7
- package/dist/device/waterdetector.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts +1 -1
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +11 -12
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +1 -1
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +11 -12
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +1 -1
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +9 -10
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +1 -1
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +15 -16
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/irdevice.d.ts +6 -6
- package/dist/irdevice/irdevice.d.ts.map +1 -1
- package/dist/irdevice/irdevice.js +7 -13
- package/dist/irdevice/irdevice.js.map +1 -1
- package/dist/irdevice/light.d.ts +1 -1
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +9 -10
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +1 -1
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +9 -10
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +1 -1
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +27 -28
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +9 -10
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +1 -1
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +9 -10
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts +6 -14
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +105 -170
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +1 -3
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js.map +1 -1
- package/docs/assets/highlight.css +42 -0
- package/docs/assets/main.js +1 -1
- package/docs/functions/default.html +1 -1
- package/docs/index.html +61 -50
- package/docs/media/security-privacy-bluetooth.png +0 -0
- package/package.json +13 -14
- package/src/device/blindtilt.ts +20 -24
- package/src/device/bot.ts +16 -20
- package/src/device/ceilinglight.ts +36 -43
- package/src/device/colorbulb.ts +36 -43
- package/src/device/contact.ts +8 -11
- package/src/device/curtain.ts +18 -22
- package/src/device/device.ts +29 -18
- package/src/device/fan.ts +33 -38
- package/src/device/hub.ts +8 -11
- package/src/device/humidifier.ts +29 -35
- package/src/device/iosensor.ts +8 -11
- package/src/device/lightstrip.ts +29 -35
- package/src/device/lock.ts +16 -20
- package/src/device/meter.ts +8 -11
- package/src/device/meterplus.ts +8 -11
- package/src/device/motion.ts +8 -11
- package/src/device/plug.ts +15 -19
- package/src/device/robotvacuumcleaner.ts +22 -31
- package/src/device/waterdetector.ts +8 -11
- package/src/irdevice/airconditioner.ts +12 -14
- package/src/irdevice/airpurifier.ts +12 -13
- package/src/irdevice/camera.ts +10 -11
- package/src/irdevice/fan.ts +16 -17
- package/src/irdevice/irdevice.ts +9 -17
- package/src/irdevice/light.ts +10 -11
- package/src/irdevice/other.ts +10 -11
- package/src/irdevice/tv.ts +28 -29
- package/src/irdevice/vacuumcleaner.ts +10 -11
- package/src/irdevice/waterheater.ts +10 -11
- package/src/platform.ts +110 -171
- package/src/settings.ts +5 -4
- package/src/utils.ts +2 -1
- package/dist/types/bledevicestatus.d.ts +0 -281
- package/dist/types/bledevicestatus.d.ts.map +0 -1
- package/dist/types/bledevicestatus.js +0 -2
- package/dist/types/bledevicestatus.js.map +0 -1
- package/dist/types/devicelist.d.ts +0 -89
- package/dist/types/devicelist.d.ts.map +0 -1
- package/dist/types/devicelist.js +0 -6
- package/dist/types/devicelist.js.map +0 -1
- package/dist/types/deviceresponse.d.ts +0 -13
- package/dist/types/deviceresponse.d.ts.map +0 -1
- package/dist/types/deviceresponse.js +0 -2
- package/dist/types/deviceresponse.js.map +0 -1
- package/dist/types/devicestatus.d.ts +0 -149
- package/dist/types/devicestatus.d.ts.map +0 -1
- package/dist/types/devicestatus.js +0 -3
- package/dist/types/devicestatus.js.map +0 -1
- package/dist/types/devicewebhookstatus.d.ts +0 -156
- package/dist/types/devicewebhookstatus.d.ts.map +0 -1
- package/dist/types/devicewebhookstatus.js +0 -2
- package/dist/types/devicewebhookstatus.js.map +0 -1
- package/dist/types/irdevicelist.d.ts +0 -10
- package/dist/types/irdevicelist.d.ts.map +0 -1
- package/dist/types/irdevicelist.js +0 -2
- package/dist/types/irdevicelist.js.map +0 -1
- package/dist/types/pushbody.d.ts +0 -6
- package/dist/types/pushbody.d.ts.map +0 -1
- package/dist/types/pushbody.js +0 -2
- package/dist/types/pushbody.js.map +0 -1
- package/src/types/bledevicestatus.ts +0 -303
- package/src/types/devicelist.ts +0 -124
- package/src/types/deviceresponse.ts +0 -14
- package/src/types/devicestatus.ts +0 -178
- package/src/types/devicewebhookstatus.ts +0 -191
- package/src/types/irdevicelist.ts +0 -15
- package/src/types/pushbody.ts +0 -9
package/dist/platform.js
CHANGED
|
@@ -1,18 +1,10 @@
|
|
|
1
|
-
import { Buffer } from 'node:buffer';
|
|
2
|
-
import crypto, { randomUUID } from 'node:crypto';
|
|
3
1
|
import { readFileSync, writeFileSync } from 'node:fs';
|
|
4
|
-
import { createServer } from 'node:http';
|
|
5
2
|
import process from 'node:process';
|
|
6
3
|
import asyncmqtt from 'async-mqtt';
|
|
7
4
|
import fakegato from 'fakegato-history';
|
|
8
5
|
import { EveHomeKitTypes } from 'homebridge-lib/EveHomeKitTypes';
|
|
9
|
-
|
|
10
|
-
* For Testing Locally:
|
|
11
|
-
* import { SwitchBotModel } from '/Users/Shared/GitHub/OpenWonderLabs/node-switchbot/dist/index.js';
|
|
12
|
-
*/
|
|
13
|
-
import { SwitchBot, SwitchBotModel } from 'node-switchbot';
|
|
6
|
+
import { LogLevel, SwitchBotBLE, SwitchBotModel, SwitchBotOpenAPI } from 'node-switchbot';
|
|
14
7
|
import { queueScheduler } from 'rxjs';
|
|
15
|
-
import { request } from 'undici';
|
|
16
8
|
import { BlindTilt } from './device/blindtilt.js';
|
|
17
9
|
import { Bot } from './device/bot.js';
|
|
18
10
|
import { CeilingLight } from './device/ceilinglight.js';
|
|
@@ -40,7 +32,7 @@ import { Others } from './irdevice/other.js';
|
|
|
40
32
|
import { TV } from './irdevice/tv.js';
|
|
41
33
|
import { VacuumCleaner } from './irdevice/vacuumcleaner.js';
|
|
42
34
|
import { WaterHeater } from './irdevice/waterheater.js';
|
|
43
|
-
import {
|
|
35
|
+
import { PLATFORM_NAME, PLUGIN_NAME } from './settings.js';
|
|
44
36
|
import { formatDeviceIdAsMac, isBlindTiltDevice, isCurtainDevice, sleep } from './utils.js';
|
|
45
37
|
/**
|
|
46
38
|
* HomebridgePlatform
|
|
@@ -64,6 +56,9 @@ export class SwitchBotPlatform {
|
|
|
64
56
|
// MQTT and Webhook properties
|
|
65
57
|
mqttClient = null;
|
|
66
58
|
webhookEventListener = null;
|
|
59
|
+
// SwitchBot APIs
|
|
60
|
+
switchBotAPI;
|
|
61
|
+
switchBotBLE;
|
|
67
62
|
// External APIs
|
|
68
63
|
eve;
|
|
69
64
|
fakegatoAPI;
|
|
@@ -100,6 +95,37 @@ export class SwitchBotPlatform {
|
|
|
100
95
|
this.debugErrorLog(`Verify Config, Error: ${e}`);
|
|
101
96
|
return;
|
|
102
97
|
}
|
|
98
|
+
// SwitchBot OpenAPI
|
|
99
|
+
this.switchBotAPI = new SwitchBotOpenAPI(this.config.credentials?.token, this.config.credentials?.secret);
|
|
100
|
+
// Listen for log events
|
|
101
|
+
this.switchBotAPI.on('log', (log) => {
|
|
102
|
+
switch (log.level) {
|
|
103
|
+
case LogLevel.SUCCESS:
|
|
104
|
+
this.successLog(log.message);
|
|
105
|
+
break;
|
|
106
|
+
case LogLevel.DEBUGSUCCESS:
|
|
107
|
+
this.debugSuccessLog(log.message);
|
|
108
|
+
break;
|
|
109
|
+
case LogLevel.WARN:
|
|
110
|
+
this.warnLog(log.message);
|
|
111
|
+
break;
|
|
112
|
+
case LogLevel.DEBUGWARN:
|
|
113
|
+
this.debugWarnLog(log.message);
|
|
114
|
+
break;
|
|
115
|
+
case LogLevel.ERROR:
|
|
116
|
+
this.errorLog(log.message);
|
|
117
|
+
break;
|
|
118
|
+
case LogLevel.DEBUGERROR:
|
|
119
|
+
this.debugErrorLog(log.message);
|
|
120
|
+
break;
|
|
121
|
+
case LogLevel.DEBUG:
|
|
122
|
+
this.debugLog(log.message);
|
|
123
|
+
break;
|
|
124
|
+
case LogLevel.INFO:
|
|
125
|
+
default:
|
|
126
|
+
this.infoLog(log.message);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
103
129
|
// import fakegato-history module and EVE characteristics
|
|
104
130
|
this.fakegatoAPI = fakegato(api);
|
|
105
131
|
this.eve = new EveHomeKitTypes(api);
|
|
@@ -181,123 +207,23 @@ export class SwitchBotPlatform {
|
|
|
181
207
|
if (this.config.options?.webhookURL) {
|
|
182
208
|
const url = this.config.options?.webhookURL;
|
|
183
209
|
try {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
try {
|
|
192
|
-
const body = JSON.parse(data);
|
|
193
|
-
await this.debugLog(`Received Webhook: ${JSON.stringify(body)}`);
|
|
194
|
-
if (this.config.options?.mqttURL) {
|
|
195
|
-
const mac = body.context.deviceMac?.toLowerCase().match(/[\s\S]{1,2}/g)?.join(':');
|
|
196
|
-
const options = this.config.options?.mqttPubOptions || {};
|
|
197
|
-
this.mqttClient?.publish(`homebridge-switchbot/webhook/${mac}`, `${JSON.stringify(body.context)}`, options);
|
|
198
|
-
}
|
|
199
|
-
this.webhookEventHandler[body.context.deviceMac]?.(body.context);
|
|
200
|
-
}
|
|
201
|
-
catch (e) {
|
|
202
|
-
await this.errorLog(`Failed to handle webhook event. Error:${e}`);
|
|
203
|
-
}
|
|
204
|
-
});
|
|
205
|
-
response.writeHead(200, { 'Content-Type': 'text/plain' });
|
|
206
|
-
response.end('OK');
|
|
207
|
-
}
|
|
208
|
-
// else {
|
|
209
|
-
// response.writeHead(403, {'Content-Type': 'text/plain'});
|
|
210
|
-
// response.end(`NG`);
|
|
211
|
-
// }
|
|
210
|
+
this.switchBotAPI.setupWebhook(url);
|
|
211
|
+
// Listen for webhook events
|
|
212
|
+
this.switchBotAPI.on('webhookEvent', (body) => {
|
|
213
|
+
if (this.config.options?.mqttURL) {
|
|
214
|
+
const mac = body.context.deviceMac?.toLowerCase().match(/[\s\S]{1,2}/g)?.join(':');
|
|
215
|
+
const options = this.config.options?.mqttPubOptions || {};
|
|
216
|
+
this.mqttClient?.publish(`homebridge-switchbot/webhook/${mac}`, `${JSON.stringify(body.context)}`, options);
|
|
212
217
|
}
|
|
213
|
-
|
|
214
|
-
this.errorLog(`Failed to handle webhook event. Error:${e}`);
|
|
215
|
-
}
|
|
216
|
-
}).listen(port || 80);
|
|
217
|
-
}
|
|
218
|
-
catch (e) {
|
|
219
|
-
await this.errorLog(`Failed to create webhook listener. Error:${e.message}`);
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
try {
|
|
223
|
-
const { body, statusCode } = await request(setupWebhook, {
|
|
224
|
-
method: 'POST',
|
|
225
|
-
headers: this.generateHeaders(),
|
|
226
|
-
body: JSON.stringify({
|
|
227
|
-
action: 'setupWebhook',
|
|
228
|
-
url,
|
|
229
|
-
deviceList: 'ALL',
|
|
230
|
-
}),
|
|
218
|
+
this.webhookEventHandler[body.context.deviceMac]?.(body.context);
|
|
231
219
|
});
|
|
232
|
-
const response = await body.json();
|
|
233
|
-
await this.debugLog(`setupWebhook: url:${url}, body:${JSON.stringify(response)}, statusCode:${statusCode}`);
|
|
234
|
-
if (statusCode !== 200 || response?.statusCode !== 100) {
|
|
235
|
-
await this.errorLog(`Failed to configure webhook. Existing webhook well be overridden. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`);
|
|
236
|
-
}
|
|
237
220
|
}
|
|
238
221
|
catch (e) {
|
|
239
|
-
await this.errorLog(`Failed to
|
|
240
|
-
}
|
|
241
|
-
try {
|
|
242
|
-
const { body, statusCode } = await request(updateWebhook, {
|
|
243
|
-
method: 'POST',
|
|
244
|
-
headers: this.generateHeaders(),
|
|
245
|
-
body: JSON.stringify({
|
|
246
|
-
action: 'updateWebhook',
|
|
247
|
-
config: {
|
|
248
|
-
url,
|
|
249
|
-
enable: true,
|
|
250
|
-
},
|
|
251
|
-
}),
|
|
252
|
-
});
|
|
253
|
-
const response = await body.json();
|
|
254
|
-
await this.debugLog(`updateWebhook: url:${url}, body:${JSON.stringify(response)}, statusCode:${statusCode}`);
|
|
255
|
-
if (statusCode !== 200 || response?.statusCode !== 100) {
|
|
256
|
-
await this.errorLog(`Failed to update webhook. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
catch (e) {
|
|
260
|
-
await this.errorLog(`Failed to update webhook. Error:${e.message}`);
|
|
261
|
-
}
|
|
262
|
-
try {
|
|
263
|
-
const { body, statusCode } = await request(queryWebhook, {
|
|
264
|
-
method: 'POST',
|
|
265
|
-
headers: this.generateHeaders(),
|
|
266
|
-
body: JSON.stringify({
|
|
267
|
-
action: 'queryUrl',
|
|
268
|
-
}),
|
|
269
|
-
});
|
|
270
|
-
const response = await body.json();
|
|
271
|
-
await this.debugLog(`queryWebhook: body:${JSON.stringify(response)}`);
|
|
272
|
-
await this.debugLog(`queryWebhook: statusCode:${statusCode}`);
|
|
273
|
-
if (statusCode !== 200 || response?.statusCode !== 100) {
|
|
274
|
-
await this.errorLog(`Failed to query webhook. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`);
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
await this.infoLog(`Listening webhook on ${response?.body?.urls[0]}`);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
catch (e) {
|
|
281
|
-
await this.errorLog(`Failed to query webhook. Error:${e}`);
|
|
222
|
+
await this.errorLog(`Failed to setup webhook. Error:${e.message}`);
|
|
282
223
|
}
|
|
283
224
|
this.api.on('shutdown', async () => {
|
|
284
225
|
try {
|
|
285
|
-
|
|
286
|
-
method: 'POST',
|
|
287
|
-
headers: this.generateHeaders(),
|
|
288
|
-
body: JSON.stringify({
|
|
289
|
-
action: 'deleteWebhook',
|
|
290
|
-
url,
|
|
291
|
-
}),
|
|
292
|
-
});
|
|
293
|
-
const response = await body.json();
|
|
294
|
-
await this.debugLog(`deleteWebhook: url:${url}, body:${JSON.stringify(response)}, statusCode:${statusCode}`);
|
|
295
|
-
if (statusCode !== 200 || response?.statusCode !== 100) {
|
|
296
|
-
await this.errorLog(`Failed to delete webhook. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`);
|
|
297
|
-
}
|
|
298
|
-
else {
|
|
299
|
-
await this.infoLog('Unregistered webhook to close listening.');
|
|
300
|
-
}
|
|
226
|
+
this.switchBotAPI.deleteWebhook(url);
|
|
301
227
|
}
|
|
302
228
|
catch (e) {
|
|
303
229
|
await this.errorLog(`Failed to delete webhook. Error:${e.message}`);
|
|
@@ -306,20 +232,54 @@ export class SwitchBotPlatform {
|
|
|
306
232
|
}
|
|
307
233
|
}
|
|
308
234
|
async setupBlE() {
|
|
235
|
+
this.switchBotBLE = new SwitchBotBLE();
|
|
236
|
+
// Listen for log events
|
|
237
|
+
this.switchBotBLE.on('log', (log) => {
|
|
238
|
+
switch (log.level) {
|
|
239
|
+
case LogLevel.SUCCESS:
|
|
240
|
+
this.successLog(log.message);
|
|
241
|
+
break;
|
|
242
|
+
case LogLevel.DEBUGSUCCESS:
|
|
243
|
+
this.debugSuccessLog(log.message);
|
|
244
|
+
break;
|
|
245
|
+
case LogLevel.WARN:
|
|
246
|
+
this.warnLog(log.message);
|
|
247
|
+
break;
|
|
248
|
+
case LogLevel.DEBUGWARN:
|
|
249
|
+
this.debugWarnLog(log.message);
|
|
250
|
+
break;
|
|
251
|
+
case LogLevel.ERROR:
|
|
252
|
+
this.errorLog(log.message);
|
|
253
|
+
break;
|
|
254
|
+
case LogLevel.DEBUGERROR:
|
|
255
|
+
this.debugErrorLog(log.message);
|
|
256
|
+
break;
|
|
257
|
+
case LogLevel.DEBUG:
|
|
258
|
+
this.debugLog(log.message);
|
|
259
|
+
break;
|
|
260
|
+
case LogLevel.INFO:
|
|
261
|
+
default:
|
|
262
|
+
this.infoLog(log.message);
|
|
263
|
+
}
|
|
264
|
+
});
|
|
309
265
|
if (this.config.options?.BLE) {
|
|
310
266
|
await this.debugLog('setupBLE');
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
267
|
+
if (this.switchBotBLE === undefined) {
|
|
268
|
+
await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${this.switchBotBLE}`);
|
|
314
269
|
}
|
|
315
270
|
else {
|
|
316
271
|
// Start to monitor advertisement packets
|
|
317
272
|
(async () => {
|
|
318
273
|
// Start to monitor advertisement packets
|
|
319
274
|
await this.debugLog('Scanning for BLE SwitchBot devices...');
|
|
320
|
-
|
|
275
|
+
try {
|
|
276
|
+
await this.switchBotBLE.startScan();
|
|
277
|
+
}
|
|
278
|
+
catch (e) {
|
|
279
|
+
await this.errorLog(`Failed to start BLE scanning. Error:${e}`);
|
|
280
|
+
}
|
|
321
281
|
// Set an event handler to monitor advertisement packets
|
|
322
|
-
|
|
282
|
+
this.switchBotBLE.onadvertisement = async (ad) => {
|
|
323
283
|
try {
|
|
324
284
|
this.bleEventHandler[ad.address]?.(ad.serviceData);
|
|
325
285
|
}
|
|
@@ -330,7 +290,7 @@ export class SwitchBotPlatform {
|
|
|
330
290
|
})();
|
|
331
291
|
this.api.on('shutdown', async () => {
|
|
332
292
|
try {
|
|
333
|
-
|
|
293
|
+
this.switchBotBLE.stopScan();
|
|
334
294
|
await this.infoLog('Stopped BLE scanning to close listening.');
|
|
335
295
|
}
|
|
336
296
|
catch (e) {
|
|
@@ -492,23 +452,6 @@ export class SwitchBotPlatform {
|
|
|
492
452
|
await this.errorLog(`Update Token: ${e}`);
|
|
493
453
|
}
|
|
494
454
|
}
|
|
495
|
-
generateHeaders = () => {
|
|
496
|
-
const t = `${Date.now()}`;
|
|
497
|
-
const nonce = randomUUID();
|
|
498
|
-
const data = this.config.credentials?.token + t + nonce;
|
|
499
|
-
const signTerm = crypto
|
|
500
|
-
.createHmac('sha256', this.config.credentials?.secret)
|
|
501
|
-
.update(Buffer.from(data, 'utf-8'))
|
|
502
|
-
.digest();
|
|
503
|
-
const sign = signTerm.toString('base64');
|
|
504
|
-
return {
|
|
505
|
-
'Authorization': this.config.credentials?.token,
|
|
506
|
-
'sign': sign,
|
|
507
|
-
'nonce': nonce,
|
|
508
|
-
't': t,
|
|
509
|
-
'Content-Type': 'application/json',
|
|
510
|
-
};
|
|
511
|
-
};
|
|
512
455
|
async discoverDevices() {
|
|
513
456
|
if (!this.config.credentials?.token) {
|
|
514
457
|
return this.handleManualConfig();
|
|
@@ -521,17 +464,15 @@ export class SwitchBotPlatform {
|
|
|
521
464
|
await this.debugWarnLog(`Delay Between Retries: ${delayBetweenRetries}`);
|
|
522
465
|
while (retryCount < maxRetries) {
|
|
523
466
|
try {
|
|
524
|
-
const {
|
|
525
|
-
await this.
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
await this.handleDevices(devicesAPI.body.deviceList);
|
|
530
|
-
await this.handleIRDevices(devicesAPI.body.infraredRemoteList);
|
|
467
|
+
const { response, statusCode } = await this.switchBotAPI.getDevices();
|
|
468
|
+
await this.debugLog(`response: ${JSON.stringify(response)}`);
|
|
469
|
+
if (this.isSuccessfulResponse(statusCode)) {
|
|
470
|
+
await this.handleDevices(Array.isArray(response.body.deviceList) ? response.body.deviceList : []);
|
|
471
|
+
await this.handleIRDevices(Array.isArray(response.body.infraredRemoteList) ? response.body.infraredRemoteList : []);
|
|
531
472
|
break;
|
|
532
473
|
}
|
|
533
474
|
else {
|
|
534
|
-
await this.handleErrorResponse(statusCode,
|
|
475
|
+
await this.handleErrorResponse(statusCode, retryCount, maxRetries, delayBetweenRetries);
|
|
535
476
|
retryCount++;
|
|
536
477
|
}
|
|
537
478
|
}
|
|
@@ -565,8 +506,8 @@ export class SwitchBotPlatform {
|
|
|
565
506
|
await this.errorLog('Neither SwitchBot Token or Device Config are set.');
|
|
566
507
|
}
|
|
567
508
|
}
|
|
568
|
-
isSuccessfulResponse(
|
|
569
|
-
return (
|
|
509
|
+
isSuccessfulResponse(apiStatusCode) {
|
|
510
|
+
return (apiStatusCode === 200 || apiStatusCode === 100);
|
|
570
511
|
}
|
|
571
512
|
async handleDevices(deviceLists) {
|
|
572
513
|
if (!this.config.options?.devices) {
|
|
@@ -631,11 +572,10 @@ export class SwitchBotPlatform {
|
|
|
631
572
|
return { ...matchingItem, ...itm };
|
|
632
573
|
});
|
|
633
574
|
}
|
|
634
|
-
async handleErrorResponse(
|
|
635
|
-
await this.statusCode(statusCode);
|
|
575
|
+
async handleErrorResponse(apiStatusCode, retryCount, maxRetries, delayBetweenRetries) {
|
|
636
576
|
await this.statusCode(apiStatusCode);
|
|
637
|
-
if (
|
|
638
|
-
this.infoLog(`statusCode: ${
|
|
577
|
+
if (apiStatusCode === 500) {
|
|
578
|
+
this.infoLog(`statusCode: ${apiStatusCode} Attempt ${retryCount + 1} of ${maxRetries}`);
|
|
639
579
|
await sleep(delayBetweenRetries);
|
|
640
580
|
}
|
|
641
581
|
}
|
|
@@ -2531,19 +2471,15 @@ export class SwitchBotPlatform {
|
|
|
2531
2471
|
await this.errorLog(message);
|
|
2532
2472
|
}
|
|
2533
2473
|
}
|
|
2534
|
-
async retryRequest(deviceMaxRetries, deviceDelayBetweenRetries
|
|
2474
|
+
async retryRequest(deviceId, deviceMaxRetries, deviceDelayBetweenRetries) {
|
|
2535
2475
|
let retryCount = 0;
|
|
2536
2476
|
const maxRetries = deviceMaxRetries;
|
|
2537
2477
|
const delayBetweenRetries = deviceDelayBetweenRetries;
|
|
2538
2478
|
while (retryCount < maxRetries) {
|
|
2539
2479
|
try {
|
|
2540
|
-
const {
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
}
|
|
2544
|
-
else {
|
|
2545
|
-
await this.debugLog(`Received status code: ${statusCode}`);
|
|
2546
|
-
}
|
|
2480
|
+
const { response, statusCode } = await this.switchBotAPI.getDeviceStatus(deviceId);
|
|
2481
|
+
await this.debugLog(`response: ${JSON.stringify(response)}`);
|
|
2482
|
+
return { response, statusCode };
|
|
2547
2483
|
}
|
|
2548
2484
|
catch (error) {
|
|
2549
2485
|
await this.errorLog(`Error making request: ${error.message}`);
|
|
@@ -2552,15 +2488,14 @@ export class SwitchBotPlatform {
|
|
|
2552
2488
|
await this.debugLog(`Retry attempt ${retryCount} of ${maxRetries}`);
|
|
2553
2489
|
await sleep(delayBetweenRetries);
|
|
2554
2490
|
}
|
|
2555
|
-
return {
|
|
2491
|
+
return { response: null, statusCode: 500 };
|
|
2556
2492
|
}
|
|
2557
2493
|
// BLE Connection
|
|
2558
2494
|
async connectBLE(accessory, device) {
|
|
2559
2495
|
try {
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
return switchbot;
|
|
2496
|
+
queueScheduler.schedule(async () => this.switchBotBLE);
|
|
2497
|
+
await this.debugLog(`${device.deviceType}: ${accessory.displayName} 'node-switchbot' found: ${this.switchBotBLE}`);
|
|
2498
|
+
return this.switchBotBLE;
|
|
2564
2499
|
}
|
|
2565
2500
|
catch (e) {
|
|
2566
2501
|
await this.errorLog(`${device.deviceType}: ${accessory.displayName} 'node-switchbot' not found, Error: ${e}`);
|