Skip to content

Commit 8511ea5

Browse files
v1.8.0 (#182)
## [Version 1.8.0](https://github.com/OpenWonderLabs/node-switchbot/releases/tag/v1.8.0) (2023-01-28) ## What's Changed - Add Support for BlindTilt (Read Only) - Use Error object for promise rejection, Thanks [@dnicolson](https://github.com/dnicolson/). [#181](#181) - Housekeeping and update dependencies **Full Changelog**: v1.7.3...v1.8.0
1 parent e001c70 commit 8511ea5

File tree

7 files changed

+240
-37
lines changed

7 files changed

+240
-37
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

33
All notable changes to this project will be documented in this file. This project uses [Semantic Versioning](https://semver.org/)
44

5+
## [Version 1.8.0](https://github.com/OpenWonderLabs/node-switchbot/releases/tag/v1.8.0) (2023-01-28)
6+
7+
## What's Changed
8+
9+
- Add Support for BlindTilt (Read Only)
10+
- Use Error object for promise rejection, Thanks [@dnicolson](https://github.com/dnicolson/). [#181](https://github.com/OpenWonderLabs/node-switchbot/pull/181)
11+
- Housekeeping and update dependencies
12+
13+
**Full Changelog**: https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.3...v1.8.0
14+
515
## [Version 1.7.3](https://github.com/OpenWonderLabs/node-switchbot/releases/tag/v1.7.3) (2023-01-05)
616

717
## What's Changed

lib/switchbot-advertising.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ class SwitchbotAdvertising {
9494
sd = this._parseServiceDataForWoContact(buf, onlog);//WoContact
9595
} else if (model === "c") {
9696
sd = this._parseServiceDataForWoCurtain(buf, onlog);// WoCurtain
97+
} else if (model === "x") {
98+
sd = this._parseServiceDataForWoBlindTilt(buf, onlog);// WoBlindTilt
9799
} else if (model === "u") {
98100
sd = this._parseServiceDataForWoBulb(manufacturerData, onlog);// WoBulb
99101
} else if (model === "g") {
@@ -365,6 +367,37 @@ class SwitchbotAdvertising {
365367
return data;
366368
}
367369

370+
_parseServiceDataForWoBlindTilt(buf, onlog) {
371+
if (buf.length !== 5 && buf.length !== 6) {
372+
if (onlog && typeof onlog === "function") {
373+
onlog(
374+
`[_parseServiceDataForWoBlindTilt] Buffer length ${buf.length} !== 5 or 6!`
375+
);
376+
}
377+
return null;
378+
}
379+
let byte1 = buf.readUInt8(1);
380+
let byte2 = buf.readUInt8(2);
381+
382+
let calibration = byte1 & 0b00000001 ? true : false; // Whether the calibration is completed
383+
let battery = byte2 & 0b01111111; // %
384+
let inMotion = byte2 & 0b10000000 ? true : false;
385+
let tilt = byte2 & 0b01111111; // current tilt % (100 - _tilt) if reverse else _tilt,
386+
let lightLevel = (byte1 >> 4) & 0b00001111; // light sensor level (1-10)
387+
388+
let data = {
389+
model: "x",
390+
modelName: "WoBlindTilt",
391+
calibration: calibration,
392+
battery: battery,
393+
inMotion: inMotion,
394+
tilt: tilt,
395+
lightLevel: lightLevel,
396+
};
397+
398+
return data;
399+
}
400+
368401
_parseServiceDataForWoBulb(manufacturerData, onlog) {
369402
if (manufacturerData.length !== 13) {
370403
if (onlog && typeof onlog === "function") {
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
"use strict";
2+
let SwitchbotDevice = require("./switchbot-device.js");
3+
4+
class SwitchbotDeviceWoBlindTilt extends SwitchbotDevice {
5+
/* ------------------------------------------------------------------
6+
* open()
7+
* - Open the blindtilt
8+
*
9+
* [Arguments]
10+
* - none
11+
*
12+
* [Return value]
13+
* - Promise object
14+
* Nothing will be passed to the `resolve()`.
15+
* ---------------------------------------------------------------- */
16+
open() {
17+
return this._operateBlindTilt([0x57, 0x0f, 0x45, 0x01, 0x05, 0xff, 0x00]);
18+
}
19+
20+
/* ------------------------------------------------------------------
21+
* close()
22+
* - close the blindtilt
23+
*
24+
* [Arguments]
25+
* - none
26+
*
27+
* [Return value]
28+
* - Promise object
29+
* Nothing will be passed to the `resolve()`.
30+
* ---------------------------------------------------------------- */
31+
close() {
32+
return this._operateBlindTilt([0x57, 0x0f, 0x45, 0x01, 0x05, 0xff, 0x64]);
33+
}
34+
35+
/* ------------------------------------------------------------------
36+
* pause()
37+
* - pause the blindtilt
38+
*
39+
* [Arguments]
40+
* - none
41+
*
42+
* [Return value]
43+
* - Promise object
44+
* Nothing will be passed to the `resolve()`.
45+
* ---------------------------------------------------------------- */
46+
pause() {
47+
return this._operateBlindTilt([0x57, 0x0f, 0x45, 0x01, 0x00, 0xff]);
48+
}
49+
50+
/* ------------------------------------------------------------------
51+
* runToPos()
52+
* - run to the targe position
53+
*
54+
* [Arguments]
55+
* - percent | number | Required | the percentage of target position
56+
*
57+
* [Return value]
58+
* - Promise object
59+
* Nothing will be passed to the `resolve()`.
60+
* ---------------------------------------------------------------- */
61+
runToPos(percent, mode) {
62+
if (typeof percent != "number") {
63+
return new Promise((resolve, reject) => {
64+
reject(
65+
new Error(
66+
"The type of target position percentage is incorrent: " +
67+
typeof percent
68+
)
69+
);
70+
});
71+
}
72+
if (mode == null) {
73+
mode = 0xff;
74+
} else {
75+
if (typeof mode != "number") {
76+
return new Promise((resolve, reject) => {
77+
reject(
78+
new Error("The type of running mode is incorrent: " + typeof mode)
79+
);
80+
});
81+
}
82+
if (mode > 1) {
83+
mode = 0xff;
84+
}
85+
}
86+
if (percent > 100) {
87+
percent = 100;
88+
} else if (percent < 0) {
89+
percent = 0;
90+
}
91+
return this._operateBlindTilt([0x57, 0x0f, 0x45, 0x01, 0x05, mode, percent]);
92+
}
93+
94+
_operateBlindTilt(bytes) {
95+
return new Promise((resolve, reject) => {
96+
let req_buf = Buffer.from(bytes);
97+
this._command(req_buf)
98+
.then((res_buf) => {
99+
let code = res_buf.readUInt8(0);
100+
if (res_buf.length === 3 && code === 0x01) {
101+
resolve();
102+
} else {
103+
reject(
104+
new Error(
105+
"The device returned an error: 0x" + res_buf.toString("hex")
106+
)
107+
);
108+
}
109+
})
110+
.catch((error) => {
111+
reject(error);
112+
});
113+
});
114+
}
115+
}
116+
117+
module.exports = SwitchbotDeviceWoBlindTilt;

lib/switchbot-device.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ class SwitchbotDevice {
444444
this._connect()
445445
.then(() => {
446446
if (!this._chars) {
447-
return reject("No characteristics available.");
447+
return reject(new Error("No characteristics available."));
448448
}
449449
return this._write(this._chars.write, req_buf);
450450
})

lib/switchbot.js

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ let switchbotAdvertising = require("./switchbot-advertising.js");
55
let SwitchbotDevice = require("./switchbot-device.js");
66
let SwitchbotDeviceWoHand = require("./switchbot-device-wohand.js");
77
let SwitchbotDeviceWoCurtain = require("./switchbot-device-wocurtain.js");
8+
let SwitchbotDeviceWoBlindTilt = require("./switchbot-device-woblindtilt.js");
89
let SwitchbotDeviceWoPresence = require("./switchbot-device-wopresence.js");
910
let SwitchbotDeviceWoContact = require("./switchbot-device-wocontact.js");
1011
let SwitchbotDeviceWoSensorTH = require("./switchbot-device-wosensorth.js");
@@ -92,7 +93,21 @@ class Switchbot {
9293
model: {
9394
required: false,
9495
type: "string",
95-
enum: ["H", "T", "e", "s", "d", "c", "u", "g", "j", "o", "i", "r"],
96+
enum: [
97+
"H",
98+
"T",
99+
"e",
100+
"s",
101+
"d",
102+
"c",
103+
"u",
104+
"g",
105+
"j",
106+
"o",
107+
"i",
108+
"r",
109+
"x",
110+
],
96111
},
97112
id: { required: false, type: "string", min: 12, max: 17 },
98113
quick: { required: false, type: "boolean" },
@@ -229,6 +244,9 @@ class Switchbot {
229244
case "c":
230245
device = new SwitchbotDeviceWoCurtain(peripheral, this.noble);
231246
break;
247+
case "x":
248+
device = new SwitchbotDeviceWoBlindTilt(peripheral, this.noble);
249+
break;
232250
case "u":
233251
device = new SwitchbotDeviceWoBulb(peripheral, this.noble);
234252
break;
@@ -240,7 +258,7 @@ class Switchbot {
240258
device = new SwitchbotDeviceWoSmartLock(peripheral, this.noble);
241259
break;
242260
case "i":
243-
device = new SwitchbotDeviceWoSensorTHPlus(peripheral, this.noble);
261+
device = new SwitchbotDeviceWoSensorTH(peripheral, this.noble);
244262
break;
245263
case "r":
246264
device = new SwitchbotDeviceWoStrip(peripheral, this.noble);
@@ -279,7 +297,7 @@ class Switchbot {
279297
*
280298
* [Arguments]
281299
* - params | Object | Optional |
282-
* - model | String | Optional | "H", "T", "e", "s", "d", "c", "u", "g", "o", "i", or "r".
300+
* - model | String | Optional | "H", "T", "e", "s", "d", "c", "u", "g", "o", "i", "x", or "r".
283301
* | | | If "H" is specified, the `onadvertisement`
284302
* | | | event handler will be called only when advertising
285303
* | | | packets comes from Bots.
@@ -298,6 +316,9 @@ class Switchbot {
298316
* | | | If "c" is specified, the `onadvertisement`
299317
* | | | event handler will be called only when advertising
300318
* | | | packets comes from Curtains.
319+
* | | | If "x" is specified, the `onadvertisement`
320+
* | | | event handler will be called only when advertising
321+
* | | | packets comes from BlindTilt.
301322
* | | | If "u" is specified, the `onadvertisement`
302323
* | | | event handler will be called only when advertising
303324
* | | | packets comes from Color Bulb.
@@ -334,7 +355,21 @@ class Switchbot {
334355
model: {
335356
required: false,
336357
type: "string",
337-
enum: ["H", "T", "e", "s", "d", "c", "u", "g", "j", "o", "i", "r"],
358+
enum: [
359+
"H",
360+
"T",
361+
"e",
362+
"s",
363+
"d",
364+
"c",
365+
"u",
366+
"g",
367+
"j",
368+
"o",
369+
"i",
370+
"r",
371+
"x",
372+
],
338373
},
339374
id: { required: false, type: "string", min: 12, max: 17 },
340375
},

0 commit comments

Comments
 (0)