Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

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

## [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](https://github.com/OpenWonderLabs/node-switchbot/pull/181)
- Housekeeping and update dependencies

**Full Changelog**: https://github.com/OpenWonderLabs/node-switchbot/compare/v1.7.3...v1.8.0

## [Version 1.7.3](https://github.com/OpenWonderLabs/node-switchbot/releases/tag/v1.7.3) (2023-01-05)

## What's Changed
Expand Down
33 changes: 33 additions & 0 deletions lib/switchbot-advertising.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ class SwitchbotAdvertising {
sd = this._parseServiceDataForWoContact(buf, onlog);//WoContact
} else if (model === "c") {
sd = this._parseServiceDataForWoCurtain(buf, onlog);// WoCurtain
} else if (model === "x") {
sd = this._parseServiceDataForWoBlindTilt(buf, onlog);// WoBlindTilt
} else if (model === "u") {
sd = this._parseServiceDataForWoBulb(manufacturerData, onlog);// WoBulb
} else if (model === "g") {
Expand Down Expand Up @@ -365,6 +367,37 @@ class SwitchbotAdvertising {
return data;
}

_parseServiceDataForWoBlindTilt(buf, onlog) {
if (buf.length !== 5 && buf.length !== 6) {
if (onlog && typeof onlog === "function") {
onlog(
`[_parseServiceDataForWoBlindTilt] Buffer length ${buf.length} !== 5 or 6!`
);
}
return null;
}
let byte1 = buf.readUInt8(1);
let byte2 = buf.readUInt8(2);

let calibration = byte1 & 0b00000001 ? true : false; // Whether the calibration is completed
let battery = byte2 & 0b01111111; // %
let inMotion = byte2 & 0b10000000 ? true : false;
let tilt = byte2 & 0b01111111; // current tilt % (100 - _tilt) if reverse else _tilt,
let lightLevel = (byte1 >> 4) & 0b00001111; // light sensor level (1-10)

let data = {
model: "x",
modelName: "WoBlindTilt",
calibration: calibration,
battery: battery,
inMotion: inMotion,
tilt: tilt,
lightLevel: lightLevel,
};

return data;
}

_parseServiceDataForWoBulb(manufacturerData, onlog) {
if (manufacturerData.length !== 13) {
if (onlog && typeof onlog === "function") {
Expand Down
117 changes: 117 additions & 0 deletions lib/switchbot-device-woblindtilt.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
"use strict";
let SwitchbotDevice = require("./switchbot-device.js");

class SwitchbotDeviceWoBlindTilt extends SwitchbotDevice {
/* ------------------------------------------------------------------
* open()
* - Open the blindtilt
*
* [Arguments]
* - none
*
* [Return value]
* - Promise object
* Nothing will be passed to the `resolve()`.
* ---------------------------------------------------------------- */
open() {
return this._operateBlindTilt([0x57, 0x0f, 0x45, 0x01, 0x05, 0xff, 0x00]);
}

/* ------------------------------------------------------------------
* close()
* - close the blindtilt
*
* [Arguments]
* - none
*
* [Return value]
* - Promise object
* Nothing will be passed to the `resolve()`.
* ---------------------------------------------------------------- */
close() {
return this._operateBlindTilt([0x57, 0x0f, 0x45, 0x01, 0x05, 0xff, 0x64]);
}

/* ------------------------------------------------------------------
* pause()
* - pause the blindtilt
*
* [Arguments]
* - none
*
* [Return value]
* - Promise object
* Nothing will be passed to the `resolve()`.
* ---------------------------------------------------------------- */
pause() {
return this._operateBlindTilt([0x57, 0x0f, 0x45, 0x01, 0x00, 0xff]);
}

/* ------------------------------------------------------------------
* runToPos()
* - run to the targe position
*
* [Arguments]
* - percent | number | Required | the percentage of target position
*
* [Return value]
* - Promise object
* Nothing will be passed to the `resolve()`.
* ---------------------------------------------------------------- */
runToPos(percent, mode) {
if (typeof percent != "number") {
return new Promise((resolve, reject) => {
reject(
new Error(
"The type of target position percentage is incorrent: " +
typeof percent
)
);
});
}
if (mode == null) {
mode = 0xff;
} else {
if (typeof mode != "number") {
return new Promise((resolve, reject) => {
reject(
new Error("The type of running mode is incorrent: " + typeof mode)
);
});
}
if (mode > 1) {
mode = 0xff;
}
}
if (percent > 100) {
percent = 100;
} else if (percent < 0) {
percent = 0;
}
return this._operateBlindTilt([0x57, 0x0f, 0x45, 0x01, 0x05, mode, percent]);
}

_operateBlindTilt(bytes) {
return new Promise((resolve, reject) => {
let req_buf = Buffer.from(bytes);
this._command(req_buf)
.then((res_buf) => {
let code = res_buf.readUInt8(0);
if (res_buf.length === 3 && code === 0x01) {
resolve();
} else {
reject(
new Error(
"The device returned an error: 0x" + res_buf.toString("hex")
)
);
}
})
.catch((error) => {
reject(error);
});
});
}
}

module.exports = SwitchbotDeviceWoBlindTilt;
2 changes: 1 addition & 1 deletion lib/switchbot-device.js
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ class SwitchbotDevice {
this._connect()
.then(() => {
if (!this._chars) {
return reject("No characteristics available.");
return reject(new Error("No characteristics available."));
}
return this._write(this._chars.write, req_buf);
})
Expand Down
43 changes: 39 additions & 4 deletions lib/switchbot.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ let switchbotAdvertising = require("./switchbot-advertising.js");
let SwitchbotDevice = require("./switchbot-device.js");
let SwitchbotDeviceWoHand = require("./switchbot-device-wohand.js");
let SwitchbotDeviceWoCurtain = require("./switchbot-device-wocurtain.js");
let SwitchbotDeviceWoBlindTilt = require("./switchbot-device-woblindtilt.js");
let SwitchbotDeviceWoPresence = require("./switchbot-device-wopresence.js");
let SwitchbotDeviceWoContact = require("./switchbot-device-wocontact.js");
let SwitchbotDeviceWoSensorTH = require("./switchbot-device-wosensorth.js");
Expand Down Expand Up @@ -92,7 +93,21 @@ class Switchbot {
model: {
required: false,
type: "string",
enum: ["H", "T", "e", "s", "d", "c", "u", "g", "j", "o", "i", "r"],
enum: [
"H",
"T",
"e",
"s",
"d",
"c",
"u",
"g",
"j",
"o",
"i",
"r",
"x",
],
},
id: { required: false, type: "string", min: 12, max: 17 },
quick: { required: false, type: "boolean" },
Expand Down Expand Up @@ -229,6 +244,9 @@ class Switchbot {
case "c":
device = new SwitchbotDeviceWoCurtain(peripheral, this.noble);
break;
case "x":
device = new SwitchbotDeviceWoBlindTilt(peripheral, this.noble);
break;
case "u":
device = new SwitchbotDeviceWoBulb(peripheral, this.noble);
break;
Expand All @@ -240,7 +258,7 @@ class Switchbot {
device = new SwitchbotDeviceWoSmartLock(peripheral, this.noble);
break;
case "i":
device = new SwitchbotDeviceWoSensorTHPlus(peripheral, this.noble);
device = new SwitchbotDeviceWoSensorTH(peripheral, this.noble);
break;
case "r":
device = new SwitchbotDeviceWoStrip(peripheral, this.noble);
Expand Down Expand Up @@ -279,7 +297,7 @@ class Switchbot {
*
* [Arguments]
* - params | Object | Optional |
* - model | String | Optional | "H", "T", "e", "s", "d", "c", "u", "g", "o", "i", or "r".
* - model | String | Optional | "H", "T", "e", "s", "d", "c", "u", "g", "o", "i", "x", or "r".
* | | | If "H" is specified, the `onadvertisement`
* | | | event handler will be called only when advertising
* | | | packets comes from Bots.
Expand All @@ -298,6 +316,9 @@ class Switchbot {
* | | | If "c" is specified, the `onadvertisement`
* | | | event handler will be called only when advertising
* | | | packets comes from Curtains.
* | | | If "x" is specified, the `onadvertisement`
* | | | event handler will be called only when advertising
* | | | packets comes from BlindTilt.
* | | | If "u" is specified, the `onadvertisement`
* | | | event handler will be called only when advertising
* | | | packets comes from Color Bulb.
Expand Down Expand Up @@ -334,7 +355,21 @@ class Switchbot {
model: {
required: false,
type: "string",
enum: ["H", "T", "e", "s", "d", "c", "u", "g", "j", "o", "i", "r"],
enum: [
"H",
"T",
"e",
"s",
"d",
"c",
"u",
"g",
"j",
"o",
"i",
"r",
"x",
],
},
id: { required: false, type: "string", min: 12, max: 17 },
},
Expand Down
Loading