@switchbot/homebridge-switchbot 3.8.3 → 4.0.0-beta.1
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/npm-version-script.cjs +81 -0
- package/.github/workflows/beta-release.yml +12 -4
- package/CHANGELOG.md +15 -1
- package/config.schema.json +583 -937
- package/dist/device/blindtilt.d.ts +1 -4
- package/dist/device/blindtilt.d.ts.map +1 -1
- package/dist/device/blindtilt.js +68 -66
- 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 +63 -59
- 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 +56 -65
- 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 +73 -80
- 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 +38 -38
- 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 +60 -60
- 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 +86 -20
- 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 +50 -51
- 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 +48 -48
- 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 +53 -55
- 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 +35 -35
- 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 +57 -65
- 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 +38 -39
- 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 +35 -35
- 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 +35 -35
- 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 +27 -27
- 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 +32 -32
- 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 +39 -40
- 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 +28 -28
- 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 +31 -32
- 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 +22 -23
- 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 +28 -14
- 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 +12 -13
- 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 +12 -15
- 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 +9 -22
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +154 -260
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +64 -82
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +0 -20
- package/dist/settings.js.map +1 -1
- package/dist/utils.d.ts +1 -102
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +0 -105
- 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 +5 -7
- package/src/device/blindtilt.ts +74 -74
- package/src/device/bot.ts +68 -67
- package/src/device/ceilinglight.ts +59 -70
- package/src/device/colorbulb.ts +79 -88
- package/src/device/contact.ts +40 -43
- package/src/device/curtain.ts +66 -68
- package/src/device/device.ts +86 -40
- package/src/device/fan.ts +52 -56
- package/src/device/hub.ts +50 -53
- package/src/device/humidifier.ts +56 -61
- package/src/device/iosensor.ts +37 -40
- package/src/device/lightstrip.ts +62 -72
- package/src/device/lock.ts +41 -45
- package/src/device/meter.ts +37 -40
- package/src/device/meterplus.ts +37 -40
- package/src/device/motion.ts +29 -32
- package/src/device/plug.ts +34 -37
- package/src/device/robotvacuumcleaner.ts +41 -49
- package/src/device/waterdetector.ts +30 -33
- package/src/irdevice/airconditioner.ts +33 -35
- package/src/irdevice/airpurifier.ts +12 -13
- package/src/irdevice/camera.ts +10 -11
- package/src/irdevice/fan.ts +24 -25
- package/src/irdevice/irdevice.ts +31 -27
- package/src/irdevice/light.ts +14 -15
- package/src/irdevice/other.ts +14 -17
- 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 +178 -287
- package/src/settings.ts +67 -88
- package/src/utils.ts +2 -106
- 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 {
|
|
2
|
-
import crypto, { randomUUID } from 'node:crypto';
|
|
3
|
-
import { readFileSync, writeFileSync } from 'node:fs';
|
|
4
|
-
import { createServer } from 'node:http';
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
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;
|
|
@@ -75,6 +70,7 @@ export class SwitchBotPlatform {
|
|
|
75
70
|
this.log = log;
|
|
76
71
|
// only load if configured
|
|
77
72
|
if (!config) {
|
|
73
|
+
this.log.error('No configuration found for the plugin, please check your config.');
|
|
78
74
|
return;
|
|
79
75
|
}
|
|
80
76
|
// Plugin options into our config variables.
|
|
@@ -83,6 +79,8 @@ export class SwitchBotPlatform {
|
|
|
83
79
|
name: config.name,
|
|
84
80
|
credentials: config.credentials,
|
|
85
81
|
options: config.options,
|
|
82
|
+
devices: config.devices,
|
|
83
|
+
deviceConfig: config.deviceConfig,
|
|
86
84
|
};
|
|
87
85
|
// Plugin Configuration
|
|
88
86
|
this.getPlatformLogSettings();
|
|
@@ -96,10 +94,52 @@ export class SwitchBotPlatform {
|
|
|
96
94
|
this.debugLog('Config OK');
|
|
97
95
|
}
|
|
98
96
|
catch (e) {
|
|
99
|
-
this.errorLog(`Verify Config, Error Message: ${e.message}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug');
|
|
100
|
-
this.debugErrorLog(`Verify Config, Error: ${e}`);
|
|
97
|
+
this.errorLog(`Verify Config, Error Message: ${e.message ?? e}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug');
|
|
98
|
+
this.debugErrorLog(`Verify Config, Error: ${e.message ?? e}`);
|
|
101
99
|
return;
|
|
102
100
|
}
|
|
101
|
+
// SwitchBot OpenAPI
|
|
102
|
+
if (this.config.credentials?.token && this.config.credentials?.secret) {
|
|
103
|
+
this.switchBotAPI = new SwitchBotOpenAPI(this.config.credentials.token, this.config.credentials.secret);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
this.debugErrorLog('Missing SwitchBot API credentials (token or secret).');
|
|
107
|
+
}
|
|
108
|
+
// Listen for log events
|
|
109
|
+
if (!this.config.options?.disableLogsforOpenAPI && this.switchBotAPI) {
|
|
110
|
+
this.switchBotAPI.on('log', (log) => {
|
|
111
|
+
switch (log.level) {
|
|
112
|
+
case LogLevel.SUCCESS:
|
|
113
|
+
this.successLog(log.message);
|
|
114
|
+
break;
|
|
115
|
+
case LogLevel.DEBUGSUCCESS:
|
|
116
|
+
this.debugSuccessLog(log.message);
|
|
117
|
+
break;
|
|
118
|
+
case LogLevel.WARN:
|
|
119
|
+
this.warnLog(log.message);
|
|
120
|
+
break;
|
|
121
|
+
case LogLevel.DEBUGWARN:
|
|
122
|
+
this.debugWarnLog(log.message);
|
|
123
|
+
break;
|
|
124
|
+
case LogLevel.ERROR:
|
|
125
|
+
this.errorLog(log.message);
|
|
126
|
+
break;
|
|
127
|
+
case LogLevel.DEBUGERROR:
|
|
128
|
+
this.debugErrorLog(log.message);
|
|
129
|
+
break;
|
|
130
|
+
case LogLevel.DEBUG:
|
|
131
|
+
this.debugLog(log.message);
|
|
132
|
+
break;
|
|
133
|
+
case LogLevel.INFO:
|
|
134
|
+
default:
|
|
135
|
+
this.infoLog(log.message);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
this.debugErrorLog(`SwitchBot OpenAPI logs are disabled, enable it by setting disableLogsforOpenAPI to false.`);
|
|
141
|
+
this.debugLog(`SwitchBot OpenAPI: ${JSON.stringify(this.switchBotAPI)}, disableLogsforOpenAPI: ${this.config.options?.disableLogsforOpenAPI}`);
|
|
142
|
+
}
|
|
103
143
|
// import fakegato-history module and EVE characteristics
|
|
104
144
|
this.fakegatoAPI = fakegato(api);
|
|
105
145
|
this.eve = new EveHomeKitTypes(api);
|
|
@@ -111,38 +151,30 @@ export class SwitchBotPlatform {
|
|
|
111
151
|
await this.debugLog('Executed didFinishLaunching callback');
|
|
112
152
|
// run the method to discover / register your devices as accessories
|
|
113
153
|
try {
|
|
114
|
-
|
|
115
|
-
await this.updateToken();
|
|
116
|
-
}
|
|
117
|
-
else if (this.config.credentials?.token && !this.config.credentials?.secret) {
|
|
118
|
-
await this.errorLog('"secret" config is not populated, you must populate then please restart Homebridge.');
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
await this.discoverDevices();
|
|
122
|
-
}
|
|
154
|
+
await this.discoverDevices();
|
|
123
155
|
}
|
|
124
156
|
catch (e) {
|
|
125
|
-
await this.errorLog(`Failed to Discover, Error Message: ${e.message}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug');
|
|
126
|
-
await this.debugErrorLog(`Failed to Discover, Error: ${e}`);
|
|
157
|
+
await this.errorLog(`Failed to Discover, Error Message: ${e.message ?? e}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug');
|
|
158
|
+
await this.debugErrorLog(`Failed to Discover, Error: ${e.message ?? e}`);
|
|
127
159
|
}
|
|
128
160
|
});
|
|
129
161
|
try {
|
|
130
162
|
this.setupMqtt();
|
|
131
163
|
}
|
|
132
164
|
catch (e) {
|
|
133
|
-
this.errorLog(`Setup MQTT, Error Message: ${e.message}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug');
|
|
165
|
+
this.errorLog(`Setup MQTT, Error Message: ${e.message ?? e}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug');
|
|
134
166
|
}
|
|
135
167
|
try {
|
|
136
168
|
this.setupwebhook();
|
|
137
169
|
}
|
|
138
170
|
catch (e) {
|
|
139
|
-
this.errorLog(`Setup Webhook, Error Message: ${e.message}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug');
|
|
171
|
+
this.errorLog(`Setup Webhook, Error Message: ${e.message ?? e}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug');
|
|
140
172
|
}
|
|
141
173
|
try {
|
|
142
174
|
this.setupBlE();
|
|
143
175
|
}
|
|
144
176
|
catch (e) {
|
|
145
|
-
this.errorLog(`Setup Platform BLE, Error Message: ${e.message}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug');
|
|
177
|
+
this.errorLog(`Setup Platform BLE, Error Message: ${e.message ?? e}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug');
|
|
146
178
|
}
|
|
147
179
|
}
|
|
148
180
|
async setupMqtt() {
|
|
@@ -152,7 +184,7 @@ export class SwitchBotPlatform {
|
|
|
152
184
|
this.mqttClient = await connectAsync(this.config.options?.mqttURL, this.config.options.mqttOptions || {});
|
|
153
185
|
await this.debugLog('MQTT connection has been established successfully.');
|
|
154
186
|
this.mqttClient.on('error', async (e) => {
|
|
155
|
-
await this.errorLog(`Failed to publish MQTT messages. ${e}`);
|
|
187
|
+
await this.errorLog(`Failed to publish MQTT messages. ${e.message ?? e}`);
|
|
156
188
|
});
|
|
157
189
|
if (!this.config.options?.webhookURL) {
|
|
158
190
|
// receive webhook events via MQTT
|
|
@@ -165,14 +197,14 @@ export class SwitchBotPlatform {
|
|
|
165
197
|
this.webhookEventHandler[context.deviceMac]?.(context);
|
|
166
198
|
}
|
|
167
199
|
catch (e) {
|
|
168
|
-
await this.errorLog(`Failed to handle webhook event. Error:${e}`);
|
|
200
|
+
await this.errorLog(`Failed to handle webhook event. Error:${e.message ?? e}`);
|
|
169
201
|
}
|
|
170
202
|
});
|
|
171
203
|
}
|
|
172
204
|
}
|
|
173
205
|
catch (e) {
|
|
174
206
|
this.mqttClient = null;
|
|
175
|
-
await this.errorLog(`Failed to establish MQTT connection. ${e}`);
|
|
207
|
+
await this.errorLog(`Failed to establish MQTT connection. ${e.message ?? e}`);
|
|
176
208
|
}
|
|
177
209
|
}
|
|
178
210
|
}
|
|
@@ -181,160 +213,96 @@ export class SwitchBotPlatform {
|
|
|
181
213
|
if (this.config.options?.webhookURL) {
|
|
182
214
|
const url = this.config.options?.webhookURL;
|
|
183
215
|
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
|
-
// }
|
|
216
|
+
this.switchBotAPI.setupWebhook(url);
|
|
217
|
+
// Listen for webhook events
|
|
218
|
+
this.switchBotAPI.on('webhookEvent', (body) => {
|
|
219
|
+
if (this.config.options?.mqttURL) {
|
|
220
|
+
const mac = body.context.deviceMac?.toLowerCase().match(/[\s\S]{1,2}/g)?.join(':');
|
|
221
|
+
const options = this.config.options?.mqttPubOptions || {};
|
|
222
|
+
this.mqttClient?.publish(`homebridge-switchbot/webhook/${mac}`, `${JSON.stringify(body.context)}`, options);
|
|
212
223
|
}
|
|
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
|
-
}),
|
|
224
|
+
this.webhookEventHandler[body.context.deviceMac]?.(body.context);
|
|
231
225
|
});
|
|
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
|
-
}
|
|
238
|
-
catch (e) {
|
|
239
|
-
await this.errorLog(`Failed to configure webhook. Error: ${e.message}`);
|
|
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
226
|
}
|
|
280
227
|
catch (e) {
|
|
281
|
-
await this.errorLog(`Failed to
|
|
228
|
+
await this.errorLog(`Failed to setup webhook. Error:${e.message ?? e}`);
|
|
282
229
|
}
|
|
283
230
|
this.api.on('shutdown', async () => {
|
|
284
231
|
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
|
-
}
|
|
232
|
+
this.switchBotAPI.deleteWebhook(url);
|
|
301
233
|
}
|
|
302
234
|
catch (e) {
|
|
303
|
-
await this.errorLog(`Failed to delete webhook. Error:${e.message}`);
|
|
235
|
+
await this.errorLog(`Failed to delete webhook. Error:${e.message ?? e}`);
|
|
304
236
|
}
|
|
305
237
|
});
|
|
306
238
|
}
|
|
307
239
|
}
|
|
308
240
|
async setupBlE() {
|
|
241
|
+
this.switchBotBLE = new SwitchBotBLE();
|
|
242
|
+
// Listen for log events
|
|
243
|
+
if (!this.config.options?.disableLogsforBLE) {
|
|
244
|
+
this.switchBotBLE.on('log', (log) => {
|
|
245
|
+
switch (log.level) {
|
|
246
|
+
case LogLevel.SUCCESS:
|
|
247
|
+
this.successLog(log.message);
|
|
248
|
+
break;
|
|
249
|
+
case LogLevel.DEBUGSUCCESS:
|
|
250
|
+
this.debugSuccessLog(log.message);
|
|
251
|
+
break;
|
|
252
|
+
case LogLevel.WARN:
|
|
253
|
+
this.warnLog(log.message);
|
|
254
|
+
break;
|
|
255
|
+
case LogLevel.DEBUGWARN:
|
|
256
|
+
this.debugWarnLog(log.message);
|
|
257
|
+
break;
|
|
258
|
+
case LogLevel.ERROR:
|
|
259
|
+
this.errorLog(log.message);
|
|
260
|
+
break;
|
|
261
|
+
case LogLevel.DEBUGERROR:
|
|
262
|
+
this.debugErrorLog(log.message);
|
|
263
|
+
break;
|
|
264
|
+
case LogLevel.DEBUG:
|
|
265
|
+
this.debugLog(log.message);
|
|
266
|
+
break;
|
|
267
|
+
case LogLevel.INFO:
|
|
268
|
+
default:
|
|
269
|
+
this.infoLog(log.message);
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
}
|
|
309
273
|
if (this.config.options?.BLE) {
|
|
310
274
|
await this.debugLog('setupBLE');
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
275
|
+
if (this.switchBotBLE === undefined) {
|
|
276
|
+
await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${JSON.stringify(this.switchBotBLE)}`);
|
|
314
277
|
}
|
|
315
278
|
else {
|
|
316
279
|
// Start to monitor advertisement packets
|
|
317
280
|
(async () => {
|
|
318
281
|
// Start to monitor advertisement packets
|
|
319
282
|
await this.debugLog('Scanning for BLE SwitchBot devices...');
|
|
320
|
-
|
|
283
|
+
try {
|
|
284
|
+
await this.switchBotBLE.startScan();
|
|
285
|
+
}
|
|
286
|
+
catch (e) {
|
|
287
|
+
await this.errorLog(`Failed to start BLE scanning. Error:${e.message ?? e}`);
|
|
288
|
+
}
|
|
321
289
|
// Set an event handler to monitor advertisement packets
|
|
322
|
-
|
|
290
|
+
this.switchBotBLE.onadvertisement = async (ad) => {
|
|
323
291
|
try {
|
|
324
292
|
this.bleEventHandler[ad.address]?.(ad.serviceData);
|
|
325
293
|
}
|
|
326
294
|
catch (e) {
|
|
327
|
-
await this.errorLog(`Failed to handle BLE event. Error:${e}`);
|
|
295
|
+
await this.errorLog(`Failed to handle BLE event. Error:${e.message ?? e}`);
|
|
328
296
|
}
|
|
329
297
|
};
|
|
330
298
|
})();
|
|
331
299
|
this.api.on('shutdown', async () => {
|
|
332
300
|
try {
|
|
333
|
-
|
|
301
|
+
// this.switchBotBLE.stopScan()
|
|
334
302
|
await this.infoLog('Stopped BLE scanning to close listening.');
|
|
335
303
|
}
|
|
336
304
|
catch (e) {
|
|
337
|
-
await this.errorLog(`Failed to stop Platform BLE scanning. Error:${e.message}`);
|
|
305
|
+
await this.errorLog(`Failed to stop Platform BLE scanning. Error:${e.message ?? e}`);
|
|
338
306
|
}
|
|
339
307
|
});
|
|
340
308
|
}
|
|
@@ -445,70 +413,6 @@ export class SwitchBotPlatform {
|
|
|
445
413
|
}
|
|
446
414
|
}
|
|
447
415
|
}
|
|
448
|
-
/**
|
|
449
|
-
* The openToken was old config.
|
|
450
|
-
* This method saves the openToken as the token in the config.json file
|
|
451
|
-
*/
|
|
452
|
-
async updateToken() {
|
|
453
|
-
try {
|
|
454
|
-
// check the new token was provided
|
|
455
|
-
if (!this.config.credentials?.openToken) {
|
|
456
|
-
throw new Error('New token not provided');
|
|
457
|
-
}
|
|
458
|
-
// load in the current config
|
|
459
|
-
const currentConfig = JSON.parse(readFileSync(this.api.user.configPath(), 'utf8'));
|
|
460
|
-
// check the platforms section is an array before we do array things on it
|
|
461
|
-
if (!Array.isArray(currentConfig.platforms)) {
|
|
462
|
-
throw new TypeError('Cannot find platforms array in config');
|
|
463
|
-
}
|
|
464
|
-
// find this plugins current config
|
|
465
|
-
const pluginConfig = currentConfig.platforms.find((x) => x.platform === PLATFORM_NAME);
|
|
466
|
-
if (!pluginConfig) {
|
|
467
|
-
throw new Error(`Cannot find config for ${PLATFORM_NAME} in platforms array`);
|
|
468
|
-
}
|
|
469
|
-
// check the .credentials is an object before doing object things with it
|
|
470
|
-
if (typeof pluginConfig.credentials !== 'object') {
|
|
471
|
-
throw new TypeError('pluginConfig.credentials is not an object');
|
|
472
|
-
}
|
|
473
|
-
// Move openToken to token
|
|
474
|
-
if (!this.config.credentials.secret) {
|
|
475
|
-
await this.warnLog('This plugin has been updated to use OpenAPI v1.1, config is set with openToken, "openToken" cconfig has been moved to the "token" config');
|
|
476
|
-
this.errorLog('"secret" config is not populated, you must populate then please restart Homebridge.');
|
|
477
|
-
}
|
|
478
|
-
else {
|
|
479
|
-
await this.warnLog('This plugin has been updated to use OpenAPI v1.1, config is set with openToken, "openToken" config has been moved to the "token" config, please restart Homebridge.');
|
|
480
|
-
}
|
|
481
|
-
// set the refresh token
|
|
482
|
-
pluginConfig.credentials.token = this.config.credentials?.openToken;
|
|
483
|
-
if (pluginConfig.credentials.token) {
|
|
484
|
-
pluginConfig.credentials.openToken = undefined;
|
|
485
|
-
}
|
|
486
|
-
await this.debugWarnLog(`token: ${pluginConfig.credentials.token}`);
|
|
487
|
-
// save the config, ensuring we maintain pretty json
|
|
488
|
-
writeFileSync(this.api.user.configPath(), JSON.stringify(currentConfig, null, 4));
|
|
489
|
-
await this.verifyConfig();
|
|
490
|
-
}
|
|
491
|
-
catch (e) {
|
|
492
|
-
await this.errorLog(`Update Token: ${e}`);
|
|
493
|
-
}
|
|
494
|
-
}
|
|
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
416
|
async discoverDevices() {
|
|
513
417
|
if (!this.config.credentials?.token) {
|
|
514
418
|
return this.handleManualConfig();
|
|
@@ -521,24 +425,22 @@ export class SwitchBotPlatform {
|
|
|
521
425
|
await this.debugWarnLog(`Delay Between Retries: ${delayBetweenRetries}`);
|
|
522
426
|
while (retryCount < maxRetries) {
|
|
523
427
|
try {
|
|
524
|
-
const {
|
|
525
|
-
await this.
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
await this.handleDevices(devicesAPI.body.deviceList);
|
|
530
|
-
await this.handleIRDevices(devicesAPI.body.infraredRemoteList);
|
|
428
|
+
const { response, statusCode } = await this.switchBotAPI.getDevices();
|
|
429
|
+
await this.debugLog(`response: ${JSON.stringify(response)}`);
|
|
430
|
+
if (this.isSuccessfulResponse(statusCode)) {
|
|
431
|
+
await this.handleDevices(Array.isArray(response.body.deviceList) ? response.body.deviceList : []);
|
|
432
|
+
await this.handleIRDevices(Array.isArray(response.body.infraredRemoteList) ? response.body.infraredRemoteList : []);
|
|
531
433
|
break;
|
|
532
434
|
}
|
|
533
435
|
else {
|
|
534
|
-
await this.handleErrorResponse(statusCode,
|
|
436
|
+
await this.handleErrorResponse(statusCode, retryCount, maxRetries, delayBetweenRetries);
|
|
535
437
|
retryCount++;
|
|
536
438
|
}
|
|
537
439
|
}
|
|
538
440
|
catch (e) {
|
|
539
441
|
retryCount++;
|
|
540
442
|
await this.debugErrorLog(`Failed to Discover Devices, Error Message: ${JSON.stringify(e.message)}, Submit Bugs Here: https://tinyurl.com/SwitchBotBug`);
|
|
541
|
-
await this.debugErrorLog(`Failed to Discover Devices, Error: ${e}`);
|
|
443
|
+
await this.debugErrorLog(`Failed to Discover Devices, Error: ${e.message ?? e}`);
|
|
542
444
|
}
|
|
543
445
|
}
|
|
544
446
|
}
|
|
@@ -565,8 +467,8 @@ export class SwitchBotPlatform {
|
|
|
565
467
|
await this.errorLog('Neither SwitchBot Token or Device Config are set.');
|
|
566
468
|
}
|
|
567
469
|
}
|
|
568
|
-
isSuccessfulResponse(
|
|
569
|
-
return (
|
|
470
|
+
isSuccessfulResponse(apiStatusCode) {
|
|
471
|
+
return (apiStatusCode === 200 || apiStatusCode === 100);
|
|
570
472
|
}
|
|
571
473
|
async handleDevices(deviceLists) {
|
|
572
474
|
if (!this.config.options?.devices) {
|
|
@@ -631,11 +533,10 @@ export class SwitchBotPlatform {
|
|
|
631
533
|
return { ...matchingItem, ...itm };
|
|
632
534
|
});
|
|
633
535
|
}
|
|
634
|
-
async handleErrorResponse(
|
|
635
|
-
await this.statusCode(statusCode);
|
|
536
|
+
async handleErrorResponse(apiStatusCode, retryCount, maxRetries, delayBetweenRetries) {
|
|
636
537
|
await this.statusCode(apiStatusCode);
|
|
637
|
-
if (
|
|
638
|
-
this.infoLog(`statusCode: ${
|
|
538
|
+
if (apiStatusCode === 500) {
|
|
539
|
+
this.infoLog(`statusCode: ${apiStatusCode} Attempt ${retryCount + 1} of ${maxRetries}`);
|
|
639
540
|
await sleep(delayBetweenRetries);
|
|
640
541
|
}
|
|
641
542
|
}
|
|
@@ -1299,7 +1200,7 @@ export class SwitchBotPlatform {
|
|
|
1299
1200
|
}
|
|
1300
1201
|
else if (await this.registerDevice(device)) {
|
|
1301
1202
|
if (isBlindTiltDevice(device)) {
|
|
1302
|
-
if (device.group && !device.
|
|
1203
|
+
if (device.group && !device.disable_group) {
|
|
1303
1204
|
this.debugLog('Your Curtains are grouped, '
|
|
1304
1205
|
+ `, Secondary curtain automatically hidden. Main Curtain: ${device.deviceName}, deviceId: ${device.deviceId}`);
|
|
1305
1206
|
}
|
|
@@ -1373,7 +1274,7 @@ export class SwitchBotPlatform {
|
|
|
1373
1274
|
}
|
|
1374
1275
|
else if (await this.registerDevice(device)) {
|
|
1375
1276
|
if (isCurtainDevice(device)) {
|
|
1376
|
-
if (device.group && !device.
|
|
1277
|
+
if (device.group && !device.disable_group) {
|
|
1377
1278
|
this.debugLog('Your Curtains are grouped, '
|
|
1378
1279
|
+ `, Secondary curtain automatically hidden. Main Curtain: ${device.deviceName}, deviceId: ${device.deviceId}`);
|
|
1379
1280
|
}
|
|
@@ -1901,7 +1802,7 @@ export class SwitchBotPlatform {
|
|
|
1901
1802
|
? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
|
|
1902
1803
|
: await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
|
|
1903
1804
|
accessory.context.connectionType = await this.connectionType(device);
|
|
1904
|
-
accessory.context.version = device.firmware ??
|
|
1805
|
+
accessory.context.version = device.firmware ?? this.version ?? '0.0.0';
|
|
1905
1806
|
const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
|
|
1906
1807
|
await this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`);
|
|
1907
1808
|
// create the accessory handler for the newly create accessory
|
|
@@ -1958,7 +1859,7 @@ export class SwitchBotPlatform {
|
|
|
1958
1859
|
? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
|
|
1959
1860
|
: await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
|
|
1960
1861
|
accessory.context.connectionType = await this.connectionType(device);
|
|
1961
|
-
accessory.context.version = device.firmware ??
|
|
1862
|
+
accessory.context.version = device.firmware ?? this.version ?? '0.0.0';
|
|
1962
1863
|
const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
|
|
1963
1864
|
await this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`);
|
|
1964
1865
|
// create the accessory handler for the newly create accessory
|
|
@@ -2016,7 +1917,7 @@ export class SwitchBotPlatform {
|
|
|
2016
1917
|
? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
|
|
2017
1918
|
: await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
|
|
2018
1919
|
accessory.context.connectionType = await this.connectionType(device);
|
|
2019
|
-
accessory.context.version = device.firmware ??
|
|
1920
|
+
accessory.context.version = device.firmware ?? this.version ?? '0.0.0';
|
|
2020
1921
|
const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
|
|
2021
1922
|
await this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`);
|
|
2022
1923
|
// create the accessory handler for the newly create accessory
|
|
@@ -2074,7 +1975,7 @@ export class SwitchBotPlatform {
|
|
|
2074
1975
|
? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
|
|
2075
1976
|
: await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
|
|
2076
1977
|
accessory.context.connectionType = await this.connectionType(device);
|
|
2077
|
-
accessory.context.version = device.firmware ??
|
|
1978
|
+
accessory.context.version = device.firmware ?? this.version ?? '0.0.0';
|
|
2078
1979
|
const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
|
|
2079
1980
|
await this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`);
|
|
2080
1981
|
// create the accessory handler for the newly create accessory
|
|
@@ -2132,7 +2033,7 @@ export class SwitchBotPlatform {
|
|
|
2132
2033
|
? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
|
|
2133
2034
|
: await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
|
|
2134
2035
|
accessory.context.connectionType = await this.connectionType(device);
|
|
2135
|
-
accessory.context.version = device.firmware ??
|
|
2036
|
+
accessory.context.version = device.firmware ?? this.version ?? '0.0.0';
|
|
2136
2037
|
const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
|
|
2137
2038
|
await this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`);
|
|
2138
2039
|
// create the accessory handler for the newly create accessory
|
|
@@ -2190,7 +2091,7 @@ export class SwitchBotPlatform {
|
|
|
2190
2091
|
? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
|
|
2191
2092
|
: await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
|
|
2192
2093
|
accessory.context.connectionType = await this.connectionType(device);
|
|
2193
|
-
accessory.context.version = device.firmware ??
|
|
2094
|
+
accessory.context.version = device.firmware ?? this.version ?? '0.0.0';
|
|
2194
2095
|
const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
|
|
2195
2096
|
await this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`);
|
|
2196
2097
|
// create the accessory handler for the newly create accessory
|
|
@@ -2248,7 +2149,7 @@ export class SwitchBotPlatform {
|
|
|
2248
2149
|
? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
|
|
2249
2150
|
: await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
|
|
2250
2151
|
accessory.context.connectionType = await this.connectionType(device);
|
|
2251
|
-
accessory.context.version = device.firmware ??
|
|
2152
|
+
accessory.context.version = device.firmware ?? this.version ?? '0.0.0';
|
|
2252
2153
|
const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
|
|
2253
2154
|
await this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`);
|
|
2254
2155
|
// create the accessory handler for the newly create accessory
|
|
@@ -2306,7 +2207,7 @@ export class SwitchBotPlatform {
|
|
|
2306
2207
|
? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
|
|
2307
2208
|
: await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
|
|
2308
2209
|
accessory.context.connectionType = await this.connectionType(device);
|
|
2309
|
-
accessory.context.version = device.firmware ??
|
|
2210
|
+
accessory.context.version = device.firmware ?? this.version ?? '0.0.0';
|
|
2310
2211
|
const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
|
|
2311
2212
|
await this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`);
|
|
2312
2213
|
// create the accessory handler for the newly create accessory
|
|
@@ -2364,7 +2265,7 @@ export class SwitchBotPlatform {
|
|
|
2364
2265
|
? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
|
|
2365
2266
|
: await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
|
|
2366
2267
|
accessory.context.connectionType = await this.connectionType(device);
|
|
2367
|
-
accessory.context.version = device.firmware ??
|
|
2268
|
+
accessory.context.version = device.firmware ?? this.version ?? '0.0.0';
|
|
2368
2269
|
const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
|
|
2369
2270
|
await this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`);
|
|
2370
2271
|
// create the accessory handler for the newly create accessory
|
|
@@ -2382,11 +2283,11 @@ export class SwitchBotPlatform {
|
|
|
2382
2283
|
async registerCurtains(device) {
|
|
2383
2284
|
let registerWindowCovering;
|
|
2384
2285
|
if (isCurtainDevice(device)) {
|
|
2385
|
-
await this.debugWarnLog(`deviceName: ${device.deviceName} deviceId: ${device.deviceId}, curtainDevicesIds: ${device.curtainDevicesIds},x master: ${device.master}, group: ${device.group}, disable_group: ${device.
|
|
2286
|
+
await this.debugWarnLog(`deviceName: ${device.deviceName} deviceId: ${device.deviceId}, curtainDevicesIds: ${device.curtainDevicesIds},x master: ${device.master}, group: ${device.group}, disable_group: ${device.disable_group}, connectionType: ${device.connectionType}`);
|
|
2386
2287
|
registerWindowCovering = await this.registerWindowCovering(device);
|
|
2387
2288
|
}
|
|
2388
2289
|
else if (isBlindTiltDevice(device)) {
|
|
2389
|
-
await this.debugWarnLog(`deviceName: ${device.deviceName} deviceId: ${device.deviceId}, blindTiltDevicesIds: ${device.blindTiltDevicesIds}, master: ${device.master}, group: ${device.group}, disable_group: ${device.
|
|
2290
|
+
await this.debugWarnLog(`deviceName: ${device.deviceName} deviceId: ${device.deviceId}, blindTiltDevicesIds: ${device.blindTiltDevicesIds}, master: ${device.master}, group: ${device.group}, disable_group: ${device.disable_group}, connectionType: ${device.connectionType}`);
|
|
2390
2291
|
registerWindowCovering = await this.registerWindowCovering(device);
|
|
2391
2292
|
}
|
|
2392
2293
|
else {
|
|
@@ -2403,11 +2304,9 @@ export class SwitchBotPlatform {
|
|
|
2403
2304
|
await this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master}, device.group: ${device.group} connectionType; ${device.connectionType}`);
|
|
2404
2305
|
await this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`);
|
|
2405
2306
|
}
|
|
2406
|
-
else if (!device.master && device.
|
|
2407
|
-
// !device.group && device.connectionType === 'BLE'
|
|
2408
|
-
// OpenAPI: Non-Master Curtains/Blind Tilts that has Disable Grouping Checked
|
|
2307
|
+
else if (!device.master && device.disable_group) {
|
|
2409
2308
|
registerCurtain = true;
|
|
2410
|
-
await this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master}, disable_group: ${device.
|
|
2309
|
+
await this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master}, disable_group: ${device.disable_group}, connectionType; ${device.connectionType}`);
|
|
2411
2310
|
await this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`);
|
|
2412
2311
|
}
|
|
2413
2312
|
else if (device.master && !device.group) {
|
|
@@ -2424,7 +2323,7 @@ export class SwitchBotPlatform {
|
|
|
2424
2323
|
}
|
|
2425
2324
|
else {
|
|
2426
2325
|
registerCurtain = false;
|
|
2427
|
-
await this.debugErrorLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] disable_group: ${device.
|
|
2326
|
+
await this.debugErrorLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] disable_group: ${device.disable_group}, device.master: ${device.master}, device.group: ${device.group}`);
|
|
2428
2327
|
await this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}, device.connectionType: ${device.connectionType}`);
|
|
2429
2328
|
}
|
|
2430
2329
|
return registerCurtain;
|
|
@@ -2531,19 +2430,15 @@ export class SwitchBotPlatform {
|
|
|
2531
2430
|
await this.errorLog(message);
|
|
2532
2431
|
}
|
|
2533
2432
|
}
|
|
2534
|
-
async retryRequest(deviceMaxRetries, deviceDelayBetweenRetries
|
|
2433
|
+
async retryRequest(deviceId, deviceMaxRetries, deviceDelayBetweenRetries) {
|
|
2535
2434
|
let retryCount = 0;
|
|
2536
2435
|
const maxRetries = deviceMaxRetries;
|
|
2537
2436
|
const delayBetweenRetries = deviceDelayBetweenRetries;
|
|
2538
2437
|
while (retryCount < maxRetries) {
|
|
2539
2438
|
try {
|
|
2540
|
-
const {
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
}
|
|
2544
|
-
else {
|
|
2545
|
-
await this.debugLog(`Received status code: ${statusCode}`);
|
|
2546
|
-
}
|
|
2439
|
+
const { response, statusCode } = await this.switchBotAPI.getDeviceStatus(deviceId);
|
|
2440
|
+
await this.debugLog(`response: ${JSON.stringify(response)}`);
|
|
2441
|
+
return { response, statusCode };
|
|
2547
2442
|
}
|
|
2548
2443
|
catch (error) {
|
|
2549
2444
|
await this.errorLog(`Error making request: ${error.message}`);
|
|
@@ -2552,18 +2447,17 @@ export class SwitchBotPlatform {
|
|
|
2552
2447
|
await this.debugLog(`Retry attempt ${retryCount} of ${maxRetries}`);
|
|
2553
2448
|
await sleep(delayBetweenRetries);
|
|
2554
2449
|
}
|
|
2555
|
-
return {
|
|
2450
|
+
return { response: null, statusCode: 500 };
|
|
2556
2451
|
}
|
|
2557
2452
|
// BLE Connection
|
|
2558
2453
|
async connectBLE(accessory, device) {
|
|
2559
2454
|
try {
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
return switchbot;
|
|
2455
|
+
queueScheduler.schedule(async () => this.switchBotBLE);
|
|
2456
|
+
await this.debugLog(`${device.deviceType}: ${accessory.displayName} 'node-switchbot' found: ${this.switchBotBLE}`);
|
|
2457
|
+
return this.switchBotBLE;
|
|
2564
2458
|
}
|
|
2565
2459
|
catch (e) {
|
|
2566
|
-
await this.errorLog(`${device.deviceType}: ${accessory.displayName} 'node-switchbot' not found, Error: ${e}`);
|
|
2460
|
+
await this.errorLog(`${device.deviceType}: ${accessory.displayName} 'node-switchbot' not found, Error: ${e.message ?? e}`);
|
|
2567
2461
|
return false;
|
|
2568
2462
|
}
|
|
2569
2463
|
}
|