diff --git a/lib/switchbot-advertising.js b/lib/switchbot-advertising.js index b8e8241b..2d7e5784 100644 --- a/lib/switchbot-advertising.js +++ b/lib/switchbot-advertising.js @@ -97,23 +97,19 @@ class SwitchbotAdvertising { return null; } let address = peripheral.address || ''; - if(address === '') - { + if (address === '') { address = peripheral.advertisement.manufacturerData || ''; - if(address !== '') - { + if (address !== '') { const str = peripheral.advertisement.manufacturerData.toString('hex').slice(4); - address = str.substr(0,2); - for(var i = 2; i< str.length; i+=2) - { + address = str.substr(0, 2); + for (var i = 2; i < str.length; i += 2) { address = address + ":" + str.substr(i, 2); } // console.log("address", typeof(address), address); } } - else - { - address=address.replace(/-/g,':'); + else { + address = address.replace(/-/g, ':'); } let data = { id: peripheral.id, @@ -175,6 +171,34 @@ class SwitchbotAdvertising { return data; } + _parseServiceDataForWoSensorMS(buf) { + if (buf.length !== 6) { + return null; + } + + let data = { + model: 'M', + modelName: 'WoSensorMS', + battery: (byte2 & 0b01111111) + }; + + return data; + } + + _parseServiceDataForWoSensorCS(buf) { + if (buf.length !== 6) { + return null; + } + + let data = { + model: 'CS', + modelName: 'WoSensorCS', + battery: (byte2 & 0b01111111) + }; + + return data; + } + _parseServiceDataForWoCurtain(buf) { if (buf.length !== 5) { return null; diff --git a/lib/switchbot-device-wocurtain.js b/lib/switchbot-device-wocurtain.js index 97deafaf..293f0037 100644 --- a/lib/switchbot-device-wocurtain.js +++ b/lib/switchbot-device-wocurtain.js @@ -6,7 +6,7 @@ * Date: 2020-10-26 * ---------------------------------------------------------------- */ 'use strict'; -import SwitchbotDevice from './switchbot-device.js'; +const SwitchbotDevice = require('./switchbot-device.js'); class SwitchbotDeviceWoCurtain extends SwitchbotDevice { @@ -106,4 +106,4 @@ class SwitchbotDeviceWoCurtain extends SwitchbotDevice { } } -export default SwitchbotDeviceWoCurtain; \ No newline at end of file +module.exports = SwitchbotDeviceWoCurtain; \ No newline at end of file diff --git a/lib/switchbot-device-wohand.js b/lib/switchbot-device-wohand.js index a4178086..7c7ce654 100644 --- a/lib/switchbot-device-wohand.js +++ b/lib/switchbot-device-wohand.js @@ -6,7 +6,7 @@ * Date: 2020-02-10 * ---------------------------------------------------------------- */ 'use strict'; -import SwitchbotDevice from './switchbot-device.js'; +const SwitchbotDevice = require('./switchbot-device.js'); class SwitchbotDeviceWoHand extends SwitchbotDevice { @@ -103,4 +103,4 @@ class SwitchbotDeviceWoHand extends SwitchbotDevice { } -export default SwitchbotDeviceWoHand; \ No newline at end of file +module.exports = SwitchbotDeviceWoHand; \ No newline at end of file diff --git a/lib/switchbot-device-wosensorcs.js b/lib/switchbot-device-wosensorcs.js new file mode 100644 index 00000000..cd1916be --- /dev/null +++ b/lib/switchbot-device-wosensorcs.js @@ -0,0 +1,16 @@ +/* ------------------------------------------------------------------ +* node-linking - switchbot-device-wosensorth.js +* +* Copyright (c) 2019, Futomi Hatano, All rights reserved. +* Released under the MIT license +* Date: 2019-11-16 +* ---------------------------------------------------------------- */ +'use strict'; +const SwitchbotDevice = require('./switchbot-device.js'); + +class SwitchbotDeviceWoSensorCS extends SwitchbotDevice { + + +} + +module.exports = SwitchbotDeviceWoSensorCS; \ No newline at end of file diff --git a/lib/switchbot-device-wosensorms.js b/lib/switchbot-device-wosensorms.js new file mode 100644 index 00000000..af2e94a7 --- /dev/null +++ b/lib/switchbot-device-wosensorms.js @@ -0,0 +1,16 @@ +/* ------------------------------------------------------------------ +* node-linking - switchbot-device-wosensorth.js +* +* Copyright (c) 2019, Futomi Hatano, All rights reserved. +* Released under the MIT license +* Date: 2019-11-16 +* ---------------------------------------------------------------- */ +'use strict'; +const SwitchbotDevice = require('./switchbot-device.js'); + +class SwitchbotDeviceWoSensorMS extends SwitchbotDevice { + + +} + +module.exports = SwitchbotDeviceWoSensorMS; \ No newline at end of file diff --git a/lib/switchbot-device-wosensorth.js b/lib/switchbot-device-wosensorth.js index 9e5ed710..3b9225d7 100644 --- a/lib/switchbot-device-wosensorth.js +++ b/lib/switchbot-device-wosensorth.js @@ -6,11 +6,11 @@ * Date: 2019-11-16 * ---------------------------------------------------------------- */ 'use strict'; -import SwitchbotDevice from './switchbot-device.js'; +const SwitchbotDevice = require('./switchbot-device.js'); class SwitchbotDeviceWoSensorTH extends SwitchbotDevice { } -export default SwitchbotDeviceWoSensorTH; \ No newline at end of file +module.exports = SwitchbotDeviceWoSensorTH; \ No newline at end of file diff --git a/lib/switchbot-device.js b/lib/switchbot-device.js index da8ca62f..ca2ba5ca 100644 --- a/lib/switchbot-device.js +++ b/lib/switchbot-device.js @@ -6,8 +6,8 @@ * Date: 2020-02-19 * ---------------------------------------------------------------- */ 'use strict'; -import { check, error as _error } from './parameter-checker.js'; -import { parse } from './switchbot-advertising.js'; +const parameterChecker = require('./parameter-checker.js'); +const switchbotAdvertising = require('./switchbot-advertising.js'); class SwitchbotDevice { /* ------------------------------------------------------------------ @@ -16,6 +16,7 @@ class SwitchbotDevice { * [Arguments] * - peripheral | Object | Required | The `peripheral` object of noble, * | | | which represents this device + * - noble | Noble | Required | The Nobel object created by the noble module. * ---------------------------------------------------------------- */ constructor(peripheral, noble) { this._peripheral = peripheral; @@ -32,7 +33,7 @@ class SwitchbotDevice { this._COMMAND_TIMEOUT_MSEC = 3000; // Save the device information - let ad = parse(peripheral); + let ad = switchbotAdvertising.parse(peripheral); this._id = ad.id; this._address = ad.address; this._model = ad.serviceData.model; @@ -374,12 +375,12 @@ class SwitchbotDevice { setDeviceName(name) { return new Promise((resolve, reject) => { // Check the parameters - let valid = check({ name: name }, { + let valid = parameterChecker.check({ name: name }, { name: { required: true, type: 'string', minBytes: 1, maxBytes: 100 } }); if (!valid) { - reject(new Error(_error.message)); + reject(new Error(parameterChecker.error.message)); return; } @@ -494,4 +495,4 @@ class SwitchbotDevice { } -export default SwitchbotDevice; \ No newline at end of file +module.exports = SwitchbotDevice; \ No newline at end of file diff --git a/lib/switchbot.js b/lib/switchbot.js index 0a1c8b2b..d99f9951 100644 --- a/lib/switchbot.js +++ b/lib/switchbot.js @@ -6,13 +6,15 @@ * Date: 2019-11-18 * ---------------------------------------------------------------- */ 'use strict'; -import { check, error as _error } from './parameter-checker.js'; -import { parse } from './switchbot-advertising.js'; +const parameterChecker = require('./parameter-checker.js'); +const switchbotAdvertising = require('./switchbot-advertising.js'); -import SwitchbotDevice from './switchbot-device.js'; -import SwitchbotDeviceWoHand from './switchbot-device-wohand.js'; -import SwitchbotDeviceWoSensorTH from './switchbot-device-wosensorth.js'; -import SwitchbotDeviceWoCurtain from './switchbot-device-wocurtain.js'; +const SwitchbotDevice = require('./switchbot-device.js'); +const SwitchbotDeviceWoHand = require('./switchbot-device-wohand.js'); +const SwitchbotDeviceWoCurtain = require('./switchbot-device-wocurtain.js'); +const SwitchbotDeviceWoSensorMS = require('./switchbot-device-wosensorms.js'); +const SwitchbotDeviceWoSensorCS = require('./switchbot-device-wosensorcs.js'); +const SwitchbotDeviceWoSensorTH = require('./switchbot-device-wosensorth.js'); class Switchbot { /* ------------------------------------------------------------------ @@ -40,7 +42,6 @@ class Switchbot { this.onadvertisement = null; // Private properties - this._initialized = false; this._scanning = false; this._DEFAULT_DISCOVERY_DURATION = 5000 this._PRIMARY_SERVICE_UUID_LIST = ['cba20d00224d11e69fb80002a5d5c51b']; @@ -55,11 +56,12 @@ class Switchbot { * - duration | Integer | Optional | Duration for discovery process (msec). * | | | The value must be in the range of 1 to 60000. * | | | The default value is 5000 (msec). - * - model | String | Optional | "H", "T" or "c". - * | | | If "H" is specified, this method will discover - * | | | only Bots. If "T" is specified, this method - * | | | will discover only Meters. If "c" is specified, - * | | | this method will discover only Curtains. + * - model | String | Optional | "H", "T", "M", "CS", or "c". + * | | | If "H" is specified, this method will discover only Bots. + * | | | If "T" is specified, this method will discover only Meters. + * | | | If "M" is specified, this method will discover only Motion Sensors. + * | | | If "CS" is specified, this method will discover only Contact Sensors. + * | | | If "C" is specified, this method will discover only Curtains. * - id | String | Optional | If this value is set, this method willl discover * | | | only a device whose ID is as same as this value. * | | | The ID is identical to the MAC address. @@ -79,15 +81,15 @@ class Switchbot { discover(params = {}) { let promise = new Promise((resolve, reject) => { // Check the parameters - let valid = check(params, { + let valid = parameterChecker.check(params, { duration: { required: false, type: 'integer', min: 1, max: 60000 }, - model: { required: false, type: 'string', enum: ['H', 'T', 'c'] }, + model: { required: false, type: 'string', enum: ['H', 'T', 'M', 'CS', 'c'] }, id: { required: false, type: 'string', min: 12, max: 17 }, quick: { required: false, type: 'boolean' } }, false); if (!valid) { - reject(new Error(_error.message)); + reject(new Error(parameterChecker.error.message)); return; } @@ -181,17 +183,27 @@ class Switchbot { } _getDeviceObject(peripheral, id, model) { - let ad = parse(peripheral); + let ad = switchbotAdvertising.parse(peripheral); if (this._filterAdvertising(ad, id, model)) { let device = null; - if (ad.serviceData.model === 'H') { - device = new SwitchbotDeviceWoHand(peripheral); - } else if (ad.serviceData.model === 'T') { - device = new SwitchbotDeviceWoSensorTH(peripheral); - } else if (ad.serviceData.model === 'c') { - device = new SwitchbotDeviceWoCurtain(peripheral); - } else { - device = new SwitchbotDevice(peripheral); + switch (ad.serviceData.model) { + case 'H': + device = new SwitchbotDeviceWoHand(peripheral, this.noble); + break; + case 'T': + device = new SwitchbotDeviceWoSensorTH(peripheral, this.noble); + break; + case 'M': + device = new SwitchbotDeviceWoSensorMS(peripheral, this.noble); + break; + case 'CS': + device = new SwitchbotDeviceWoSensorCS(peripheral, this.noble); + break; + case 'c': + device = new SwitchbotDeviceWoCurtain(peripheral, this.noble); + break; + default: // 'resetting', 'unknown' + device = new SwitchbotDevice(peripheral, this.noble); } return device; } else { @@ -222,15 +234,21 @@ class Switchbot { * - Start to monitor advertising packets coming from switchbot devices * * [Arguments] - * - params | Object | Optional | - * - model | String | Optional | "H", or "T" or "c". + * - params | Object | Optional | + * - model | String | Optional | "H", "T", "M", "CS", or "C". * | | | If "H" is specified, the `onadvertisement` * | | | event hander will be called only when advertising * | | | packets comes from Bots. * | | | If "T" is specified, the `onadvertisement` * | | | event hander will be called only when advertising * | | | packets comes from Meters. - * | | | If "c" is specified, the `onadvertisement` + * | | | If "M" is specified, the `onadvertisement` + * | | | event hander will be called only when advertising + * | | | packets comes from Motion Sensor. + * | | | If "CS" is specified, the `onadvertisement` + * | | | event hander will be called only when advertising + * | | | packets comes from Contact Sensor. + * | | | If "C" is specified, the `onadvertisement` * | | | event hander will be called only when advertising * | | | packets comes from Curtains. * - id | String | Optional | If this value is set, the `onadvertisement` @@ -248,13 +266,13 @@ class Switchbot { startScan(params) { let promise = new Promise((resolve, reject) => { // Check the parameters - let valid = check(params, { - model: { required: false, type: 'string', enum: ['H', 'T', 'c'] }, + let valid = parameterChecker.check(params, { + model: { required: false, type: 'string', enum: ['H', 'T', 'M', 'CS', 'c'] }, id: { required: false, type: 'string', min: 12, max: 17 }, }, false); if (!valid) { - reject(new Error(_error.message)); + reject(new Error(parameterChecker.error.message)); return; } @@ -273,7 +291,7 @@ class Switchbot { // Set an handler for the 'discover' event this.noble.on('discover', (peripheral) => { - let ad = parse(peripheral); + let ad = switchbotAdvertising.parse(peripheral); if (this._filterAdvertising(ad, p.id, p.model)) { if (this.onadvertisement && typeof (this.onadvertisement) === 'function') { this.onadvertisement(ad); @@ -325,12 +343,12 @@ class Switchbot { wait(msec) { return new Promise((resolve, reject) => { // Check the parameters - let valid = check({ msec: msec }, { + let valid = parameterChecker.check({ msec: msec }, { msec: { required: true, type: 'integer', min: 0 } }); if (!valid) { - reject(new Error(_error.message)); + reject(new Error(parameterChecker.error.message)); return; } // Set a timer @@ -340,4 +358,4 @@ class Switchbot { } -export default Switchbot; +module.exports = Switchbot; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 1f69644d..28bd233f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { "name": "node-switchbot", - "version": "1.0.2", + "version": "1.0.3", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "1.0.2", + "version": "1.0.3", "license": "MIT", "dependencies": { "@abandonware/noble": ">=1.9.2-14" diff --git a/package.json b/package.json index b55c8331..33906fba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-switchbot", - "version": "1.0.2", + "version": "1.0.3", "description": "The node-switchbot is a Node.js module which allows you to move your Switchbot (Bot)'s arm and Switchbot Curtain(Curtain), also monitor the temperature/humidity from SwitchBot Thermometer & Hygrometer (Meter).", "main": "./lib/switchbot.js", "files": [