node-switchbot 1.10.0 → 2.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/.gitattributes +2 -0
- package/.github/dependabot.yml +17 -0
- package/.github/labeler.yml +38 -0
- package/.github/npm-version-script.cjs +81 -0
- package/.github/workflows/beta-release.yml +31 -0
- package/.github/workflows/build.yml +18 -0
- package/.github/workflows/changerelease.yml +13 -0
- package/.github/workflows/dependabot.yml +17 -0
- package/.github/workflows/labeler.yml +16 -0
- package/.github/workflows/release-drafter.yml +14 -0
- package/.github/workflows/release.yml +24 -0
- package/.github/workflows/stale.yml +12 -0
- package/CHANGELOG.md +308 -0
- package/dist/advertising.d.ts +172 -0
- package/dist/advertising.d.ts.map +1 -0
- package/dist/advertising.js +620 -0
- package/dist/advertising.js.map +1 -0
- package/dist/device/woblindtilt.d.ts +9 -0
- package/dist/device/woblindtilt.d.ts.map +1 -0
- package/dist/device/woblindtilt.js +108 -0
- package/dist/device/woblindtilt.js.map +1 -0
- package/dist/device/wobulb.d.ts +39 -0
- package/dist/device/wobulb.d.ts.map +1 -0
- package/dist/device/wobulb.js +156 -0
- package/dist/device/wobulb.js.map +1 -0
- package/dist/device/wocontact.d.ts +4 -0
- package/dist/device/wocontact.d.ts.map +1 -0
- package/dist/device/wocontact.js +8 -0
- package/dist/device/wocontact.js.map +1 -0
- package/dist/device/wocurtain.d.ts +9 -0
- package/dist/device/wocurtain.d.ts.map +1 -0
- package/dist/device/wocurtain.js +104 -0
- package/dist/device/wocurtain.js.map +1 -0
- package/dist/device/wohand.d.ts +10 -0
- package/dist/device/wohand.d.ts.map +1 -0
- package/dist/device/wohand.js +93 -0
- package/dist/device/wohand.js.map +1 -0
- package/dist/device/wohumi.d.ts +10 -0
- package/dist/device/wohumi.d.ts.map +1 -0
- package/dist/device/wohumi.js +93 -0
- package/dist/device/wohumi.js.map +1 -0
- package/dist/device/woiosensorth.d.ts +4 -0
- package/dist/device/woiosensorth.d.ts.map +1 -0
- package/dist/device/woiosensorth.js +4 -0
- package/dist/device/woiosensorth.js.map +1 -0
- package/dist/device/woplugmini.d.ts +31 -0
- package/dist/device/woplugmini.d.ts.map +1 -0
- package/dist/device/woplugmini.js +68 -0
- package/dist/device/woplugmini.js.map +1 -0
- package/dist/device/wopresence.d.ts +4 -0
- package/dist/device/wopresence.d.ts.map +1 -0
- package/dist/device/wopresence.js +4 -0
- package/dist/device/wopresence.js.map +1 -0
- package/dist/device/wosensorth.d.ts +4 -0
- package/dist/device/wosensorth.d.ts.map +1 -0
- package/dist/device/wosensorth.js +4 -0
- package/dist/device/wosensorth.js.map +1 -0
- package/dist/device/wostrip.d.ts +39 -0
- package/dist/device/wostrip.d.ts.map +1 -0
- package/dist/device/wostrip.js +145 -0
- package/dist/device/wostrip.js.map +1 -0
- package/dist/device.d.ts +46 -0
- package/dist/device.d.ts.map +1 -0
- package/dist/device.js +498 -0
- package/dist/device.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/parameter-checker.d.ts +25 -0
- package/dist/parameter-checker.d.ts.map +1 -0
- package/dist/parameter-checker.js +488 -0
- package/dist/parameter-checker.js.map +1 -0
- package/dist/switchbot.d.ts +29 -0
- package/dist/switchbot.d.ts.map +1 -0
- package/dist/switchbot.js +461 -0
- package/dist/switchbot.js.map +1 -0
- package/package.json +19 -12
- package/lib/parameter-checker.js +0 -524
- package/lib/switchbot-advertising.js +0 -713
- package/lib/switchbot-device-woblindtilt.js +0 -120
- package/lib/switchbot-device-wobulb.js +0 -188
- package/lib/switchbot-device-wocontact.js +0 -6
- package/lib/switchbot-device-wocurtain.js +0 -117
- package/lib/switchbot-device-wohand.js +0 -106
- package/lib/switchbot-device-wohumi.js +0 -106
- package/lib/switchbot-device-woiosensorth.js +0 -6
- package/lib/switchbot-device-woplugmini.js +0 -84
- package/lib/switchbot-device-wopresence.js +0 -6
- package/lib/switchbot-device-wosensorth.js +0 -6
- package/lib/switchbot-device-wostrip.js +0 -182
- package/lib/switchbot-device.js +0 -536
- package/lib/switchbot.js +0 -496
package/lib/switchbot-device.js
DELETED
|
@@ -1,536 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const { Buffer } = require('buffer');
|
|
4
|
-
|
|
5
|
-
const parameterChecker = require("./parameter-checker.js");
|
|
6
|
-
const switchbotAdvertising = require("./switchbot-advertising.js");
|
|
7
|
-
|
|
8
|
-
class SwitchbotDevice {
|
|
9
|
-
/* ------------------------------------------------------------------
|
|
10
|
-
* Constructor
|
|
11
|
-
*
|
|
12
|
-
* [Arguments]
|
|
13
|
-
* - peripheral | Object | Required | The `peripheral` object of noble,
|
|
14
|
-
* | | | which represents this device
|
|
15
|
-
* - noble | Noble | Required | The Noble object created by the noble module.
|
|
16
|
-
* ---------------------------------------------------------------- */
|
|
17
|
-
constructor(peripheral, noble) {
|
|
18
|
-
this._peripheral = peripheral;
|
|
19
|
-
this._noble = noble;
|
|
20
|
-
this._chars = null;
|
|
21
|
-
|
|
22
|
-
this._SERV_UUID_PRIMARY = "cba20d00224d11e69fb80002a5d5c51b";
|
|
23
|
-
this._CHAR_UUID_WRITE = "cba20002224d11e69fb80002a5d5c51b";
|
|
24
|
-
this._CHAR_UUID_NOTIFY = "cba20003224d11e69fb80002a5d5c51b";
|
|
25
|
-
this._CHAR_UUID_DEVICE = "2a00";
|
|
26
|
-
|
|
27
|
-
this._READ_TIMEOUT_MSEC = 3000;
|
|
28
|
-
this._WRITE_TIMEOUT_MSEC = 3000;
|
|
29
|
-
this._COMMAND_TIMEOUT_MSEC = 3000;
|
|
30
|
-
|
|
31
|
-
// Save the device information
|
|
32
|
-
const ad = switchbotAdvertising.parse(peripheral);
|
|
33
|
-
this._id = ad.id;
|
|
34
|
-
this._address = ad.address;
|
|
35
|
-
this._model = ad.serviceData.model;
|
|
36
|
-
this._modelName = ad.serviceData.modelName;
|
|
37
|
-
|
|
38
|
-
this._was_connected_explicitly = false;
|
|
39
|
-
this._connected = false;
|
|
40
|
-
|
|
41
|
-
this._onconnect = () => {};
|
|
42
|
-
this._ondisconnect = () => {};
|
|
43
|
-
this._ondisconnect_internal = () => {};
|
|
44
|
-
this._onnotify_internal = () => {};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Getters
|
|
48
|
-
get id() {
|
|
49
|
-
return this._id;
|
|
50
|
-
}
|
|
51
|
-
get address() {
|
|
52
|
-
return this._address;
|
|
53
|
-
}
|
|
54
|
-
get model() {
|
|
55
|
-
return this._model;
|
|
56
|
-
}
|
|
57
|
-
get modelName() {
|
|
58
|
-
return this._modelName;
|
|
59
|
-
}
|
|
60
|
-
get connectionState() {
|
|
61
|
-
if (!this._connected && this._peripheral.state === "disconnecting") {
|
|
62
|
-
return "disconnected";
|
|
63
|
-
} else {
|
|
64
|
-
return this._peripheral.state;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Setters
|
|
69
|
-
set onconnect(func) {
|
|
70
|
-
if (!func || typeof func !== "function") {
|
|
71
|
-
throw new Error("The `onconnect` must be a function.");
|
|
72
|
-
}
|
|
73
|
-
this._onconnect = func;
|
|
74
|
-
}
|
|
75
|
-
set ondisconnect(func) {
|
|
76
|
-
if (!func || typeof func !== "function") {
|
|
77
|
-
throw new Error("The `ondisconnect` must be a function.");
|
|
78
|
-
}
|
|
79
|
-
this._ondisconnect = func;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/* ------------------------------------------------------------------
|
|
83
|
-
* connect()
|
|
84
|
-
* - Connect the device
|
|
85
|
-
*
|
|
86
|
-
* [Arguments]
|
|
87
|
-
* - none
|
|
88
|
-
*
|
|
89
|
-
* [Return value]
|
|
90
|
-
* - Promise object
|
|
91
|
-
* Nothing will be passed to the `resolve()`.
|
|
92
|
-
* ---------------------------------------------------------------- */
|
|
93
|
-
connect() {
|
|
94
|
-
this._was_connected_explicitly = true;
|
|
95
|
-
return this._connect();
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
_connect() {
|
|
99
|
-
return new Promise((resolve, reject) => {
|
|
100
|
-
// Check the bluetooth state
|
|
101
|
-
if (this._noble.state !== "poweredOn") {
|
|
102
|
-
reject(
|
|
103
|
-
new Error(
|
|
104
|
-
"The Bluetooth status is " + this._noble.state + ", not poweredOn."
|
|
105
|
-
)
|
|
106
|
-
);
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Check the connection state
|
|
111
|
-
const state = this.connectionState;
|
|
112
|
-
if (state === "connected") {
|
|
113
|
-
resolve();
|
|
114
|
-
return;
|
|
115
|
-
} else if (state === "connecting" || state === "disconnecting") {
|
|
116
|
-
reject(
|
|
117
|
-
new Error("Now " + state + ". Wait for a few seconds then try again.")
|
|
118
|
-
);
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Set event handlers for events fired on the `Peripheral` object
|
|
123
|
-
this._peripheral.once("connect", () => {
|
|
124
|
-
this._connected = true;
|
|
125
|
-
this._onconnect();
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
this._peripheral.once("disconnect", () => {
|
|
129
|
-
this._connected = false;
|
|
130
|
-
this._chars = null;
|
|
131
|
-
this._peripheral.removeAllListeners();
|
|
132
|
-
this._ondisconnect_internal();
|
|
133
|
-
this._ondisconnect();
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
// Connect
|
|
137
|
-
this._peripheral.connect((error) => {
|
|
138
|
-
if (error) {
|
|
139
|
-
reject(error);
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
this._getCharacteristics()
|
|
143
|
-
.then((chars) => {
|
|
144
|
-
this._chars = chars;
|
|
145
|
-
return this._subscribe();
|
|
146
|
-
})
|
|
147
|
-
.then(() => {
|
|
148
|
-
resolve();
|
|
149
|
-
})
|
|
150
|
-
.catch((error) => {
|
|
151
|
-
this._peripheral.disconnect();
|
|
152
|
-
reject(error);
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
_getCharacteristics() {
|
|
159
|
-
return new Promise((resolve, reject) => {
|
|
160
|
-
// Set timeout timer
|
|
161
|
-
let timer = setTimeout(() => {
|
|
162
|
-
this._ondisconnect_internal = () => {};
|
|
163
|
-
timer = null;
|
|
164
|
-
reject(
|
|
165
|
-
new Error("Failed to discover services and characteristics: TIMEOUT")
|
|
166
|
-
);
|
|
167
|
-
}, 5000);
|
|
168
|
-
|
|
169
|
-
// Watch the connection state
|
|
170
|
-
this._ondisconnect_internal = () => {
|
|
171
|
-
if (timer) {
|
|
172
|
-
clearTimeout(timer);
|
|
173
|
-
timer = null;
|
|
174
|
-
this._ondisconnect_internal = () => {};
|
|
175
|
-
}
|
|
176
|
-
reject(
|
|
177
|
-
new Error(
|
|
178
|
-
"Failed to discover services and characteristics: DISCONNECTED"
|
|
179
|
-
)
|
|
180
|
-
);
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
// Discover services and characteristics
|
|
184
|
-
(async () => {
|
|
185
|
-
const service_list = await this._discoverServices();
|
|
186
|
-
if (!timer) {
|
|
187
|
-
throw new Error("");
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
const chars = {
|
|
191
|
-
write: null,
|
|
192
|
-
notify: null,
|
|
193
|
-
device: null,
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
for (let service of service_list) {
|
|
197
|
-
const char_list = await this._discoverCharacteristics(service);
|
|
198
|
-
for (let char of char_list) {
|
|
199
|
-
if (char.uuid === this._CHAR_UUID_WRITE) {
|
|
200
|
-
chars.write = char;
|
|
201
|
-
} else if (char.uuid === this._CHAR_UUID_NOTIFY) {
|
|
202
|
-
chars.notify = char;
|
|
203
|
-
} else if (char.uuid === this._CHAR_UUID_DEVICE) {
|
|
204
|
-
// Some models of Bot don't seem to support this characteristic UUID
|
|
205
|
-
chars.device = char;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (chars.write && chars.notify) {
|
|
211
|
-
resolve(chars);
|
|
212
|
-
} else {
|
|
213
|
-
reject(new Error("No characteristic was found."));
|
|
214
|
-
}
|
|
215
|
-
})().catch((error) => {
|
|
216
|
-
if (timer) {
|
|
217
|
-
clearTimeout(timer);
|
|
218
|
-
timer = null;
|
|
219
|
-
this._ondisconnect_internal = () => {};
|
|
220
|
-
reject(error);
|
|
221
|
-
} else {
|
|
222
|
-
// Do nothing
|
|
223
|
-
}
|
|
224
|
-
});
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
_discoverServices() {
|
|
229
|
-
return new Promise((resolve, reject) => {
|
|
230
|
-
this._peripheral.discoverServices([], (error, service_list) => {
|
|
231
|
-
if (error) {
|
|
232
|
-
reject(error);
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
let service = null;
|
|
237
|
-
for (let s of service_list) {
|
|
238
|
-
if (s.uuid === this._SERV_UUID_PRIMARY) {
|
|
239
|
-
service = s;
|
|
240
|
-
break;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
if (service) {
|
|
244
|
-
resolve(service_list);
|
|
245
|
-
} else {
|
|
246
|
-
reject(new Error("No service was found."));
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
_discoverCharacteristics(service) {
|
|
253
|
-
return new Promise((resolve, reject) => {
|
|
254
|
-
service.discoverCharacteristics([], (error, char_list) => {
|
|
255
|
-
if (error) {
|
|
256
|
-
reject(error);
|
|
257
|
-
} else {
|
|
258
|
-
resolve(char_list);
|
|
259
|
-
}
|
|
260
|
-
});
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
_subscribe() {
|
|
265
|
-
return new Promise((resolve, reject) => {
|
|
266
|
-
const char = this._chars.notify;
|
|
267
|
-
if (!char) {
|
|
268
|
-
reject(new Error("No notify characteristic was found."));
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
271
|
-
char.subscribe((error) => {
|
|
272
|
-
if (error) {
|
|
273
|
-
reject(error);
|
|
274
|
-
return;
|
|
275
|
-
}
|
|
276
|
-
char.on("data", (buf) => {
|
|
277
|
-
this._onnotify_internal(buf);
|
|
278
|
-
});
|
|
279
|
-
resolve();
|
|
280
|
-
});
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
_unsubscribe() {
|
|
285
|
-
return new Promise((resolve) => {
|
|
286
|
-
const char = this._chars.notify;
|
|
287
|
-
if (!char) {
|
|
288
|
-
resolve();
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
|
-
char.removeAllListeners();
|
|
292
|
-
char.unsubscribe(() => {
|
|
293
|
-
resolve();
|
|
294
|
-
});
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
/* ------------------------------------------------------------------
|
|
299
|
-
* disconnect()
|
|
300
|
-
* - Disconnect the device
|
|
301
|
-
*
|
|
302
|
-
* [Arguments]
|
|
303
|
-
* - none
|
|
304
|
-
*
|
|
305
|
-
* [Return value]
|
|
306
|
-
* - Promise object
|
|
307
|
-
* Nothing will be passed to the `resolve()`.
|
|
308
|
-
* ---------------------------------------------------------------- */
|
|
309
|
-
disconnect() {
|
|
310
|
-
return new Promise((resolve, reject) => {
|
|
311
|
-
this._was_connected_explicitly = false;
|
|
312
|
-
// Check the connection state
|
|
313
|
-
const state = this._peripheral.state;
|
|
314
|
-
if (state === "disconnected") {
|
|
315
|
-
resolve();
|
|
316
|
-
return;
|
|
317
|
-
} else if (state === "connecting" || state === "disconnecting") {
|
|
318
|
-
reject(
|
|
319
|
-
new Error("Now " + state + ". Wait for a few seconds then try again.")
|
|
320
|
-
);
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
// Unsubscribe
|
|
325
|
-
this._unsubscribe().then(() => {
|
|
326
|
-
// Disconnect
|
|
327
|
-
this._peripheral.disconnect(() => {
|
|
328
|
-
resolve();
|
|
329
|
-
});
|
|
330
|
-
});
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
_disconnect() {
|
|
335
|
-
if (this._was_connected_explicitly) {
|
|
336
|
-
return new Promise((resolve) => {
|
|
337
|
-
resolve();
|
|
338
|
-
});
|
|
339
|
-
} else {
|
|
340
|
-
return this.disconnect();
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
/* ------------------------------------------------------------------
|
|
345
|
-
* getDeviceName()
|
|
346
|
-
* - Retrieve the device name
|
|
347
|
-
*
|
|
348
|
-
* [Arguments]
|
|
349
|
-
* - none
|
|
350
|
-
*
|
|
351
|
-
* [Return value]
|
|
352
|
-
* - Promise object
|
|
353
|
-
* The device name will be passed to the `resolve()`.
|
|
354
|
-
* ---------------------------------------------------------------- */
|
|
355
|
-
getDeviceName() {
|
|
356
|
-
return new Promise((resolve, reject) => {
|
|
357
|
-
let name = "";
|
|
358
|
-
this._connect()
|
|
359
|
-
.then(() => {
|
|
360
|
-
if (!this._chars.device) {
|
|
361
|
-
// Some models of Bot don't seem to support this characteristic UUID
|
|
362
|
-
throw new Error(
|
|
363
|
-
"The device does not support the characteristic UUID 0x" +
|
|
364
|
-
this._CHAR_UUID_DEVICE +
|
|
365
|
-
"."
|
|
366
|
-
);
|
|
367
|
-
}
|
|
368
|
-
return this._read(this._chars.device);
|
|
369
|
-
})
|
|
370
|
-
.then((buf) => {
|
|
371
|
-
name = buf.toString("utf8");
|
|
372
|
-
return this._disconnect();
|
|
373
|
-
})
|
|
374
|
-
.then(() => {
|
|
375
|
-
resolve(name);
|
|
376
|
-
})
|
|
377
|
-
.catch((error) => {
|
|
378
|
-
reject(error);
|
|
379
|
-
});
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
/* ------------------------------------------------------------------
|
|
384
|
-
* setDeviceName(name)
|
|
385
|
-
* - Set the device name
|
|
386
|
-
*
|
|
387
|
-
* [Arguments]
|
|
388
|
-
* - name | String | Required | Device name. The bytes length of the name
|
|
389
|
-
* | | | must be in the range of 1 to 20 bytes.
|
|
390
|
-
*
|
|
391
|
-
* [Return value]
|
|
392
|
-
* - Promise object
|
|
393
|
-
* Nothing will be passed to the `resolve()`.
|
|
394
|
-
* ---------------------------------------------------------------- */
|
|
395
|
-
setDeviceName(name) {
|
|
396
|
-
return new Promise((resolve, reject) => {
|
|
397
|
-
// Check the parameters
|
|
398
|
-
const valid = parameterChecker.check(
|
|
399
|
-
{ name: name },
|
|
400
|
-
{
|
|
401
|
-
name: { required: true, type: "string", minBytes: 1, maxBytes: 100 },
|
|
402
|
-
}
|
|
403
|
-
);
|
|
404
|
-
|
|
405
|
-
if (!valid) {
|
|
406
|
-
reject(new Error(parameterChecker.error.message));
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
const buf = Buffer.from(name, "utf8");
|
|
411
|
-
this._connect()
|
|
412
|
-
.then(() => {
|
|
413
|
-
if (!this._chars.device) {
|
|
414
|
-
// Some models of Bot don't seem to support this characteristic UUID
|
|
415
|
-
throw new Error(
|
|
416
|
-
"The device does not support the characteristic UUID 0x" +
|
|
417
|
-
this._CHAR_UUID_DEVICE +
|
|
418
|
-
"."
|
|
419
|
-
);
|
|
420
|
-
}
|
|
421
|
-
return this._write(this._chars.device, buf);
|
|
422
|
-
})
|
|
423
|
-
.then(() => {
|
|
424
|
-
return this._disconnect();
|
|
425
|
-
})
|
|
426
|
-
.then(() => {
|
|
427
|
-
resolve();
|
|
428
|
-
})
|
|
429
|
-
.catch((error) => {
|
|
430
|
-
reject(error);
|
|
431
|
-
});
|
|
432
|
-
});
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
// Write the specified Buffer data to the write characteristic
|
|
436
|
-
// and receive the response from the notify characteristic
|
|
437
|
-
// with connection handling
|
|
438
|
-
_command(req_buf) {
|
|
439
|
-
return new Promise((resolve, reject) => {
|
|
440
|
-
if (!Buffer.isBuffer(req_buf)) {
|
|
441
|
-
reject(new Error("The specified data is not acceptable for writing."));
|
|
442
|
-
return;
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
let res_buf = null;
|
|
446
|
-
|
|
447
|
-
this._connect()
|
|
448
|
-
.then(() => {
|
|
449
|
-
if (!this._chars) {
|
|
450
|
-
return reject(new Error("No characteristics available."));
|
|
451
|
-
}
|
|
452
|
-
return this._write(this._chars.write, req_buf);
|
|
453
|
-
})
|
|
454
|
-
.then(() => {
|
|
455
|
-
return this._waitCommandResponse();
|
|
456
|
-
})
|
|
457
|
-
.then((buf) => {
|
|
458
|
-
res_buf = buf;
|
|
459
|
-
return this._disconnect();
|
|
460
|
-
})
|
|
461
|
-
.then(() => {
|
|
462
|
-
resolve(res_buf);
|
|
463
|
-
})
|
|
464
|
-
.catch((error) => {
|
|
465
|
-
reject(error);
|
|
466
|
-
});
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
_waitCommandResponse() {
|
|
471
|
-
return new Promise((resolve, reject) => {
|
|
472
|
-
let timer = setTimeout(() => {
|
|
473
|
-
timer = null;
|
|
474
|
-
this._onnotify_internal = () => {};
|
|
475
|
-
reject(new Error("COMMAND_TIMEOUT"));
|
|
476
|
-
}, this._COMMAND_TIMEOUT_MSEC);
|
|
477
|
-
|
|
478
|
-
this._onnotify_internal = (buf) => {
|
|
479
|
-
if (timer) {
|
|
480
|
-
clearTimeout(timer);
|
|
481
|
-
timer = null;
|
|
482
|
-
}
|
|
483
|
-
this._onnotify_internal = () => {};
|
|
484
|
-
resolve(buf);
|
|
485
|
-
};
|
|
486
|
-
});
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
// Read data from the specified characteristic
|
|
490
|
-
_read(char) {
|
|
491
|
-
return new Promise((resolve, reject) => {
|
|
492
|
-
// Set a timeout timer
|
|
493
|
-
let timer = setTimeout(() => {
|
|
494
|
-
reject("READ_TIMEOUT");
|
|
495
|
-
}, this._READ_TIMEOUT_MSEC);
|
|
496
|
-
|
|
497
|
-
// Read charcteristic data
|
|
498
|
-
char.read((error, buf) => {
|
|
499
|
-
if (timer) {
|
|
500
|
-
clearTimeout(timer);
|
|
501
|
-
timer = null;
|
|
502
|
-
}
|
|
503
|
-
if (error) {
|
|
504
|
-
reject(error);
|
|
505
|
-
} else {
|
|
506
|
-
resolve(buf);
|
|
507
|
-
}
|
|
508
|
-
});
|
|
509
|
-
});
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
// Write the specified Buffer data to the specified characteristic
|
|
513
|
-
_write(char, buf) {
|
|
514
|
-
return new Promise((resolve, reject) => {
|
|
515
|
-
// Set a timeout timer
|
|
516
|
-
let timer = setTimeout(() => {
|
|
517
|
-
reject("WRITE_TIMEOUT");
|
|
518
|
-
}, this._WRITE_TIMEOUT_MSEC);
|
|
519
|
-
|
|
520
|
-
// write charcteristic data
|
|
521
|
-
char.write(buf, false, (error) => {
|
|
522
|
-
if (timer) {
|
|
523
|
-
clearTimeout(timer);
|
|
524
|
-
timer = null;
|
|
525
|
-
}
|
|
526
|
-
if (error) {
|
|
527
|
-
reject(error);
|
|
528
|
-
} else {
|
|
529
|
-
resolve();
|
|
530
|
-
}
|
|
531
|
-
});
|
|
532
|
-
});
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
module.exports = SwitchbotDevice;
|