node-switchbot 1.8.1-beta.6 → 1.8.1-beta.8
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/README.md +15 -15
- package/lib/parameter-checker.js +7 -7
- package/lib/switchbot-advertising.js +169 -169
- package/lib/switchbot-device-wobulb.js +6 -6
- package/lib/switchbot-device-wocontact.js +1 -1
- package/lib/switchbot-device-wocurtain.js +3 -3
- package/lib/switchbot-device-wohand.js +3 -3
- package/lib/switchbot-device-wohumi.js +3 -3
- package/lib/switchbot-device-woplugmini.js +6 -6
- package/lib/switchbot-device-wopresence.js +1 -1
- package/lib/switchbot-device-wosensorth.js +1 -1
- package/lib/switchbot-device-wostrip.js +6 -6
- package/lib/switchbot-device.js +14 -14
- package/lib/switchbot.js +30 -34
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -110,9 +110,9 @@ Monitoring the advertising packets, you can find your devices and know the lates
|
|
|
110
110
|
|
|
111
111
|
```JavaScript
|
|
112
112
|
// Load the node-switchbot and get a `Switchbot` constructor object
|
|
113
|
-
|
|
113
|
+
const Switchbot = require('node-switchbot');
|
|
114
114
|
// Create an `Switchbot` object
|
|
115
|
-
|
|
115
|
+
const switchbot = new Switchbot();
|
|
116
116
|
|
|
117
117
|
(async () => {
|
|
118
118
|
// Start to monitor advertisement packets
|
|
@@ -137,9 +137,9 @@ The [`startScan()`](#startscan-method) and [`wait()`](#Switchbot-wait-method) me
|
|
|
137
137
|
|
|
138
138
|
```javascript
|
|
139
139
|
// Load the node-switchbot and get a `Switchbot` constructor object
|
|
140
|
-
|
|
140
|
+
const Switchbot = require("node-switchbot");
|
|
141
141
|
// Create an `Switchbot` object
|
|
142
|
-
|
|
142
|
+
const switchbot = new Switchbot();
|
|
143
143
|
|
|
144
144
|
// Start to monitor advertisement packets
|
|
145
145
|
switchbot
|
|
@@ -213,18 +213,18 @@ This sample discovers a Bot (WoHand), then put the Bot's arm down, finally put i
|
|
|
213
213
|
|
|
214
214
|
```javascript
|
|
215
215
|
// Load the node-switchbot and get a `Switchbot` constructor object
|
|
216
|
-
|
|
216
|
+
const Switchbot = require("node-switchbot");
|
|
217
217
|
// Create an `Switchbot` object
|
|
218
|
-
|
|
218
|
+
const switchbot = new Switchbot();
|
|
219
219
|
|
|
220
220
|
(async () => {
|
|
221
221
|
// Find a Bot (WoHand)
|
|
222
|
-
|
|
222
|
+
const bot_list = await switchbot.discover({ model: "H", quick: true });
|
|
223
223
|
if (bot_list.length === 0) {
|
|
224
224
|
throw new Error("No device was found.");
|
|
225
225
|
}
|
|
226
226
|
// The `SwitchbotDeviceWoHand` object representing the found Bot.
|
|
227
|
-
|
|
227
|
+
const device = bot_list[0];
|
|
228
228
|
// Put the Bot's arm down (stretch the arm)
|
|
229
229
|
await device.down();
|
|
230
230
|
// Wait for 5 seconds
|
|
@@ -246,13 +246,13 @@ In this code, you can get a [`SwitchbotDeviceWoHand`](#SwitchbotDeviceWoHand-obj
|
|
|
246
246
|
In order to use the node-switchbot, you have to load the node-switchbot module as follows:
|
|
247
247
|
|
|
248
248
|
```JavaScript
|
|
249
|
-
|
|
249
|
+
const Switchbot = require('node-switchbot');
|
|
250
250
|
```
|
|
251
251
|
|
|
252
252
|
You can get an `Switchbot` constructor from the code above. Then you have to create an `Switchbot` object from the `Switchbot` constructor as follows:
|
|
253
253
|
|
|
254
254
|
```javascript
|
|
255
|
-
|
|
255
|
+
const switchbot = new Switchbot();
|
|
256
256
|
```
|
|
257
257
|
|
|
258
258
|
The `Switchbot` constructor takes an argument optionally. It must be a hash object containing the properties as follows:
|
|
@@ -263,15 +263,15 @@ The `Switchbot` constructor takes an argument optionally. It must be a hash obje
|
|
|
263
263
|
|
|
264
264
|
The node-switchbot module uses the [`@abandonware/noble`](https://github.com/abandonware/noble) module in order to interact with BLE devices. If you want to interact other BLE devices using the `@abandonware/noble` module, you can create an `Noble` object by yourself, then pass it to this module. If you don't specify a `Noble` object to the `noble` property, this module automatically create a `Noble` object internally.
|
|
265
265
|
|
|
266
|
-
The sample code below shows how to pass a `
|
|
266
|
+
The sample code below shows how to pass a `Noble` object to the `Switchbot` constructor.
|
|
267
267
|
|
|
268
268
|
```JavaScript
|
|
269
269
|
// Create a Noble object
|
|
270
|
-
|
|
270
|
+
const noble = require('@abandonware/noble');
|
|
271
271
|
|
|
272
272
|
// Create a Switchbot object
|
|
273
|
-
|
|
274
|
-
|
|
273
|
+
const Switchbot = require('node-switchbot');
|
|
274
|
+
const switchbot = new Switchbot({'noble': noble});
|
|
275
275
|
```
|
|
276
276
|
|
|
277
277
|
In the code snippet above, the variable `switchbot` is an `Switchbot` object. The `Switchbot` object has a lot of methods as described in sections below.
|
|
@@ -565,7 +565,7 @@ The code below calls the [`press()`](#SwitchbotDeviceWoHand-press-method) method
|
|
|
565
565
|
switchbot
|
|
566
566
|
.discover({ model: "H", quick: true })
|
|
567
567
|
.then((device_list) => {
|
|
568
|
-
|
|
568
|
+
const device = device_list[0];
|
|
569
569
|
if (!device) {
|
|
570
570
|
console.log("No device was found.");
|
|
571
571
|
process.exit();
|
package/lib/parameter-checker.js
CHANGED
|
@@ -37,7 +37,7 @@ class ParameterChecker {
|
|
|
37
37
|
* an `Error` object will be set to `this._error`.
|
|
38
38
|
*
|
|
39
39
|
* [Usage]
|
|
40
|
-
*
|
|
40
|
+
* const valid = parameterChecker.check(params, {
|
|
41
41
|
* level: {
|
|
42
42
|
* required: false,
|
|
43
43
|
* type: 'integer',
|
|
@@ -50,7 +50,7 @@ class ParameterChecker {
|
|
|
50
50
|
* }
|
|
51
51
|
* });
|
|
52
52
|
* if(!valid) {
|
|
53
|
-
*
|
|
53
|
+
* const e = parameterChecker.error.message;
|
|
54
54
|
* throw new Error(message);
|
|
55
55
|
* }
|
|
56
56
|
* ---------------------------------------------------------------- */
|
|
@@ -79,11 +79,11 @@ class ParameterChecker {
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
let result = true;
|
|
82
|
-
|
|
82
|
+
const name_list = Object.keys(rules);
|
|
83
83
|
|
|
84
84
|
for (let i = 0; i < name_list.length; i++) {
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
const name = name_list[i];
|
|
86
|
+
const v = obj[name];
|
|
87
87
|
let rule = rules[name];
|
|
88
88
|
|
|
89
89
|
if (!rule) {
|
|
@@ -458,7 +458,7 @@ class ParameterChecker {
|
|
|
458
458
|
}
|
|
459
459
|
}
|
|
460
460
|
if (typeof rule.minBytes === "number") {
|
|
461
|
-
|
|
461
|
+
const blen = Buffer.from(value, "utf8").length;
|
|
462
462
|
if (blen < rule.minBytes) {
|
|
463
463
|
this._error = {
|
|
464
464
|
code: "LENGTH_UNDERFLOW",
|
|
@@ -475,7 +475,7 @@ class ParameterChecker {
|
|
|
475
475
|
}
|
|
476
476
|
}
|
|
477
477
|
if (typeof rule.maxBytes === "number") {
|
|
478
|
-
|
|
478
|
+
const blen = Buffer.from(value, "utf8").length;
|
|
479
479
|
if (blen > rule.maxBytes) {
|
|
480
480
|
this._error = {
|
|
481
481
|
code: "LENGTH_OVERFLOW",
|
|
@@ -61,16 +61,16 @@ class SwitchbotAdvertising {
|
|
|
61
61
|
* device, this method will return `null`.
|
|
62
62
|
* ---------------------------------------------------------------- */
|
|
63
63
|
parse(peripheral, onlog) {
|
|
64
|
-
|
|
64
|
+
const ad = peripheral.advertisement;
|
|
65
65
|
if (!ad || !ad.serviceData) {
|
|
66
66
|
return null;
|
|
67
67
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
const serviceData = ad.serviceData[0] || ad.serviceData;
|
|
69
|
+
const manufacturerData = ad.manufacturerData;
|
|
70
|
+
const buf = serviceData.data;
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
const bufIsInvalid = !buf || !Buffer.isBuffer(buf) || buf.length < 3;
|
|
73
|
+
const manufacturerDataIsInvalid =
|
|
74
74
|
!manufacturerData ||
|
|
75
75
|
!Buffer.isBuffer(manufacturerData) ||
|
|
76
76
|
manufacturerData.length < 3;
|
|
@@ -79,7 +79,7 @@ class SwitchbotAdvertising {
|
|
|
79
79
|
return null;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
const model = buf.slice(0, 1).toString("utf8");
|
|
83
83
|
let sd = null;
|
|
84
84
|
|
|
85
85
|
if (model === "H") {
|
|
@@ -129,7 +129,7 @@ class SwitchbotAdvertising {
|
|
|
129
129
|
if (address === "") {
|
|
130
130
|
address = peripheral.advertisement.manufacturerData || "";
|
|
131
131
|
if (address !== "") {
|
|
132
|
-
|
|
132
|
+
const str = peripheral.advertisement.manufacturerData
|
|
133
133
|
.toString("hex")
|
|
134
134
|
.slice(4, 16);
|
|
135
135
|
address = str.substr(0, 2);
|
|
@@ -141,7 +141,7 @@ class SwitchbotAdvertising {
|
|
|
141
141
|
} else {
|
|
142
142
|
address = address.replace(/-/g, ":");
|
|
143
143
|
}
|
|
144
|
-
|
|
144
|
+
const data = {
|
|
145
145
|
id: peripheral.id,
|
|
146
146
|
address: address,
|
|
147
147
|
rssi: peripheral.rssi,
|
|
@@ -167,14 +167,14 @@ class SwitchbotAdvertising {
|
|
|
167
167
|
}
|
|
168
168
|
return null;
|
|
169
169
|
}
|
|
170
|
-
|
|
171
|
-
|
|
170
|
+
const byte1 = buf.readUInt8(1);
|
|
171
|
+
const byte2 = buf.readUInt8(2);
|
|
172
172
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
173
|
+
const mode = byte1 & 0b10000000 ? true : false; // Whether the light switch Add-on is used or not
|
|
174
|
+
const state = byte1 & 0b01000000 ? true : false; // Whether the switch status is ON or OFF
|
|
175
|
+
const battery = byte2 & 0b01111111; // %
|
|
176
176
|
|
|
177
|
-
|
|
177
|
+
const data = {
|
|
178
178
|
model: "H",
|
|
179
179
|
modelName: "WoHand",
|
|
180
180
|
mode: mode,
|
|
@@ -194,17 +194,17 @@ class SwitchbotAdvertising {
|
|
|
194
194
|
}
|
|
195
195
|
return null;
|
|
196
196
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
197
|
+
const byte2 = buf.readUInt8(2);
|
|
198
|
+
const byte3 = buf.readUInt8(3);
|
|
199
|
+
const byte4 = buf.readUInt8(4);
|
|
200
|
+
const byte5 = buf.readUInt8(5);
|
|
201
|
+
|
|
202
|
+
const temp_sign = byte4 & 0b10000000 ? 1 : -1;
|
|
203
|
+
const temp_c = temp_sign * ((byte4 & 0b01111111) + (byte3 & 0b00001111) / 10);
|
|
204
|
+
const temp_f = (temp_c * 9 / 5) + 32;
|
|
205
205
|
temp_f = Math.round(temp_f * 10) / 10;
|
|
206
206
|
|
|
207
|
-
|
|
207
|
+
const data = {
|
|
208
208
|
model: "T",
|
|
209
209
|
modelName: "WoSensorTH",
|
|
210
210
|
temperature: {
|
|
@@ -228,15 +228,15 @@ class SwitchbotAdvertising {
|
|
|
228
228
|
}
|
|
229
229
|
return null;
|
|
230
230
|
}
|
|
231
|
-
|
|
232
|
-
|
|
231
|
+
const byte1 = buf.readUInt8(1);
|
|
232
|
+
const byte4 = buf.readUInt8(4);
|
|
233
233
|
|
|
234
234
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
235
|
+
const onState = byte1 & 0b10000000 ? true : false; // 1 - on
|
|
236
|
+
const autoMode = byte4 & 0b10000000 ? true : false; // 1 - auto
|
|
237
|
+
const percentage = byte4 & 0b01111111; // 0-100%, 101/102/103 - Quick gear 1/2/3
|
|
238
238
|
|
|
239
|
-
|
|
239
|
+
const data = {
|
|
240
240
|
model: "e",
|
|
241
241
|
modelName: "WoHumi",
|
|
242
242
|
onState: onState,
|
|
@@ -257,20 +257,20 @@ class SwitchbotAdvertising {
|
|
|
257
257
|
return null;
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
260
|
+
const byte1 = buf.readUInt8(1);
|
|
261
|
+
const byte2 = buf.readUInt8(2);
|
|
262
|
+
const byte5 = buf.readUInt8(5);
|
|
263
263
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
264
|
+
const tested = byte1 & 0b10000000 ? true : false;
|
|
265
|
+
const movement = byte1 & 0b01000000 ? true : false;
|
|
266
|
+
const battery = byte2 & 0b01111111;
|
|
267
|
+
const led = (byte5 & 0b00100000) >> 5;
|
|
268
|
+
const iot = (byte5 & 0b00010000) >> 4;
|
|
269
|
+
const sense_distance = (byte5 & 0b00001100) >> 2;
|
|
270
|
+
const lightLevel = byte5 & 0b00000011;
|
|
271
|
+
const is_light = byte5 & 0b00000010 ? true : false;
|
|
272
272
|
|
|
273
|
-
|
|
273
|
+
const data = {
|
|
274
274
|
model: "s",
|
|
275
275
|
modelName: "WoMotion",
|
|
276
276
|
tested: tested,
|
|
@@ -297,21 +297,21 @@ class SwitchbotAdvertising {
|
|
|
297
297
|
return null;
|
|
298
298
|
}
|
|
299
299
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
300
|
+
const byte1 = buf.readUInt8(1);
|
|
301
|
+
const byte2 = buf.readUInt8(2);
|
|
302
|
+
const byte3 = buf.readUInt8(3);
|
|
303
|
+
const byte8 = buf.readUInt8(8);
|
|
304
|
+
|
|
305
|
+
const hallState = (byte3 >> 1) & 0b00000011;
|
|
306
|
+
const tested = byte1 & 0b10000000;
|
|
307
|
+
const movement = byte1 & 0b01000000 ? true : false; // 1 - Movement detected
|
|
308
|
+
const battery = byte2 & 0b01111111; // %
|
|
309
|
+
const contact_open = byte3 & 0b00000010 == 0b00000010;
|
|
310
|
+
const contact_timeout = byte3 & 0b00000100 == 0b00000100;
|
|
311
|
+
const lightLevel = byte3 & 0b00000001;
|
|
312
|
+
const button_count = byte8 & 0b00001111;
|
|
313
|
+
|
|
314
|
+
const data = {
|
|
315
315
|
model: "d",
|
|
316
316
|
modelName: "WoContact",
|
|
317
317
|
movement: movement,
|
|
@@ -341,19 +341,19 @@ class SwitchbotAdvertising {
|
|
|
341
341
|
}
|
|
342
342
|
return null;
|
|
343
343
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
344
|
+
const byte1 = buf.readUInt8(1);
|
|
345
|
+
const byte2 = buf.readUInt8(2);
|
|
346
|
+
const byte3 = buf.readUInt8(3);
|
|
347
|
+
const byte4 = buf.readUInt8(4);
|
|
348
|
+
|
|
349
|
+
const calibration = byte1 & 0b01000000 ? true : false; // Whether the calibration is compconsted
|
|
350
|
+
const battery = byte2 & 0b01111111; // %
|
|
351
|
+
const inMotion = byte3 & 0b10000000 ? true : false;
|
|
352
|
+
const currPosition = byte3 & 0b01111111; // current positon %
|
|
353
|
+
const lightLevel = (byte4 >> 4) & 0b00001111; // light sensor level (1-10)
|
|
354
|
+
const deviceChain = byte4 & 0b00000111;
|
|
355
|
+
|
|
356
|
+
const data = {
|
|
357
357
|
model: "c",
|
|
358
358
|
modelName: "WoCurtain",
|
|
359
359
|
calibration: calibration,
|
|
@@ -407,31 +407,31 @@ class SwitchbotAdvertising {
|
|
|
407
407
|
}
|
|
408
408
|
return null;
|
|
409
409
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
410
|
+
const byte1 = manufacturerData.readUInt8(1);//power and light status
|
|
411
|
+
const byte2 = manufacturerData.readUInt8(2);//bulb brightness
|
|
412
|
+
const byte3 = manufacturerData.readUInt8(3);//bulb R
|
|
413
|
+
const byte4 = manufacturerData.readUInt8(4);//bulb G
|
|
414
|
+
const byte5 = manufacturerData.readUInt8(5);//bulb B
|
|
415
|
+
const byte6 = manufacturerData.readUInt8(6);//bulb temperature
|
|
416
|
+
const byte7 = manufacturerData.readUInt8(7);
|
|
417
|
+
const byte8 = manufacturerData.readUInt8(8);
|
|
418
|
+
const byte9 = manufacturerData.readUInt8(9);
|
|
419
|
+
const byte10 = manufacturerData.readUInt8(10);//bulb mode
|
|
420
|
+
|
|
421
|
+
const power = byte1;
|
|
422
|
+
const red = byte3;
|
|
423
|
+
const green = byte4;
|
|
424
|
+
const blue = byte5;
|
|
425
|
+
const color_temperature = byte6;
|
|
426
|
+
const state = byte7 & 0b01111111 ? true : false;
|
|
427
|
+
const brightness = byte7 & 0b01111111;
|
|
428
|
+
const delay = byte8 & 0b10000000;
|
|
429
|
+
const preset = byte8 & 0b00001000;
|
|
430
|
+
const color_mode = byte8 & 0b00000111;
|
|
431
|
+
const speed = byte9 & 0b01111111;
|
|
432
|
+
const loop_index = byte10 & 0b11111110;
|
|
433
|
+
|
|
434
|
+
const data = {
|
|
435
435
|
model: "u",
|
|
436
436
|
modelName: "WoBulb",
|
|
437
437
|
color_temperature: color_temperature,
|
|
@@ -460,22 +460,22 @@ class SwitchbotAdvertising {
|
|
|
460
460
|
}
|
|
461
461
|
return null;
|
|
462
462
|
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
463
|
+
const byte9 = manufacturerData.readUInt8(9); // byte9: plug mini state; 0x00=off, 0x80=on
|
|
464
|
+
const byte10 = manufacturerData.readUInt8(10); // byte10: bit0: 0=no delay,1=delay, bit1:0=no timer, 1=timer; bit2:0=no sync time, 1=sync'ed time
|
|
465
|
+
const byte11 = manufacturerData.readUInt8(11); // byte11: wifi rssi
|
|
466
|
+
const byte12 = manufacturerData.readUInt8(12); // byte12: bit7: overload?
|
|
467
|
+
const byte13 = manufacturerData.readUInt8(13); // byte12[bit0~6] + byte13: current power value
|
|
468
|
+
|
|
469
|
+
const state = byte9 === 0x00 ? "off" : byte9 === 0x80 ? "on" : null;
|
|
470
|
+
const delay = !!(byte10 & 0b00000001);
|
|
471
|
+
const timer = !!(byte10 & 0b00000010);
|
|
472
|
+
const syncUtcTime = !!(byte10 & 0b00000100);
|
|
473
|
+
const wifiRssi = byte11;
|
|
474
|
+
const overload = !!(byte12 & 0b10000000);
|
|
475
|
+
const currentPower = (((byte12 & 0b01111111) << 8) + byte13) / 10; // in watt
|
|
476
476
|
// TODO: voltage ???
|
|
477
477
|
|
|
478
|
-
|
|
478
|
+
const data = {
|
|
479
479
|
model: "g",
|
|
480
480
|
modelName: "WoPlugMini",
|
|
481
481
|
state: state,
|
|
@@ -499,22 +499,22 @@ class SwitchbotAdvertising {
|
|
|
499
499
|
}
|
|
500
500
|
return null;
|
|
501
501
|
}
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
502
|
+
const byte9 = manufacturerData.readUInt8(9); // byte9: plug mini state; 0x00=off, 0x80=on
|
|
503
|
+
const byte10 = manufacturerData.readUInt8(10); // byte10: bit0: 0=no delay,1=delay, bit1:0=no timer, 1=timer; bit2:0=no sync time, 1=sync'ed time
|
|
504
|
+
const byte11 = manufacturerData.readUInt8(11); // byte11: wifi rssi
|
|
505
|
+
const byte12 = manufacturerData.readUInt8(12); // byte12: bit7: overload?
|
|
506
|
+
const byte13 = manufacturerData.readUInt8(13); // byte12[bit0~6] + byte13: current power value
|
|
507
|
+
|
|
508
|
+
const state = byte9 === 0x00 ? "off" : byte9 === 0x80 ? "on" : null;
|
|
509
|
+
const delay = !!(byte10 & 0b00000001);
|
|
510
|
+
const timer = !!(byte10 & 0b00000010);
|
|
511
|
+
const syncUtcTime = !!(byte10 & 0b00000100);
|
|
512
|
+
const wifiRssi = byte11;
|
|
513
|
+
const overload = !!(byte12 & 0b10000000);
|
|
514
|
+
const currentPower = (((byte12 & 0b01111111) << 8) + byte13) / 10; // in watt
|
|
515
515
|
// TODO: voltage ???
|
|
516
516
|
|
|
517
|
-
|
|
517
|
+
const data = {
|
|
518
518
|
model: "j",
|
|
519
519
|
modelName: "WoPlugMini",
|
|
520
520
|
state: state,
|
|
@@ -538,12 +538,12 @@ class SwitchbotAdvertising {
|
|
|
538
538
|
}
|
|
539
539
|
return null;
|
|
540
540
|
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
541
|
+
const byte2 = manufacturerData.readUInt8(2);
|
|
542
|
+
const byte7 = manufacturerData.readUInt8(7);
|
|
543
|
+
const byte8 = manufacturerData.readUInt8(8);
|
|
544
544
|
|
|
545
545
|
|
|
546
|
-
|
|
546
|
+
const LockStatus = {
|
|
547
547
|
LOCKED: 0b0000000,
|
|
548
548
|
UNLOCKED: 0b0010000,
|
|
549
549
|
LOCKING: 0b0100000,
|
|
@@ -553,17 +553,17 @@ class SwitchbotAdvertising {
|
|
|
553
553
|
NOT_FULLY_LOCKED: 0b1100000, //Only EU lock type
|
|
554
554
|
}
|
|
555
555
|
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
556
|
+
const battery = byte2 & 0b01111111; // %
|
|
557
|
+
const calibration = byte7 & 0b10000000 ? true : false;
|
|
558
|
+
const status = LockStatus(byte7 & 0b01110000);
|
|
559
|
+
const update_from_secondary_lock = byte7 & 0b00001000 ? true : false;
|
|
560
|
+
const door_open = byte7 & 0b00000100 ? true : false;
|
|
561
|
+
const double_lock_mode = byte8 & 0b10000000 ? true : false;
|
|
562
|
+
const unclosed_alarm = byte8 & 0b00100000 ? true : false;
|
|
563
|
+
const unlocked_alarm = byte8 & 0b00010000 ? true : false;
|
|
564
|
+
const auto_lock_paused = byte8 & 0b00000010 ? true : false;
|
|
565
|
+
|
|
566
|
+
const data = {
|
|
567
567
|
model: "o",
|
|
568
568
|
modelName: "WoSmartLock",
|
|
569
569
|
battery: battery,
|
|
@@ -589,17 +589,17 @@ class SwitchbotAdvertising {
|
|
|
589
589
|
}
|
|
590
590
|
return null;
|
|
591
591
|
}
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
592
|
+
const byte2 = buf.readUInt8(2);
|
|
593
|
+
const byte3 = buf.readUInt8(3);
|
|
594
|
+
const byte4 = buf.readUInt8(4);
|
|
595
|
+
const byte5 = buf.readUInt8(5);
|
|
596
|
+
|
|
597
|
+
const temp_sign = byte4 & 0b10000000 ? 1 : -1;
|
|
598
|
+
const temp_c = temp_sign * ((byte4 & 0b01111111) + (byte3 & 0b00001111) / 10);
|
|
599
|
+
const temp_f = (temp_c * 9 / 5) + 32;
|
|
600
600
|
temp_f = Math.round(temp_f * 10) / 10;
|
|
601
601
|
|
|
602
|
-
|
|
602
|
+
const data = {
|
|
603
603
|
model: "i",
|
|
604
604
|
modelName: "WoSensorTHPlus",
|
|
605
605
|
temperature: {
|
|
@@ -624,28 +624,28 @@ class SwitchbotAdvertising {
|
|
|
624
624
|
return null;
|
|
625
625
|
}
|
|
626
626
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
627
|
+
const byte1 = buf.readUInt8(1);//power and light status
|
|
628
|
+
const byte2 = buf.readUInt8(2);//bulb brightness
|
|
629
|
+
const byte3 = buf.readUInt8(3);//bulb R
|
|
630
|
+
const byte4 = buf.readUInt8(4);//bulb G
|
|
631
|
+
const byte5 = buf.readUInt8(5);//bulb B
|
|
632
|
+
const byte7 = buf.readUInt8(7);
|
|
633
|
+
const byte8 = buf.readUInt8(8);
|
|
634
|
+
const byte9 = buf.readUInt8(9);
|
|
635
|
+
const byte10 = buf.readUInt8(10);
|
|
636
|
+
|
|
637
|
+
const state = byte7 & 0b10000000 ? true : false;
|
|
638
|
+
const brightness = byte7 & 0b01111111;
|
|
639
|
+
const red = byte3;
|
|
640
|
+
const green = byte4;
|
|
641
|
+
const blue = byte5;
|
|
642
|
+
const delay = byte8 & 0b10000000;
|
|
643
|
+
const preset = byte8 & 0b00001000;
|
|
644
|
+
const color_mode = byte8 & 0b00000111;
|
|
645
|
+
const speed = byte9 & 0b01111111;
|
|
646
|
+
const loop_index = byte10 & 0b11111110;
|
|
647
|
+
|
|
648
|
+
const data = {
|
|
649
649
|
model: "r",
|
|
650
650
|
modelName: "WoStrip",
|
|
651
651
|
state: state,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
2
|
+
const SwitchbotDevice = require("./switchbot-device.js");
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/colorbulb.md
|
|
@@ -16,7 +16,7 @@ class SwitchbotDeviceWoBulb extends SwitchbotDevice {
|
|
|
16
16
|
* @private
|
|
17
17
|
*/
|
|
18
18
|
_setState(reqByteArray) {
|
|
19
|
-
|
|
19
|
+
const base = [0x57, 0x0f, 0x47, 0x01];
|
|
20
20
|
return this._operateBot([].concat(base, reqByteArray));
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -149,15 +149,15 @@ class SwitchbotDeviceWoBulb extends SwitchbotDevice {
|
|
|
149
149
|
* @private
|
|
150
150
|
*/
|
|
151
151
|
_operateBot(bytes) {
|
|
152
|
-
|
|
152
|
+
const req_buf = Buffer.from(bytes);
|
|
153
153
|
return new Promise((resolve, reject) => {
|
|
154
154
|
this._command(req_buf)
|
|
155
155
|
.then((res_bytes) => {
|
|
156
|
-
|
|
156
|
+
const res_buf = Buffer.from(res_bytes);
|
|
157
157
|
if (res_buf.length === 2) {
|
|
158
|
-
|
|
158
|
+
const code = res_buf.readUInt8(1);
|
|
159
159
|
if (code === 0x00 || code === 0x80) {
|
|
160
|
-
|
|
160
|
+
const is_on = code === 0x80;
|
|
161
161
|
resolve(is_on);
|
|
162
162
|
} else {
|
|
163
163
|
reject(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
2
|
+
const SwitchbotDevice = require("./switchbot-device.js");
|
|
3
3
|
|
|
4
4
|
class SwitchbotDeviceWoCurtain extends SwitchbotDevice {
|
|
5
5
|
/* ------------------------------------------------------------------
|
|
@@ -93,10 +93,10 @@ class SwitchbotDeviceWoCurtain extends SwitchbotDevice {
|
|
|
93
93
|
|
|
94
94
|
_operateCurtain(bytes) {
|
|
95
95
|
return new Promise((resolve, reject) => {
|
|
96
|
-
|
|
96
|
+
const req_buf = Buffer.from(bytes);
|
|
97
97
|
this._command(req_buf)
|
|
98
98
|
.then((res_buf) => {
|
|
99
|
-
|
|
99
|
+
const code = res_buf.readUInt8(0);
|
|
100
100
|
if (res_buf.length === 3 && code === 0x01) {
|
|
101
101
|
resolve();
|
|
102
102
|
} else {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
2
|
+
const SwitchbotDevice = require("./switchbot-device.js");
|
|
3
3
|
|
|
4
4
|
class SwitchbotDeviceWoHand extends SwitchbotDevice {
|
|
5
5
|
/* ------------------------------------------------------------------
|
|
@@ -79,10 +79,10 @@ class SwitchbotDeviceWoHand extends SwitchbotDevice {
|
|
|
79
79
|
|
|
80
80
|
_operateBot(bytes) {
|
|
81
81
|
return new Promise((resolve, reject) => {
|
|
82
|
-
|
|
82
|
+
const req_buf = Buffer.from(bytes);
|
|
83
83
|
this._command(req_buf)
|
|
84
84
|
.then((res_buf) => {
|
|
85
|
-
|
|
85
|
+
const code = res_buf.readUInt8(0);
|
|
86
86
|
if (res_buf.length === 3 && (code === 0x01 || code === 0x05)) {
|
|
87
87
|
resolve();
|
|
88
88
|
} else {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
2
|
+
const SwitchbotDevice = require("./switchbot-device.js");
|
|
3
3
|
|
|
4
4
|
class SwitchbotDeviceWoHumi extends SwitchbotDevice {
|
|
5
5
|
/* ------------------------------------------------------------------
|
|
@@ -79,10 +79,10 @@ class SwitchbotDeviceWoHumi extends SwitchbotDevice {
|
|
|
79
79
|
|
|
80
80
|
_operateBot(bytes) {
|
|
81
81
|
return new Promise((resolve, reject) => {
|
|
82
|
-
|
|
82
|
+
const req_buf = Buffer.from(bytes);
|
|
83
83
|
this._command(req_buf)
|
|
84
84
|
.then((res_buf) => {
|
|
85
|
-
|
|
85
|
+
const code = res_buf.readUInt8(0);
|
|
86
86
|
if (res_buf.length === 3 && (code === 0x01 || code === 0x05)) {
|
|
87
87
|
resolve();
|
|
88
88
|
} else {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
2
|
+
const SwitchbotDevice = require("./switchbot-device.js");
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/plugmini.md
|
|
@@ -16,7 +16,7 @@ class SwitchbotDeviceWoPlugMini extends SwitchbotDevice {
|
|
|
16
16
|
* @private
|
|
17
17
|
*/
|
|
18
18
|
_setState(reqByteArray) {
|
|
19
|
-
|
|
19
|
+
const base = [0x57, 0x0f, 0x50, 0x01];
|
|
20
20
|
return this._operateBot([].concat(base, reqByteArray));
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -45,15 +45,15 @@ class SwitchbotDeviceWoPlugMini extends SwitchbotDevice {
|
|
|
45
45
|
* @private
|
|
46
46
|
*/
|
|
47
47
|
_operateBot(bytes) {
|
|
48
|
-
|
|
48
|
+
const req_buf = Buffer.from(bytes);
|
|
49
49
|
return new Promise((resolve, reject) => {
|
|
50
50
|
this._command(req_buf)
|
|
51
51
|
.then((res_bytes) => {
|
|
52
|
-
|
|
52
|
+
const res_buf = Buffer.from(res_bytes);
|
|
53
53
|
if (res_buf.length === 2) {
|
|
54
|
-
|
|
54
|
+
const code = res_buf.readUInt8(1);
|
|
55
55
|
if (code === 0x00 || code === 0x80) {
|
|
56
|
-
|
|
56
|
+
const is_on = code === 0x80;
|
|
57
57
|
resolve(is_on);
|
|
58
58
|
} else {
|
|
59
59
|
reject(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
2
|
+
const SwitchbotDevice = require("./switchbot-device.js");
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/colorbulb.md
|
|
@@ -16,7 +16,7 @@ class SwitchbotDeviceWoStrip extends SwitchbotDevice {
|
|
|
16
16
|
* @private
|
|
17
17
|
*/
|
|
18
18
|
_setState(reqByteArray) {
|
|
19
|
-
|
|
19
|
+
const base = [0x57, 0x0f, 0x49, 0x01];
|
|
20
20
|
return this._operateBot([].concat(base, reqByteArray));
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -143,15 +143,15 @@ class SwitchbotDeviceWoStrip extends SwitchbotDevice {
|
|
|
143
143
|
* @private
|
|
144
144
|
*/
|
|
145
145
|
_operateBot(bytes) {
|
|
146
|
-
|
|
146
|
+
const req_buf = Buffer.from(bytes);
|
|
147
147
|
return new Promise((resolve, reject) => {
|
|
148
148
|
this._command(req_buf)
|
|
149
149
|
.then((res_bytes) => {
|
|
150
|
-
|
|
150
|
+
const res_buf = Buffer.from(res_bytes);
|
|
151
151
|
if (res_buf.length === 2) {
|
|
152
|
-
|
|
152
|
+
const code = res_buf.readUInt8(1);
|
|
153
153
|
if (code === 0x00 || code === 0x80) {
|
|
154
|
-
|
|
154
|
+
const is_on = code === 0x80;
|
|
155
155
|
resolve(is_on);
|
|
156
156
|
} else {
|
|
157
157
|
reject(
|
package/lib/switchbot-device.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
const parameterChecker = require("./parameter-checker.js");
|
|
3
|
+
const switchbotAdvertising = require("./switchbot-advertising.js");
|
|
4
4
|
|
|
5
5
|
class SwitchbotDevice {
|
|
6
6
|
/* ------------------------------------------------------------------
|
|
@@ -9,7 +9,7 @@ class SwitchbotDevice {
|
|
|
9
9
|
* [Arguments]
|
|
10
10
|
* - peripheral | Object | Required | The `peripheral` object of noble,
|
|
11
11
|
* | | | which represents this device
|
|
12
|
-
* - noble | Noble | Required | The
|
|
12
|
+
* - noble | Noble | Required | The Noble object created by the noble module.
|
|
13
13
|
* ---------------------------------------------------------------- */
|
|
14
14
|
constructor(peripheral, noble) {
|
|
15
15
|
this._peripheral = peripheral;
|
|
@@ -26,7 +26,7 @@ class SwitchbotDevice {
|
|
|
26
26
|
this._COMMAND_TIMEOUT_MSEC = 3000;
|
|
27
27
|
|
|
28
28
|
// Save the device information
|
|
29
|
-
|
|
29
|
+
const ad = switchbotAdvertising.parse(peripheral);
|
|
30
30
|
this._id = ad.id;
|
|
31
31
|
this._address = ad.address;
|
|
32
32
|
this._model = ad.serviceData.model;
|
|
@@ -105,7 +105,7 @@ class SwitchbotDevice {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
// Check the connection state
|
|
108
|
-
|
|
108
|
+
const state = this.connectionState;
|
|
109
109
|
if (state === "connected") {
|
|
110
110
|
resolve();
|
|
111
111
|
return;
|
|
@@ -179,19 +179,19 @@ class SwitchbotDevice {
|
|
|
179
179
|
|
|
180
180
|
// Discover services and characteristics
|
|
181
181
|
(async () => {
|
|
182
|
-
|
|
182
|
+
const service_list = await this._discoverServices();
|
|
183
183
|
if (!timer) {
|
|
184
184
|
throw new Error("");
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
|
|
187
|
+
const chars = {
|
|
188
188
|
write: null,
|
|
189
189
|
notify: null,
|
|
190
190
|
device: null,
|
|
191
191
|
};
|
|
192
192
|
|
|
193
193
|
for (let service of service_list) {
|
|
194
|
-
|
|
194
|
+
const char_list = await this._discoverCharacteristics(service);
|
|
195
195
|
for (let char of char_list) {
|
|
196
196
|
if (char.uuid === this._CHAR_UUID_WRITE) {
|
|
197
197
|
chars.write = char;
|
|
@@ -260,7 +260,7 @@ class SwitchbotDevice {
|
|
|
260
260
|
|
|
261
261
|
_subscribe() {
|
|
262
262
|
return new Promise((resolve, reject) => {
|
|
263
|
-
|
|
263
|
+
const char = this._chars.notify;
|
|
264
264
|
if (!char) {
|
|
265
265
|
reject(new Error("No notify characteristic was found."));
|
|
266
266
|
return;
|
|
@@ -280,7 +280,7 @@ class SwitchbotDevice {
|
|
|
280
280
|
|
|
281
281
|
_unsubscribe() {
|
|
282
282
|
return new Promise((resolve) => {
|
|
283
|
-
|
|
283
|
+
const char = this._chars.notify;
|
|
284
284
|
if (!char) {
|
|
285
285
|
resolve();
|
|
286
286
|
return;
|
|
@@ -307,7 +307,7 @@ class SwitchbotDevice {
|
|
|
307
307
|
return new Promise((resolve, reject) => {
|
|
308
308
|
this._was_connected_explicitly = false;
|
|
309
309
|
// Check the connection state
|
|
310
|
-
|
|
310
|
+
const state = this._peripheral.state;
|
|
311
311
|
if (state === "disconnected") {
|
|
312
312
|
resolve();
|
|
313
313
|
return;
|
|
@@ -351,7 +351,7 @@ class SwitchbotDevice {
|
|
|
351
351
|
* ---------------------------------------------------------------- */
|
|
352
352
|
getDeviceName() {
|
|
353
353
|
return new Promise((resolve, reject) => {
|
|
354
|
-
|
|
354
|
+
const name = "";
|
|
355
355
|
this._connect()
|
|
356
356
|
.then(() => {
|
|
357
357
|
if (!this._chars.device) {
|
|
@@ -392,7 +392,7 @@ class SwitchbotDevice {
|
|
|
392
392
|
setDeviceName(name) {
|
|
393
393
|
return new Promise((resolve, reject) => {
|
|
394
394
|
// Check the parameters
|
|
395
|
-
|
|
395
|
+
const valid = parameterChecker.check(
|
|
396
396
|
{ name: name },
|
|
397
397
|
{
|
|
398
398
|
name: { required: true, type: "string", minBytes: 1, maxBytes: 100 },
|
|
@@ -404,7 +404,7 @@ class SwitchbotDevice {
|
|
|
404
404
|
return;
|
|
405
405
|
}
|
|
406
406
|
|
|
407
|
-
|
|
407
|
+
const buf = Buffer.from(name, "utf8");
|
|
408
408
|
this._connect()
|
|
409
409
|
.then(() => {
|
|
410
410
|
if (!this._chars.device) {
|
package/lib/switchbot.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
const parameterChecker = require("./parameter-checker.js");
|
|
3
|
+
const switchbotAdvertising = require("./switchbot-advertising.js");
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
5
|
+
const SwitchbotDevice = require("./switchbot-device.js");
|
|
6
|
+
const SwitchbotDeviceWoHand = require("./switchbot-device-wohand.js");
|
|
7
|
+
const SwitchbotDeviceWoCurtain = require("./switchbot-device-wocurtain.js");
|
|
8
|
+
const SwitchbotDeviceWoBlindTilt = require("./switchbot-device-woblindtilt.js");
|
|
9
|
+
const SwitchbotDeviceWoPresence = require("./switchbot-device-wopresence.js");
|
|
10
|
+
const SwitchbotDeviceWoContact = require("./switchbot-device-wocontact.js");
|
|
11
|
+
const SwitchbotDeviceWoSensorTH = require("./switchbot-device-wosensorth.js");
|
|
12
|
+
const SwitchbotDeviceWoHumi = require("./switchbot-device-wohumi.js");
|
|
13
|
+
const SwitchbotDeviceWoPlugMini = require("./switchbot-device-woplugmini.js");
|
|
14
|
+
const SwitchbotDeviceWoBulb = require("./switchbot-device-wobulb.js");
|
|
15
|
+
const SwitchbotDeviceWoStrip = require("./switchbot-device-wostrip.js");
|
|
16
16
|
|
|
17
17
|
class Switchbot {
|
|
18
18
|
/* ------------------------------------------------------------------
|
|
@@ -20,7 +20,7 @@ class Switchbot {
|
|
|
20
20
|
*
|
|
21
21
|
* [Arguments]
|
|
22
22
|
* - params | Object | Optional |
|
|
23
|
-
* - noble | Noble | Optional | The
|
|
23
|
+
* - noble | Noble | Optional | The Noble object created by the noble module.
|
|
24
24
|
* | | | This parameter is optional.
|
|
25
25
|
* | | | If you don't specify this parameter, this
|
|
26
26
|
* | | | module automatically creates it.
|
|
@@ -84,9 +84,9 @@ class Switchbot {
|
|
|
84
84
|
* `SwitchbotDevice` objects representing the found devices.
|
|
85
85
|
* ---------------------------------------------------------------- */
|
|
86
86
|
discover(params = {}) {
|
|
87
|
-
|
|
87
|
+
const promise = new Promise((resolve, reject) => {
|
|
88
88
|
// Check the parameters
|
|
89
|
-
|
|
89
|
+
const valid = parameterChecker.check(
|
|
90
90
|
params,
|
|
91
91
|
{
|
|
92
92
|
duration: { required: false, type: "integer", min: 1, max: 60000 },
|
|
@@ -125,7 +125,7 @@ class Switchbot {
|
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
// Determine the values of the parameters
|
|
128
|
-
|
|
128
|
+
const p = {
|
|
129
129
|
duration: params.duration || this._DEFAULT_DISCOVERY_DURATION,
|
|
130
130
|
model: params.model || "",
|
|
131
131
|
id: params.id || "",
|
|
@@ -137,7 +137,7 @@ class Switchbot {
|
|
|
137
137
|
.then(() => {
|
|
138
138
|
let peripherals = {};
|
|
139
139
|
let timer = null;
|
|
140
|
-
|
|
140
|
+
const finishDiscovery = () => {
|
|
141
141
|
if (timer) {
|
|
142
142
|
clearTimeout(timer);
|
|
143
143
|
}
|
|
@@ -154,11 +154,11 @@ class Switchbot {
|
|
|
154
154
|
|
|
155
155
|
// Set a handler for the 'discover' event
|
|
156
156
|
this.noble.on("discover", (peripheral) => {
|
|
157
|
-
|
|
157
|
+
const device = this._getDeviceObject(peripheral, p.id, p.model);
|
|
158
158
|
if (!device) {
|
|
159
159
|
return;
|
|
160
160
|
}
|
|
161
|
-
|
|
161
|
+
const id = device.id;
|
|
162
162
|
peripherals[id] = device;
|
|
163
163
|
|
|
164
164
|
if (this.ondiscover && typeof this.ondiscover === "function") {
|
|
@@ -194,25 +194,23 @@ class Switchbot {
|
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
_init() {
|
|
197
|
-
|
|
197
|
+
const promise = new Promise((resolve, reject) => {
|
|
198
198
|
switch (this.noble.state) {
|
|
199
199
|
case "poweredOn":
|
|
200
200
|
resolve();
|
|
201
201
|
return;
|
|
202
202
|
case ("unsupported", "unauthorized", "poweredOff"):
|
|
203
|
-
|
|
203
|
+
const err = new Error(
|
|
204
204
|
"Failed to initialize the Noble object: " + this.noble.state
|
|
205
205
|
);
|
|
206
206
|
reject(err);
|
|
207
207
|
return;
|
|
208
208
|
default: // 'resetting', 'unknown'
|
|
209
209
|
this.noble.once("stateChange", (state) => {
|
|
210
|
-
require("events").EventEmitter.prototype.setMaxListeners(0);
|
|
211
|
-
require("events").setMaxListeners(0);
|
|
212
210
|
if (state === "poweredOn") {
|
|
213
211
|
resolve();
|
|
214
212
|
} else {
|
|
215
|
-
|
|
213
|
+
const err = new Error(
|
|
216
214
|
"Failed to initialize the Noble object: " + state
|
|
217
215
|
);
|
|
218
216
|
reject(err);
|
|
@@ -224,7 +222,7 @@ class Switchbot {
|
|
|
224
222
|
}
|
|
225
223
|
|
|
226
224
|
_getDeviceObject(peripheral, id, model) {
|
|
227
|
-
|
|
225
|
+
const ad = switchbotAdvertising.parse(peripheral, this.onlog);
|
|
228
226
|
if (this._filterAdvertising(ad, id, model)) {
|
|
229
227
|
let device = null;
|
|
230
228
|
switch (ad.serviceData.model) {
|
|
@@ -280,7 +278,7 @@ class Switchbot {
|
|
|
280
278
|
}
|
|
281
279
|
if (id) {
|
|
282
280
|
id = id.toLowerCase().replace(/\:/g, "");
|
|
283
|
-
|
|
281
|
+
const ad_id = ad.address.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
284
282
|
if (ad_id !== id) {
|
|
285
283
|
return false;
|
|
286
284
|
}
|
|
@@ -349,9 +347,9 @@ class Switchbot {
|
|
|
349
347
|
* Nothing will be passed to the `resolve()`.
|
|
350
348
|
* ---------------------------------------------------------------- */
|
|
351
349
|
startScan(params) {
|
|
352
|
-
|
|
350
|
+
const promise = new Promise((resolve, reject) => {
|
|
353
351
|
// Check the parameters
|
|
354
|
-
|
|
352
|
+
const valid = parameterChecker.check(
|
|
355
353
|
params,
|
|
356
354
|
{
|
|
357
355
|
model: {
|
|
@@ -377,8 +375,6 @@ class Switchbot {
|
|
|
377
375
|
},
|
|
378
376
|
false
|
|
379
377
|
);
|
|
380
|
-
require("events").EventEmitter.prototype.setMaxListeners(0);
|
|
381
|
-
require("events").setMaxListeners(0);
|
|
382
378
|
if (!valid) {
|
|
383
379
|
reject(new Error(parameterChecker.error.message));
|
|
384
380
|
return;
|
|
@@ -392,14 +388,14 @@ class Switchbot {
|
|
|
392
388
|
this._init()
|
|
393
389
|
.then(() => {
|
|
394
390
|
// Determine the values of the parameters
|
|
395
|
-
|
|
391
|
+
const p = {
|
|
396
392
|
model: params.model || "",
|
|
397
393
|
id: params.id || "",
|
|
398
394
|
};
|
|
399
395
|
|
|
400
396
|
// Set a handler for the 'discover' event
|
|
401
397
|
this.noble.on("discover", (peripheral) => {
|
|
402
|
-
|
|
398
|
+
const ad = switchbotAdvertising.parse(peripheral, this.onlog);
|
|
403
399
|
if (this._filterAdvertising(ad, p.id, p.model)) {
|
|
404
400
|
if (
|
|
405
401
|
this.onadvertisement &&
|
|
@@ -459,7 +455,7 @@ class Switchbot {
|
|
|
459
455
|
wait(msec) {
|
|
460
456
|
return new Promise((resolve, reject) => {
|
|
461
457
|
// Check the parameters
|
|
462
|
-
|
|
458
|
+
const valid = parameterChecker.check(
|
|
463
459
|
{ msec: msec },
|
|
464
460
|
{
|
|
465
461
|
msec: { required: true, type: "integer", min: 0 },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-switchbot",
|
|
3
|
-
"version": "1.8.1-beta.
|
|
3
|
+
"version": "1.8.1-beta.8",
|
|
4
4
|
"description": "The node-switchbot is a Node.js module which allows you to control your Switchbot Devices through Bluetooth (BLE).",
|
|
5
5
|
"main": "./lib/switchbot.js",
|
|
6
6
|
"files": [
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
},
|
|
36
36
|
"readmeFilename": "README.md",
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@
|
|
38
|
+
"@abandonware/noble": "1.9.2-15"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"npm-check-updates": "^16.7.5"
|