node-switchbot 1.1.3-beta.3 → 1.1.3-beta.4

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