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
21 changes: 14 additions & 7 deletions src/advertising.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Buffer } from 'buffer';

import { Peripheral } from '@abandonware/noble';

import { WoHand } from './device/wohand.js';
import { WoCurtain } from './device/wocurtain.js';
import { WoBlindTilt } from './device/woblindtilt.js';
Expand All @@ -13,6 +15,13 @@ import { WoBulb } from './device/wobulb.js';
import { WoStrip } from './device/wostrip.js';
import { WoSmartLock } from './device/wosmartlock.js';

export type Ad = {
id: string;
address: string;
rssi: number,
serviceData: any;
} | null

export class Advertising {

constructor() {}
Expand Down Expand Up @@ -81,7 +90,7 @@ export class Advertising {
* @param onlog - The logging function.
* @returns The parsed data of the peripheral device.
*/
static parse(peripheral, onlog?) {
static parse(peripheral: Peripheral, onlog?: (message: string) => void) {
const ad = peripheral.advertisement;
if (!ad || !ad.serviceData) {
return null;
Expand Down Expand Up @@ -150,16 +159,14 @@ export class Advertising {
}
let address = peripheral.address || '';
if (address === '') {
address = peripheral.advertisement.manufacturerData || '';
if (address !== '') {
const str = peripheral.advertisement.manufacturerData
.toString('hex')
.slice(4, 16);
const str = peripheral.advertisement.manufacturerData
.toString('hex')
.slice(4, 16);
if (str !== '') {
address = str.substr(0, 2);
for (let i = 2; i < str.length; i += 2) {
address = address + ':' + str.substr(i, 2);
}
// console.log("address", typeof(address), address);
}
} else {
address = address.replace(/-/g, ':');
Expand Down
63 changes: 27 additions & 36 deletions src/device.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import { Buffer } from 'buffer';

import { Characteristic, Peripheral, Service } from '@abandonware/noble';
import { ParameterChecker } from './parameter-checker.js';
import { Advertising } from './advertising.js';

type ad = {
id: any;
address: any;
rssi: any;
serviceData: any;
type Chars = {
write: Characteristic | null,
notify: Characteristic | null,
device: Characteristic | null,
} | null;

export class SwitchbotDevice {
_peripheral;
_noble;
_chars;
_SERV_UUID_PRIMARY;
_CHAR_UUID_WRITE;
_CHAR_UUID_NOTIFY;
_CHAR_UUID_DEVICE;
_READ_TIMEOUT_MSEC;
_WRITE_TIMEOUT_MSEC;
_COMMAND_TIMEOUT_MSEC;
_chars: Chars;
_SERV_UUID_PRIMARY = 'cba20d00224d11e69fb80002a5d5c51b';
_CHAR_UUID_WRITE = 'cba20002224d11e69fb80002a5d5c51b';
_CHAR_UUID_NOTIFY = 'cba20003224d11e69fb80002a5d5c51b';
_CHAR_UUID_DEVICE = '2a00';
_READ_TIMEOUT_MSEC = 3000;
_WRITE_TIMEOUT_MSEC = 3000;
_COMMAND_TIMEOUT_MSEC = 3000;
_id;
_address;
_model;
Expand All @@ -39,22 +39,13 @@ export class SwitchbotDevice {
* | | | which represents this device
* - noble | Noble | Required | The Noble object created by the noble module.
* ---------------------------------------------------------------- */
constructor(peripheral, noble) {
constructor(peripheral: Peripheral, noble: any) {
this._peripheral = peripheral;
this._noble = noble;
this._chars = null;

this._SERV_UUID_PRIMARY = 'cba20d00224d11e69fb80002a5d5c51b';
this._CHAR_UUID_WRITE = 'cba20002224d11e69fb80002a5d5c51b';
this._CHAR_UUID_NOTIFY = 'cba20003224d11e69fb80002a5d5c51b';
this._CHAR_UUID_DEVICE = '2a00';

this._READ_TIMEOUT_MSEC = 3000;
this._WRITE_TIMEOUT_MSEC = 3000;
this._COMMAND_TIMEOUT_MSEC = 3000;

// Save the device information
const ad: ad = Advertising.parse(peripheral);
const ad = Advertising.parse(peripheral);
this._id = ad?.id;
this._address = ad?.address;
this._model = ad?.serviceData.model;
Expand Down Expand Up @@ -95,14 +86,14 @@ export class SwitchbotDevice {
}

// Setters
set onconnect(func) {
set onconnect(func: () => void) {
if (!func || typeof func !== 'function') {
throw new Error('The `onconnect` must be a function.');
}
this._onconnect = func;
}

set ondisconnect(func) {
set ondisconnect(func: () => void) {
if (!func || typeof func !== 'function') {
throw new Error('The `ondisconnect` must be a function.');
}
Expand Down Expand Up @@ -185,7 +176,7 @@ export class SwitchbotDevice {
});
}

_getCharacteristics() {
_getCharacteristics(): Promise<Chars> {
return new Promise((resolve, reject) => {
// Set timeout timer
let timer: NodeJS.Timeout | null = setTimeout(() => {
Expand Down Expand Up @@ -279,7 +270,7 @@ export class SwitchbotDevice {
});
}

_discoverCharacteristics(service) {
_discoverCharacteristics(service: Service) {
return new Promise((resolve, reject) => {
service.discoverCharacteristics([], (error, char_list) => {
if (error) {
Expand All @@ -293,7 +284,7 @@ export class SwitchbotDevice {

_subscribe() {
return new Promise<void>((resolve, reject) => {
const char = this._chars.notify;
const char = this._chars?.notify;
if (!char) {
reject(new Error('No notify characteristic was found.'));
return;
Expand All @@ -313,7 +304,7 @@ export class SwitchbotDevice {

_unsubscribe() {
return new Promise<void>((resolve) => {
const char = this._chars.notify;
const char = this._chars?.notify;
if (!char) {
resolve();
return;
Expand Down Expand Up @@ -387,7 +378,7 @@ export class SwitchbotDevice {
let name = '';
this._connect()
.then(() => {
if (!this._chars.device) {
if (!this._chars?.device) {
// Some models of Bot don't seem to support this characteristic UUID
throw new Error(
'The device does not support the characteristic UUID 0x' +
Expand Down Expand Up @@ -422,7 +413,7 @@ export class SwitchbotDevice {
* - Promise object
* Nothing will be passed to the `resolve()`.
* ---------------------------------------------------------------- */
setDeviceName(name) {
setDeviceName(name: string) {
return new Promise<void>((resolve, reject) => {
// Check the parameters
const valid = ParameterChecker.check(
Expand All @@ -441,7 +432,7 @@ export class SwitchbotDevice {
const buf = Buffer.from(name, 'utf8');
this._connect()
.then(() => {
if (!this._chars.device) {
if (!this._chars?.device) {
// Some models of Bot don't seem to support this characteristic UUID
throw new Error(
'The device does not support the characteristic UUID 0x' +
Expand Down Expand Up @@ -477,7 +468,7 @@ export class SwitchbotDevice {

this._connect()
.then(() => {
if (!this._chars) {
if (!this._chars?.write) {
return reject(new Error('No characteristics available.'));
}
return this._write(this._chars.write, req_buf);
Expand Down Expand Up @@ -518,7 +509,7 @@ export class SwitchbotDevice {
}

// Read data from the specified characteristic
_read(char) {
_read(char: Characteristic) {
return new Promise((resolve, reject) => {
// Set a timeout timer
let timer: NodeJS.Timeout | undefined = setTimeout(() => {
Expand All @@ -541,7 +532,7 @@ export class SwitchbotDevice {
}

// Write the specified Buffer data to the specified characteristic
_write(char, buf) {
_write(char: Characteristic, buf: Buffer) {
return new Promise<void>((resolve, reject) => {
// Set a timeout timer
let timer: NodeJS.Timeout | undefined = setTimeout(() => {
Expand Down
6 changes: 3 additions & 3 deletions src/device/woblindtilt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Buffer } from 'buffer';
import { SwitchbotDevice } from '../device.js';

export class WoBlindTilt extends SwitchbotDevice {
static parseServiceData(buf, onlog) {
static parseServiceData(buf: Buffer, onlog: ((message: string) => void) | undefined) {
if (buf.length !== 5 && buf.length !== 6) {
if (onlog && typeof onlog === 'function') {
onlog(
Expand Down Expand Up @@ -94,7 +94,7 @@ export class WoBlindTilt extends SwitchbotDevice {
* - Promise object
* Nothing will be passed to the `resolve()`.
* ---------------------------------------------------------------- */
runToPos(percent, mode) {
runToPos(percent: number, mode: number) {
if (typeof percent !== 'number') {
return new Promise((resolve, reject) => {
reject(
Expand Down Expand Up @@ -127,7 +127,7 @@ export class WoBlindTilt extends SwitchbotDevice {
return this._operateBlindTilt([0x57, 0x0f, 0x45, 0x01, 0x05, mode, percent]);
}

_operateBlindTilt(bytes) {
_operateBlindTilt(bytes: number[]) {
return new Promise<void>((resolve, reject) => {
const req_buf = Buffer.from(bytes);
this._command(req_buf)
Expand Down
12 changes: 6 additions & 6 deletions src/device/wobulb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { SwitchbotDevice } from '../device.js';
* @see https://github.com/OpenWonderLabs/SwitchBotAPI-BLE/blob/latest/devicetypes/colorbulb.md
*/
export class WoBulb extends SwitchbotDevice {
static parseServiceData(manufacturerData, onlog) {
static parseServiceData(manufacturerData: Buffer, onlog: ((message: string) => void) | undefined) {
if (manufacturerData.length !== 13) {
if (onlog && typeof onlog === 'function') {
onlog(
Expand Down Expand Up @@ -73,7 +73,7 @@ export class WoBulb extends SwitchbotDevice {
/**
* @private
*/
_setState(reqByteArray) {
_setState(reqByteArray: number[]) {
const base = [0x57, 0x0f, 0x47, 0x01];
return this._operateBot(base.concat(reqByteArray));
}
Expand All @@ -95,7 +95,7 @@ export class WoBulb extends SwitchbotDevice {
/**
* @returns {Promise<number>} resolves with brightness percent
*/
setBrightness(brightness) {
setBrightness(brightness: number) {
if (typeof brightness !== 'number') {
return new Promise((resolve, reject) => {
reject(
Expand All @@ -117,7 +117,7 @@ export class WoBulb extends SwitchbotDevice {
/**
* @returns {Promise<number>} resolves with color_temperature percent
*/
setColorTemperature(color_temperature) {
setColorTemperature(color_temperature: number) {
if (typeof color_temperature !== 'number') {
return new Promise((resolve, reject) => {
reject(
Expand All @@ -139,7 +139,7 @@ export class WoBulb extends SwitchbotDevice {
/**
* @returns {Promise<number>} resolves with brightness percent
*/
setRGB(brightness, red, green, blue) {
setRGB(brightness: number, red: number, green: number, blue: number) {
if (typeof brightness !== 'number') {
return new Promise((resolve, reject) => {
reject(
Expand Down Expand Up @@ -206,7 +206,7 @@ export class WoBulb extends SwitchbotDevice {
/**
* @private
*/
_operateBot(bytes) {
_operateBot(bytes: number[]) {
const req_buf = Buffer.from(bytes);
return new Promise((resolve, reject) => {
this._command(req_buf)
Expand Down
2 changes: 1 addition & 1 deletion src/device/wocontact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import { SwitchbotDevice } from '../device.js';

export class WoContact extends SwitchbotDevice {
static parseServiceData(buf, onlog) {
static parseServiceData(buf: Buffer, onlog: ((message: string) => void) | undefined) {
if (buf.length !== 9) {
if (onlog && typeof onlog === 'function') {
onlog(
Expand Down
10 changes: 5 additions & 5 deletions src/device/wocurtain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Buffer } from 'buffer';
import { SwitchbotDevice } from '../device.js';

export class WoCurtain extends SwitchbotDevice {
static parseServiceData(buf, onlog) {
static parseServiceData(buf: Buffer, onlog: ((message: string) => void) | undefined) {
if (buf.length !== 5 && buf.length !== 6) {
if (onlog && typeof onlog === 'function') {
onlog(
Expand Down Expand Up @@ -54,7 +54,7 @@ export class WoCurtain extends SwitchbotDevice {
* - Promise object
* Nothing will be passed to the `resolve()`.
* ---------------------------------------------------------------- */
open(mode) {
open(mode?: number) {
return this.runToPos(0, mode);
}

Expand All @@ -69,7 +69,7 @@ export class WoCurtain extends SwitchbotDevice {
* - Promise object
* Nothing will be passed to the `resolve()`.
* ---------------------------------------------------------------- */
close(mode) {
close(mode?: number) {
return this.runToPos(100, mode);
}

Expand Down Expand Up @@ -100,7 +100,7 @@ export class WoCurtain extends SwitchbotDevice {
* - Promise object
* Nothing will be passed to the `resolve()`.
* ---------------------------------------------------------------- */
runToPos(percent, mode = 0xff) {
runToPos(percent: number, mode = 0xff) {
if (typeof percent !== 'number') {
return new Promise((resolve, reject) => {
reject(
Expand Down Expand Up @@ -129,7 +129,7 @@ export class WoCurtain extends SwitchbotDevice {
return this._operateCurtain([0x57, 0x0f, 0x45, 0x01, 0x05, mode, percent]);
}

_operateCurtain(bytes) {
_operateCurtain(bytes: number[]) {
return new Promise<void>((resolve, reject) => {
const req_buf = Buffer.from(bytes);
this._command(req_buf)
Expand Down
4 changes: 2 additions & 2 deletions src/device/wohand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Buffer } from 'buffer';
import { SwitchbotDevice } from '../device.js';

export class WoHand extends SwitchbotDevice {
static parseServiceData(buf, onlog) {
static parseServiceData(buf: Buffer, onlog: ((message: string) => void) | undefined) {
if (buf.length !== 3) {
if (onlog && typeof onlog === 'function') {
onlog(
Expand Down Expand Up @@ -104,7 +104,7 @@ export class WoHand extends SwitchbotDevice {
return this._operateBot([0x57, 0x01, 0x04]);
}

_operateBot(bytes) {
_operateBot(bytes: number[]) {
return new Promise<void>((resolve, reject) => {
const req_buf = Buffer.from(bytes);
this._command(req_buf)
Expand Down
4 changes: 2 additions & 2 deletions src/device/wohumi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Buffer } from 'buffer';
import { SwitchbotDevice } from '../device.js';

export class WoHumi extends SwitchbotDevice {
static parseServiceData(buf, onlog) {
static parseServiceData(buf: Buffer, onlog: ((message: string) => void) | undefined) {
if (buf.length !== 8) {
if (onlog && typeof onlog === 'function') {
onlog(
Expand Down Expand Up @@ -106,7 +106,7 @@ export class WoHumi extends SwitchbotDevice {
return this._operateBot([0x57, 0x01, 0x04]);
}

_operateBot(bytes) {
_operateBot(bytes: number[]) {
return new Promise<void>((resolve, reject) => {
const req_buf = Buffer.from(bytes);
this._command(req_buf)
Expand Down
Loading