node-switchbot 2.5.0-beta.30 → 2.5.0-beta.31
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/BLE.md +10 -10
- package/OpenAPI.md +6 -6
- package/dist/advertising.d.ts +3 -3
- package/dist/advertising.d.ts.map +1 -1
- package/dist/advertising.js +25 -26
- package/dist/advertising.js.map +1 -1
- package/dist/device/woblindtilt.d.ts +3 -2
- package/dist/device/woblindtilt.d.ts.map +1 -1
- package/dist/device/woblindtilt.js +3 -7
- package/dist/device/woblindtilt.js.map +1 -1
- package/dist/device/wobulb.d.ts +3 -2
- package/dist/device/wobulb.d.ts.map +1 -1
- package/dist/device/wobulb.js +4 -8
- package/dist/device/wobulb.js.map +1 -1
- package/dist/device/woceilinglight.d.ts +4 -4
- package/dist/device/woceilinglight.d.ts.map +1 -1
- package/dist/device/woceilinglight.js +5 -10
- package/dist/device/woceilinglight.js.map +1 -1
- package/dist/device/wocontact.d.ts +3 -2
- package/dist/device/wocontact.d.ts.map +1 -1
- package/dist/device/wocontact.js +3 -3
- package/dist/device/wocontact.js.map +1 -1
- package/dist/device/wocurtain.d.ts +3 -2
- package/dist/device/wocurtain.d.ts.map +1 -1
- package/dist/device/wocurtain.js +3 -7
- package/dist/device/wocurtain.js.map +1 -1
- package/dist/device/wohand.d.ts +3 -2
- package/dist/device/wohand.d.ts.map +1 -1
- package/dist/device/wohand.js +3 -7
- package/dist/device/wohand.js.map +1 -1
- package/dist/device/wohub2.d.ts +3 -2
- package/dist/device/wohub2.d.ts.map +1 -1
- package/dist/device/wohub2.js +3 -3
- package/dist/device/wohub2.js.map +1 -1
- package/dist/device/wohumi.d.ts +3 -2
- package/dist/device/wohumi.d.ts.map +1 -1
- package/dist/device/wohumi.js +3 -7
- package/dist/device/wohumi.js.map +1 -1
- package/dist/device/woiosensorth.d.ts +3 -2
- package/dist/device/woiosensorth.d.ts.map +1 -1
- package/dist/device/woiosensorth.js +4 -4
- package/dist/device/woiosensorth.js.map +1 -1
- package/dist/device/woplugmini.d.ts +4 -5
- package/dist/device/woplugmini.d.ts.map +1 -1
- package/dist/device/woplugmini.js +7 -13
- package/dist/device/woplugmini.js.map +1 -1
- package/dist/device/wopresence.d.ts +3 -2
- package/dist/device/wopresence.d.ts.map +1 -1
- package/dist/device/wopresence.js +3 -3
- package/dist/device/wopresence.js.map +1 -1
- package/dist/device/wosensorth.d.ts +4 -4
- package/dist/device/wosensorth.d.ts.map +1 -1
- package/dist/device/wosensorth.js +5 -6
- package/dist/device/wosensorth.js.map +1 -1
- package/dist/device/wosmartlock.d.ts +3 -1
- package/dist/device/wosmartlock.d.ts.map +1 -1
- package/dist/device/wosmartlock.js +3 -2
- package/dist/device/wosmartlock.js.map +1 -1
- package/dist/device/wosmartlockpro.d.ts +3 -1
- package/dist/device/wosmartlockpro.d.ts.map +1 -1
- package/dist/device/wosmartlockpro.js +3 -2
- package/dist/device/wosmartlockpro.js.map +1 -1
- package/dist/device/wostrip.d.ts +3 -2
- package/dist/device/wostrip.d.ts.map +1 -1
- package/dist/device/wostrip.js +3 -3
- package/dist/device/wostrip.js.map +1 -1
- package/dist/switchbot-ble.d.ts +9 -2
- package/dist/switchbot-ble.d.ts.map +1 -1
- package/dist/switchbot-ble.js +20 -4
- package/dist/switchbot-ble.js.map +1 -1
- package/dist/test/advertising.test.js +1 -1
- package/dist/test/advertising.test.js.map +1 -1
- package/dist/test/device.test.js +0 -22
- package/dist/test/device.test.js.map +1 -1
- package/dist/test/index.test.js +1 -0
- package/dist/test/index.test.js.map +1 -1
- package/dist/test/settings.test.js +1 -0
- package/dist/test/settings.test.js.map +1 -1
- package/dist/test/switchbot-openapi.test.js +1 -0
- package/dist/test/switchbot-openapi.test.js.map +1 -1
- package/dist/test/woblindtilt.test.js +1 -96
- package/dist/test/woblindtilt.test.js.map +1 -1
- package/dist/test/wobulb.test.js +1 -103
- package/dist/test/wobulb.test.js.map +1 -1
- package/dist/test/woceilinglight.test.js +1 -94
- package/dist/test/woceilinglight.test.js.map +1 -1
- package/dist/test/wocontact.test.js +1 -37
- package/dist/test/wocontact.test.js.map +1 -1
- package/dist/test/wocurtain.test.js +1 -75
- package/dist/test/wocurtain.test.js.map +1 -1
- package/dist/test/wohand.test.js +1 -75
- package/dist/test/wohand.test.js.map +1 -1
- package/dist/test/wohub2.test.js +1 -51
- package/dist/test/wohub2.test.js.map +1 -1
- package/dist/test/wohumi.test.js +1 -63
- package/dist/test/wohumi.test.js.map +1 -1
- package/dist/test/woiosensorth.test.js +1 -40
- package/dist/test/woiosensorth.test.js.map +1 -1
- package/dist/test/woplugmini.test.js +1 -95
- package/dist/test/woplugmini.test.js.map +1 -1
- package/dist/test/wopresence.test.js +1 -45
- package/dist/test/wopresence.test.js.map +1 -1
- package/dist/test/wosensorth.test.js +1 -49
- package/dist/test/wosensorth.test.js.map +1 -1
- package/dist/test/wosmartlock.test.js +1 -146
- package/dist/test/wosmartlock.test.js.map +1 -1
- package/dist/test/wosmartlockpro.test.js +1 -127
- package/dist/test/wosmartlockpro.test.js.map +1 -1
- package/dist/test/wostrip.test.js +1 -113
- package/dist/test/wostrip.test.js.map +1 -1
- package/package.json +8 -8
package/dist/test/wohumi.test.js
CHANGED
|
@@ -1,64 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
*
|
|
3
|
-
* wohumi.test.ts: Switchbot BLE API registration.
|
|
4
|
-
*/
|
|
5
|
-
import { Buffer } from 'node:buffer';
|
|
6
|
-
import * as Noble from '@stoprocent/noble';
|
|
7
|
-
import { WoHumi } from '../device/wohumi.js';
|
|
8
|
-
jest.mock('../device.js', () => {
|
|
9
|
-
return {
|
|
10
|
-
SwitchbotDevice: jest.fn().mockImplementation(() => {
|
|
11
|
-
return {
|
|
12
|
-
command: jest.fn(),
|
|
13
|
-
};
|
|
14
|
-
}),
|
|
15
|
-
};
|
|
16
|
-
});
|
|
17
|
-
describe('woHumi', () => {
|
|
18
|
-
let wohumi;
|
|
19
|
-
beforeEach(() => {
|
|
20
|
-
const peripheral = {}; // Replace with the actual peripheral object (e.g. from Noble)
|
|
21
|
-
wohumi = new WoHumi(peripheral, Noble);
|
|
22
|
-
});
|
|
23
|
-
it('press should call operateHumi with correct bytes', async () => {
|
|
24
|
-
const operateHumiSpy = jest.spyOn(wohumi, 'operateHumi');
|
|
25
|
-
await wohumi.press();
|
|
26
|
-
expect(operateHumiSpy).toHaveBeenCalledWith([0x57, 0x01, 0x00]);
|
|
27
|
-
});
|
|
28
|
-
it('turnOn should call operateHumi with correct bytes', async () => {
|
|
29
|
-
const operateHumiSpy = jest.spyOn(wohumi, 'operateHumi');
|
|
30
|
-
await wohumi.turnOn();
|
|
31
|
-
expect(operateHumiSpy).toHaveBeenCalledWith([0x57, 0x01, 0x01]);
|
|
32
|
-
});
|
|
33
|
-
it('turnOff should call operateHumi with correct bytes', async () => {
|
|
34
|
-
const operateHumiSpy = jest.spyOn(wohumi, 'operateHumi');
|
|
35
|
-
await wohumi.turnOff();
|
|
36
|
-
expect(operateHumiSpy).toHaveBeenCalledWith([0x57, 0x01, 0x02]);
|
|
37
|
-
});
|
|
38
|
-
it('down should call operateHumi with correct bytes', async () => {
|
|
39
|
-
const operateHumiSpy = jest.spyOn(wohumi, 'operateHumi');
|
|
40
|
-
await wohumi.down();
|
|
41
|
-
expect(operateHumiSpy).toHaveBeenCalledWith([0x57, 0x01, 0x03]);
|
|
42
|
-
});
|
|
43
|
-
it('up should call operateHumi with correct bytes', async () => {
|
|
44
|
-
const operateHumiSpy = jest.spyOn(wohumi, 'operateHumi');
|
|
45
|
-
await wohumi.up();
|
|
46
|
-
expect(operateHumiSpy).toHaveBeenCalledWith([0x57, 0x01, 0x04]);
|
|
47
|
-
});
|
|
48
|
-
it('operateHumi should handle successful response', async () => {
|
|
49
|
-
const mockCommand = wohumi.command;
|
|
50
|
-
mockCommand.mockResolvedValue(Buffer.from([0x01, 0x00, 0x00]));
|
|
51
|
-
await expect(wohumi.operateHumi([0x57, 0x01, 0x00])).resolves.toBeUndefined();
|
|
52
|
-
});
|
|
53
|
-
it('operateHumi should handle error response', async () => {
|
|
54
|
-
const mockCommand = wohumi.command;
|
|
55
|
-
mockCommand.mockResolvedValue(Buffer.from([0x02, 0x00, 0x00]));
|
|
56
|
-
await expect(wohumi.operateHumi([0x57, 0x01, 0x00])).rejects.toThrow('The device returned an error: 0x020000');
|
|
57
|
-
});
|
|
58
|
-
it('operateHumi should handle command rejection', async () => {
|
|
59
|
-
const mockCommand = wohumi.command;
|
|
60
|
-
mockCommand.mockRejectedValue(new Error('Command failed'));
|
|
61
|
-
await expect(wohumi.operateHumi([0x57, 0x01, 0x00])).rejects.toThrow('Command failed');
|
|
62
|
-
});
|
|
63
|
-
});
|
|
1
|
+
export {};
|
|
64
2
|
//# sourceMappingURL=wohumi.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wohumi.test.js","sourceRoot":"","sources":["../../src/test/wohumi.test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"wohumi.test.js","sourceRoot":"","sources":["../../src/test/wohumi.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,41 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
*
|
|
3
|
-
* woiosensorth.test.ts: Switchbot BLE API registration.
|
|
4
|
-
*/
|
|
5
|
-
import { Buffer } from 'node:buffer';
|
|
6
|
-
import { WoIOSensorTH } from '../device/woiosensorth.js';
|
|
7
|
-
describe('woIOSensorTH', () => {
|
|
8
|
-
const validServiceData = Buffer.from([0x00, 0x00, 0x7F]);
|
|
9
|
-
const validManufacturerData = Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x8F, 0x50, 0x00]);
|
|
10
|
-
const invalidServiceData = Buffer.from([0x00, 0x00]);
|
|
11
|
-
const invalidManufacturerData = Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A]);
|
|
12
|
-
it('should return null for incorrect serviceData length', async () => {
|
|
13
|
-
const result = await WoIOSensorTH.parseServiceData(invalidServiceData, validManufacturerData);
|
|
14
|
-
expect(result).toBeNull();
|
|
15
|
-
});
|
|
16
|
-
it('should return null for incorrect manufacturerData length', async () => {
|
|
17
|
-
const result = await WoIOSensorTH.parseServiceData(validServiceData, invalidManufacturerData);
|
|
18
|
-
expect(result).toBeNull();
|
|
19
|
-
});
|
|
20
|
-
it('should return correct parsed data for valid inputs', async () => {
|
|
21
|
-
const result = await WoIOSensorTH.parseServiceData(validServiceData, validManufacturerData);
|
|
22
|
-
expect(result).toEqual({
|
|
23
|
-
model: 'OutdoorMeter',
|
|
24
|
-
modelName: 'OutdoorMeter',
|
|
25
|
-
modelFriendlyName: 'OutdoorMeter',
|
|
26
|
-
celsius: 1.5,
|
|
27
|
-
fahrenheit: 34.7,
|
|
28
|
-
fahrenheit_mode: true,
|
|
29
|
-
humidity: 80,
|
|
30
|
-
battery: 127,
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
it('should log messages for incorrect data lengths', async () => {
|
|
34
|
-
const onlog = jest.fn();
|
|
35
|
-
await WoIOSensorTH.parseServiceData(invalidServiceData, validManufacturerData, onlog);
|
|
36
|
-
expect(onlog).toHaveBeenCalledWith('[parseServiceDataForWoIOSensorTH] Service Data Buffer length 2 !== 3!');
|
|
37
|
-
await WoIOSensorTH.parseServiceData(validServiceData, invalidManufacturerData, onlog);
|
|
38
|
-
expect(onlog).toHaveBeenCalledWith('[parseServiceDataForWoIOSensorTH] Manufacturer Data Buffer length 11 !== 14!');
|
|
39
|
-
});
|
|
40
|
-
});
|
|
1
|
+
export {};
|
|
41
2
|
//# sourceMappingURL=woiosensorth.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"woiosensorth.test.js","sourceRoot":"","sources":["../../src/test/woiosensorth.test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"woiosensorth.test.js","sourceRoot":"","sources":["../../src/test/woiosensorth.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,96 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
*
|
|
3
|
-
* woplugmini.test.ts: Switchbot BLE API registration.
|
|
4
|
-
*/
|
|
5
|
-
import { Buffer } from 'node:buffer';
|
|
6
|
-
import * as Noble from '@stoprocent/noble';
|
|
7
|
-
import { WoPlugMini } from '../device/woplugmini.js';
|
|
8
|
-
import { SwitchBotBLEModel, SwitchBotBLEModelFriendlyName, SwitchBotBLEModelName } from '../types/types.js';
|
|
9
|
-
describe('woPlugMini', () => {
|
|
10
|
-
let manufacturerData;
|
|
11
|
-
let onlog;
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
onlog = jest.fn();
|
|
14
|
-
});
|
|
15
|
-
describe('parseServiceData_US', () => {
|
|
16
|
-
it('should return null if manufacturerData length is not 14', async () => {
|
|
17
|
-
manufacturerData = Buffer.alloc(13);
|
|
18
|
-
const result = await WoPlugMini.parseServiceData_US(manufacturerData, onlog);
|
|
19
|
-
expect(result).toBeNull();
|
|
20
|
-
expect(onlog).toHaveBeenCalledWith('[parseServiceDataForWoPlugMini] Buffer length 13 should be 14');
|
|
21
|
-
});
|
|
22
|
-
it('should parse the service data correctly', async () => {
|
|
23
|
-
manufacturerData = Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x07, 0x64, 0x80, 0x40, 0x01]);
|
|
24
|
-
const result = await WoPlugMini.parseServiceData_US(manufacturerData, onlog);
|
|
25
|
-
expect(result).toEqual({
|
|
26
|
-
model: SwitchBotBLEModel.PlugMiniUS,
|
|
27
|
-
modelName: SwitchBotBLEModelName.PlugMini,
|
|
28
|
-
modelFriendlyName: SwitchBotBLEModelFriendlyName.PlugMini,
|
|
29
|
-
state: 'on',
|
|
30
|
-
delay: true,
|
|
31
|
-
timer: true,
|
|
32
|
-
syncUtcTime: false,
|
|
33
|
-
wifiRssi: 100,
|
|
34
|
-
overload: true,
|
|
35
|
-
currentPower: 32.1,
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
describe('parseServiceData_JP', () => {
|
|
40
|
-
it('should return null if manufacturerData length is not 14', async () => {
|
|
41
|
-
manufacturerData = Buffer.alloc(13);
|
|
42
|
-
const result = await WoPlugMini.parseServiceData_JP(manufacturerData, onlog);
|
|
43
|
-
expect(result).toBeNull();
|
|
44
|
-
expect(onlog).toHaveBeenCalledWith('[parseServiceDataForWoPlugMini] Buffer length 13 should be 14');
|
|
45
|
-
});
|
|
46
|
-
it('should parse the service data correctly', async () => {
|
|
47
|
-
manufacturerData = Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x07, 0x64, 0x80, 0x40, 0x01]);
|
|
48
|
-
const result = await WoPlugMini.parseServiceData_JP(manufacturerData, onlog);
|
|
49
|
-
expect(result).toEqual({
|
|
50
|
-
model: SwitchBotBLEModel.PlugMiniJP,
|
|
51
|
-
modelName: SwitchBotBLEModelName.PlugMini,
|
|
52
|
-
modelFriendlyName: SwitchBotBLEModelFriendlyName.PlugMini,
|
|
53
|
-
state: 'on',
|
|
54
|
-
delay: true,
|
|
55
|
-
timer: true,
|
|
56
|
-
syncUtcTime: false,
|
|
57
|
-
wifiRssi: 100,
|
|
58
|
-
overload: true,
|
|
59
|
-
currentPower: 32.1,
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
describe('state operations', () => {
|
|
64
|
-
let plugMini;
|
|
65
|
-
beforeEach(() => {
|
|
66
|
-
const peripheral = {}; // Replace with the actual peripheral object (e.g. from Noble)
|
|
67
|
-
plugMini = new WoPlugMini(peripheral, Noble);
|
|
68
|
-
jest.spyOn(plugMini, 'operatePlug').mockImplementation(async (bytes) => {
|
|
69
|
-
if (bytes.includes(0x80)) {
|
|
70
|
-
return true;
|
|
71
|
-
}
|
|
72
|
-
if (bytes.includes(0x00)) {
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
return true;
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
it('should read state correctly', async () => {
|
|
79
|
-
const result = await plugMini.readState();
|
|
80
|
-
expect(result).toBe(true);
|
|
81
|
-
});
|
|
82
|
-
it('should turn on correctly', async () => {
|
|
83
|
-
const result = await plugMini.turnOn();
|
|
84
|
-
expect(result).toBe(true);
|
|
85
|
-
});
|
|
86
|
-
it('should turn off correctly', async () => {
|
|
87
|
-
const result = await plugMini.turnOff();
|
|
88
|
-
expect(result).toBe(false);
|
|
89
|
-
});
|
|
90
|
-
it('should toggle correctly', async () => {
|
|
91
|
-
const result = await plugMini.toggle();
|
|
92
|
-
expect(result).toBe(true);
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
});
|
|
1
|
+
export {};
|
|
96
2
|
//# sourceMappingURL=woplugmini.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"woplugmini.test.js","sourceRoot":"","sources":["../../src/test/woplugmini.test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"woplugmini.test.js","sourceRoot":"","sources":["../../src/test/woplugmini.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,46 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
*
|
|
3
|
-
* wopresence.test.ts: Switchbot BLE API registration.
|
|
4
|
-
*/
|
|
5
|
-
import { Buffer } from 'node:buffer';
|
|
6
|
-
import { WoPresence } from '../device/wopresence.js';
|
|
7
|
-
import { SwitchBotBLEModel, SwitchBotBLEModelFriendlyName, SwitchBotBLEModelName } from '../types/types.js';
|
|
8
|
-
describe('woPresence', () => {
|
|
9
|
-
describe('parseServiceData', () => {
|
|
10
|
-
it('should return null if serviceData length is not 6', async () => {
|
|
11
|
-
const serviceData = Buffer.from([0x01, 0x02, 0x03, 0x04, 0x05]);
|
|
12
|
-
const onlog = jest.fn();
|
|
13
|
-
const result = await WoPresence.parseServiceData(serviceData, onlog);
|
|
14
|
-
expect(result).toBeNull();
|
|
15
|
-
expect(onlog).toHaveBeenCalledWith('[parseServiceDataForWoPresence] Buffer length 5 !== 6!');
|
|
16
|
-
});
|
|
17
|
-
it('should parse serviceData correctly', async () => {
|
|
18
|
-
const serviceData = Buffer.from([0x00, 0b11000000, 0b01111111, 0x00, 0x00, 0b00111111]);
|
|
19
|
-
const onlog = jest.fn();
|
|
20
|
-
const result = await WoPresence.parseServiceData(serviceData, onlog);
|
|
21
|
-
expect(result).toEqual({
|
|
22
|
-
model: SwitchBotBLEModel.MotionSensor,
|
|
23
|
-
modelName: SwitchBotBLEModelName.MotionSensor,
|
|
24
|
-
modelFriendlyName: SwitchBotBLEModelFriendlyName.MotionSensor,
|
|
25
|
-
tested: true,
|
|
26
|
-
movement: true,
|
|
27
|
-
battery: 127,
|
|
28
|
-
led: 1,
|
|
29
|
-
iot: 1,
|
|
30
|
-
sense_distance: 3,
|
|
31
|
-
lightLevel: 'unknown',
|
|
32
|
-
is_light: true,
|
|
33
|
-
});
|
|
34
|
-
expect(onlog).not.toHaveBeenCalled();
|
|
35
|
-
});
|
|
36
|
-
it('should handle different light levels correctly', async () => {
|
|
37
|
-
const serviceDataDark = Buffer.from([0x00, 0b11000000, 0b01111111, 0x00, 0x00, 0b00111101]);
|
|
38
|
-
const serviceDataBright = Buffer.from([0x00, 0b11000000, 0b01111111, 0x00, 0x00, 0b00111110]);
|
|
39
|
-
const resultDark = await WoPresence.parseServiceData(serviceDataDark, undefined);
|
|
40
|
-
const resultBright = await WoPresence.parseServiceData(serviceDataBright, undefined);
|
|
41
|
-
expect(resultDark?.lightLevel).toBe('dark');
|
|
42
|
-
expect(resultBright?.lightLevel).toBe('bright');
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
});
|
|
1
|
+
export {};
|
|
46
2
|
//# sourceMappingURL=wopresence.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wopresence.test.js","sourceRoot":"","sources":["../../src/test/wopresence.test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"wopresence.test.js","sourceRoot":"","sources":["../../src/test/wopresence.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,50 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import { WoSensorTH } from '../device/wosensorth.js';
|
|
3
|
-
import { SwitchBotBLEModel, SwitchBotBLEModelFriendlyName, SwitchBotBLEModelName } from '../types/types.js';
|
|
4
|
-
describe('woSensorTH', () => {
|
|
5
|
-
it('should parse service data correctly for Meter', async () => {
|
|
6
|
-
const serviceData = Buffer.from([0x00, 0x00, 0x7F, 0x0A, 0x81, 0x80]);
|
|
7
|
-
const expectedData = {
|
|
8
|
-
model: SwitchBotBLEModel.Meter,
|
|
9
|
-
modelName: SwitchBotBLEModelName.Meter,
|
|
10
|
-
modelFriendlyName: SwitchBotBLEModelFriendlyName.Meter,
|
|
11
|
-
celsius: -1.0,
|
|
12
|
-
fahrenheit: 30.2,
|
|
13
|
-
fahrenheit_mode: true,
|
|
14
|
-
humidity: 0,
|
|
15
|
-
battery: 127,
|
|
16
|
-
};
|
|
17
|
-
const result = await WoSensorTH.parseServiceData(serviceData);
|
|
18
|
-
expect(result).toEqual(expectedData);
|
|
19
|
-
});
|
|
20
|
-
it('should parse service data correctly for MeterPlus', async () => {
|
|
21
|
-
const serviceData = Buffer.from([0x00, 0x00, 0x7F, 0x0A, 0x81, 0x80]);
|
|
22
|
-
const expectedData = {
|
|
23
|
-
model: SwitchBotBLEModel.MeterPlus,
|
|
24
|
-
modelName: SwitchBotBLEModelName.MeterPlus,
|
|
25
|
-
modelFriendlyName: SwitchBotBLEModelFriendlyName.MeterPlus,
|
|
26
|
-
celsius: -1.0,
|
|
27
|
-
fahrenheit: 30.2,
|
|
28
|
-
fahrenheit_mode: true,
|
|
29
|
-
humidity: 0,
|
|
30
|
-
battery: 127,
|
|
31
|
-
};
|
|
32
|
-
const result = await WoSensorTH.parseServiceData_Plus(serviceData);
|
|
33
|
-
expect(result).toEqual(expectedData);
|
|
34
|
-
});
|
|
35
|
-
it('should log an error if service data length is incorrect for Meter', async () => {
|
|
36
|
-
const serviceData = Buffer.from([0x00, 0x00, 0x7F]);
|
|
37
|
-
const mockLog = jest.fn();
|
|
38
|
-
const result = await WoSensorTH.parseServiceData(serviceData, mockLog);
|
|
39
|
-
expect(result).toBeNull();
|
|
40
|
-
expect(mockLog).toHaveBeenCalledWith('[parseServiceDataForWoSensorTH] Buffer length 3 !== 6!');
|
|
41
|
-
});
|
|
42
|
-
it('should log an error if service data length is incorrect for MeterPlus', async () => {
|
|
43
|
-
const serviceData = Buffer.from([0x00, 0x00, 0x7F]);
|
|
44
|
-
const mockLog = jest.fn();
|
|
45
|
-
const result = await WoSensorTH.parseServiceData_Plus(serviceData, mockLog);
|
|
46
|
-
expect(result).toBeNull();
|
|
47
|
-
expect(mockLog).toHaveBeenCalledWith('[parseServiceDataForWoSensorTHPlus] Buffer length 3 !== 6!');
|
|
48
|
-
});
|
|
49
|
-
});
|
|
1
|
+
export {};
|
|
50
2
|
//# sourceMappingURL=wosensorth.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wosensorth.test.js","sourceRoot":"","sources":["../../src/test/wosensorth.test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"wosensorth.test.js","sourceRoot":"","sources":["../../src/test/wosensorth.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,147 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
*
|
|
3
|
-
* wosmartlock.test.ts: Switchbot BLE API registration.
|
|
4
|
-
*/
|
|
5
|
-
import { Buffer } from 'node:buffer';
|
|
6
|
-
import * as Noble from '@stoprocent/noble';
|
|
7
|
-
import sinon from 'sinon';
|
|
8
|
-
import { WoSmartLock } from '../device/wosmartlock.js';
|
|
9
|
-
describe('woSmartLock', () => {
|
|
10
|
-
let lock;
|
|
11
|
-
let mockPeripheral;
|
|
12
|
-
let mockNoble;
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
mockPeripheral = {};
|
|
15
|
-
mockNoble = sinon.stub(Noble);
|
|
16
|
-
lock = new WoSmartLock(mockPeripheral, mockNoble);
|
|
17
|
-
});
|
|
18
|
-
afterEach(() => {
|
|
19
|
-
sinon.restore();
|
|
20
|
-
});
|
|
21
|
-
describe('getLockStatus', () => {
|
|
22
|
-
it('should return correct lock status', () => {
|
|
23
|
-
expect(WoSmartLock.getLockStatus(0b0000000)).toBe('LOCKED');
|
|
24
|
-
expect(WoSmartLock.getLockStatus(0b0010000)).toBe('UNLOCKED');
|
|
25
|
-
expect(WoSmartLock.getLockStatus(0b0100000)).toBe('LOCKING');
|
|
26
|
-
expect(WoSmartLock.getLockStatus(0b0110000)).toBe('UNLOCKING');
|
|
27
|
-
expect(WoSmartLock.getLockStatus(0b1000000)).toBe('LOCKING_STOP');
|
|
28
|
-
expect(WoSmartLock.getLockStatus(0b1010000)).toBe('UNLOCKING_STOP');
|
|
29
|
-
expect(WoSmartLock.getLockStatus(0b1100000)).toBe('NOT_FULLY_LOCKED');
|
|
30
|
-
expect(WoSmartLock.getLockStatus(0b1110000)).toBe('UNKNOWN');
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
describe('parseServiceData', () => {
|
|
34
|
-
it('should parse service data correctly', async () => {
|
|
35
|
-
const serviceData = Buffer.from([0x00, 0x00, 0x7F, 0x0A, 0x81, 0x80]);
|
|
36
|
-
const manufacturerData = Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20]);
|
|
37
|
-
const expectedData = {
|
|
38
|
-
model: 'Lock',
|
|
39
|
-
modelName: 'Lock',
|
|
40
|
-
modelFriendlyName: 'Lock',
|
|
41
|
-
battery: 127,
|
|
42
|
-
calibration: false,
|
|
43
|
-
status: 'UNLOCKED',
|
|
44
|
-
update_from_secondary_lock: false,
|
|
45
|
-
door_open: false,
|
|
46
|
-
double_lock_mode: false,
|
|
47
|
-
unclosed_alarm: false,
|
|
48
|
-
unlocked_alarm: false,
|
|
49
|
-
auto_lock_paused: false,
|
|
50
|
-
night_latch: false,
|
|
51
|
-
};
|
|
52
|
-
const result = await WoSmartLock.parseServiceData(serviceData, manufacturerData, undefined);
|
|
53
|
-
expect(result).toEqual(expectedData);
|
|
54
|
-
});
|
|
55
|
-
it('should return null if manufacturer data is too short', async () => {
|
|
56
|
-
const serviceData = Buffer.from([0x00, 0x00, 0x7F, 0x0A, 0x81, 0x80]);
|
|
57
|
-
const manufacturerData = Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00]);
|
|
58
|
-
const result = await WoSmartLock.parseServiceData(serviceData, manufacturerData, undefined);
|
|
59
|
-
expect(result).toBeNull();
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
describe('lock and unlock methods', () => {
|
|
63
|
-
beforeEach(() => {
|
|
64
|
-
sinon.stub(lock, 'operateLock').resolves(Buffer.from([0x01]));
|
|
65
|
-
});
|
|
66
|
-
it('should unlock the smart lock', async () => {
|
|
67
|
-
const result = await lock.unlock();
|
|
68
|
-
expect(result).toBe(WoSmartLock.Result.SUCCESS);
|
|
69
|
-
});
|
|
70
|
-
it('should unlock the smart lock without unlatching', async () => {
|
|
71
|
-
const result = await lock.unlockNoUnlatch();
|
|
72
|
-
expect(result).toBe(WoSmartLock.Result.SUCCESS);
|
|
73
|
-
});
|
|
74
|
-
it('should lock the smart lock', async () => {
|
|
75
|
-
const result = await lock.lock();
|
|
76
|
-
expect(result).toBe(WoSmartLock.Result.SUCCESS);
|
|
77
|
-
});
|
|
78
|
-
it('should get lock info', async () => {
|
|
79
|
-
const expectedData = {
|
|
80
|
-
calibration: true,
|
|
81
|
-
status: 'LOCKED',
|
|
82
|
-
door_open: false,
|
|
83
|
-
unclosed_alarm: false,
|
|
84
|
-
unlocked_alarm: false,
|
|
85
|
-
};
|
|
86
|
-
sinon.stub(lock, 'operateLock').resolves(Buffer.from([0x01, 0b10000000, 0b00000000]));
|
|
87
|
-
const result = await lock.info();
|
|
88
|
-
expect(result).toEqual(expectedData);
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
describe('encrypt', () => {
|
|
92
|
-
it('should encrypt a string', async () => {
|
|
93
|
-
const str = 'test';
|
|
94
|
-
lock.encryption_key = Buffer.from('0123456789abcdef0123456789abcdef', 'hex');
|
|
95
|
-
lock.iv = Buffer.from('0123456789abcdef', 'hex');
|
|
96
|
-
const encrypted = await lock.encrypt(str);
|
|
97
|
-
expect(encrypted).toBeInstanceOf(String);
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
describe('decrypt', () => {
|
|
101
|
-
it('should decrypt a buffer', async () => {
|
|
102
|
-
const data = Buffer.from('74657374', 'hex'); // 'test' in hex
|
|
103
|
-
lock.encryption_key = Buffer.from('0123456789abcdef0123456789abcdef', 'hex');
|
|
104
|
-
lock.iv = Buffer.from('0123456789abcdef', 'hex');
|
|
105
|
-
const decrypted = await lock.decrypt(data);
|
|
106
|
-
expect(decrypted.toString()).toBe('test');
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
describe('getIv', () => {
|
|
110
|
-
it('should get the IV', async () => {
|
|
111
|
-
const res = Buffer.from('00000000000000000000000000000000', 'hex');
|
|
112
|
-
sinon.stub(lock, 'operateLock').resolves(res);
|
|
113
|
-
const iv = await lock.getIv();
|
|
114
|
-
expect(iv).toEqual(res.subarray(4));
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
describe('encryptedCommand', () => {
|
|
118
|
-
it('should send an encrypted command', async () => {
|
|
119
|
-
const key = 'testKey';
|
|
120
|
-
const iv = Buffer.from('0123456789abcdef', 'hex');
|
|
121
|
-
const encrypted = 'encryptedString';
|
|
122
|
-
const resBuf = Buffer.from('01000000', 'hex');
|
|
123
|
-
sinon.stub(lock, 'getIv').resolves(iv);
|
|
124
|
-
sinon.stub(lock, 'encrypt').resolves(encrypted);
|
|
125
|
-
sinon.stub(lock, 'command').resolves(resBuf);
|
|
126
|
-
sinon.stub(lock, 'decrypt').resolves(Buffer.from('decrypted', 'hex'));
|
|
127
|
-
const result = await lock.encryptedCommand(key);
|
|
128
|
-
expect(result).toBeInstanceOf(Buffer);
|
|
129
|
-
});
|
|
130
|
-
});
|
|
131
|
-
describe('operateLock', () => {
|
|
132
|
-
it('should operate the lock with encryption', async () => {
|
|
133
|
-
const key = 'testKey';
|
|
134
|
-
sinon.stub(lock, 'encryptedCommand').resolves(Buffer.from('01000000', 'hex'));
|
|
135
|
-
const result = await lock.operateLock(key);
|
|
136
|
-
expect(result).toBeInstanceOf(Buffer);
|
|
137
|
-
});
|
|
138
|
-
it('should operate the lock without encryption', async () => {
|
|
139
|
-
const key = 'testKey';
|
|
140
|
-
const resBuf = Buffer.from('01000000', 'hex');
|
|
141
|
-
sinon.stub(lock, 'command').resolves(resBuf);
|
|
142
|
-
const result = await lock.operateLock(key, false);
|
|
143
|
-
expect(result).toBeInstanceOf(Buffer);
|
|
144
|
-
});
|
|
145
|
-
});
|
|
146
|
-
});
|
|
1
|
+
export {};
|
|
147
2
|
//# sourceMappingURL=wosmartlock.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wosmartlock.test.js","sourceRoot":"","sources":["../../src/test/wosmartlock.test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"wosmartlock.test.js","sourceRoot":"","sources":["../../src/test/wosmartlock.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,128 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
*
|
|
3
|
-
* wosmartlockpro.test.ts: Switchbot BLE API registration.
|
|
4
|
-
*/
|
|
5
|
-
import { Buffer } from 'node:buffer';
|
|
6
|
-
import * as Noble from '@stoprocent/noble';
|
|
7
|
-
import sinon from 'sinon';
|
|
8
|
-
import { WoSmartLockPro } from '../device/wosmartlockpro.js';
|
|
9
|
-
import { WoSmartLockProCommands } from '../settings.js';
|
|
10
|
-
describe('woSmartLockPro', () => {
|
|
11
|
-
let lock;
|
|
12
|
-
let mockPeripheral;
|
|
13
|
-
let mockNoble;
|
|
14
|
-
beforeEach(() => {
|
|
15
|
-
mockPeripheral = {};
|
|
16
|
-
mockNoble = sinon.stub(Noble);
|
|
17
|
-
lock = new WoSmartLockPro(mockPeripheral, mockNoble);
|
|
18
|
-
});
|
|
19
|
-
afterEach(() => {
|
|
20
|
-
sinon.restore();
|
|
21
|
-
});
|
|
22
|
-
describe('setKey', () => {
|
|
23
|
-
it('should set the key id and encryption key', async () => {
|
|
24
|
-
const keyId = 'testKeyId';
|
|
25
|
-
const encryptionKey = '0123456789abcdef0123456789abcdef';
|
|
26
|
-
await lock.setKey(keyId, encryptionKey);
|
|
27
|
-
expect(lock.key_id).toBe(keyId);
|
|
28
|
-
expect(lock.encryption_key?.toString('hex')).toBe(encryptionKey);
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
describe('unlock', () => {
|
|
32
|
-
it('should unlock the smart lock', async () => {
|
|
33
|
-
const operateLockProStub = sinon.stub(lock, 'operateLockPro').resolves(Buffer.from([0x01]));
|
|
34
|
-
const result = await lock.unlock();
|
|
35
|
-
expect(result).toBe(WoSmartLockPro.Result.SUCCESS);
|
|
36
|
-
expect(operateLockProStub.calledOnceWith(WoSmartLockProCommands.UNLOCK)).toBe(true);
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
describe('unlockNoUnlatch', () => {
|
|
40
|
-
it('should unlock the smart lock without unlatching', async () => {
|
|
41
|
-
const operateLockProStub = sinon.stub(lock, 'operateLockPro').resolves(Buffer.from([0x01]));
|
|
42
|
-
const result = await lock.unlockNoUnlatch();
|
|
43
|
-
expect(result).toBe(WoSmartLockPro.Result.SUCCESS);
|
|
44
|
-
expect(operateLockProStub.calledOnceWith(WoSmartLockProCommands.UNLOCK_NO_UNLATCH)).toBe(true);
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
describe('lock', () => {
|
|
48
|
-
it('should lock the smart lock', async () => {
|
|
49
|
-
const operateLockProStub = sinon.stub(lock, 'operateLockPro').resolves(Buffer.from([0x01]));
|
|
50
|
-
const result = await lock.lock();
|
|
51
|
-
expect(result).toBe(WoSmartLockPro.Result.SUCCESS);
|
|
52
|
-
expect(operateLockProStub.calledOnceWith(WoSmartLockProCommands.LOCK)).toBe(true);
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
describe('info', () => {
|
|
56
|
-
it('should get the lock info', async () => {
|
|
57
|
-
const resBuf = Buffer.from([0b10000000, 0b00100000]);
|
|
58
|
-
const operateLockProStub = sinon.stub(lock, 'operateLockPro').resolves(resBuf);
|
|
59
|
-
const result = await lock.info();
|
|
60
|
-
expect(result).toEqual({
|
|
61
|
-
calibration: true,
|
|
62
|
-
status: 'LOCKED',
|
|
63
|
-
door_open: false,
|
|
64
|
-
unclosed_alarm: true,
|
|
65
|
-
unlocked_alarm: false,
|
|
66
|
-
});
|
|
67
|
-
expect(operateLockProStub.calledOnceWith(WoSmartLockProCommands.LOCK_INFO)).toBe(true);
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
describe('encrypt', () => {
|
|
71
|
-
it('should encrypt a string', async () => {
|
|
72
|
-
const str = 'test';
|
|
73
|
-
lock.encryption_key = Buffer.from('0123456789abcdef0123456789abcdef', 'hex');
|
|
74
|
-
lock.iv = Buffer.from('0123456789abcdef', 'hex');
|
|
75
|
-
const encrypted = await lock.encrypt(str);
|
|
76
|
-
expect(typeof encrypted).toBe('string');
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
describe('decrypt', () => {
|
|
80
|
-
it('should decrypt a buffer', async () => {
|
|
81
|
-
const data = Buffer.from('74657374', 'hex'); // 'test' in hex
|
|
82
|
-
lock.encryption_key = Buffer.from('0123456789abcdef0123456789abcdef', 'hex');
|
|
83
|
-
lock.iv = Buffer.from('0123456789abcdef', 'hex');
|
|
84
|
-
const decrypted = await lock.decrypt(data);
|
|
85
|
-
expect(decrypted.toString()).toBe('test');
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
describe('getIv', () => {
|
|
89
|
-
it('should get the IV', async () => {
|
|
90
|
-
const res = Buffer.from('00000000000000000000000000000000', 'hex');
|
|
91
|
-
const operateLockProStub = sinon.stub(lock, 'operateLockPro').resolves(res);
|
|
92
|
-
const iv = await lock.getIv();
|
|
93
|
-
expect(iv).toEqual(res.subarray(4));
|
|
94
|
-
expect(operateLockProStub.calledOnceWith(WoSmartLockProCommands.GET_CKIV + lock.key_id, false)).toBe(true);
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
describe('encryptedCommand', () => {
|
|
98
|
-
it('should send an encrypted command', async () => {
|
|
99
|
-
const key = 'testKey';
|
|
100
|
-
const iv = Buffer.from('0123456789abcdef', 'hex');
|
|
101
|
-
const encrypted = 'encryptedString';
|
|
102
|
-
const resBuf = Buffer.from('01000000', 'hex');
|
|
103
|
-
sinon.stub(lock, 'getIv').resolves(iv);
|
|
104
|
-
sinon.stub(lock, 'encrypt').resolves(encrypted);
|
|
105
|
-
sinon.stub(lock, 'command').resolves(resBuf);
|
|
106
|
-
sinon.stub(lock, 'decrypt').resolves(Buffer.from('decrypted', 'hex'));
|
|
107
|
-
const result = await lock.encryptedCommand(key);
|
|
108
|
-
expect(result).toBeInstanceOf(Buffer);
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
describe('operateLock', () => {
|
|
112
|
-
it('should operate the lock with encryption', async () => {
|
|
113
|
-
const key = 'testKey';
|
|
114
|
-
const encryptedCommandStub = sinon.stub(lock, 'encryptedCommand').resolves(Buffer.from('01000000', 'hex'));
|
|
115
|
-
const result = await lock.operateLockPro(key);
|
|
116
|
-
expect(result).toBeInstanceOf(Buffer);
|
|
117
|
-
expect(encryptedCommandStub.calledOnceWith(key)).toBe(true);
|
|
118
|
-
});
|
|
119
|
-
it('should operate the lock without encryption', async () => {
|
|
120
|
-
const key = 'testKey';
|
|
121
|
-
const resBuf = Buffer.from('01000000', 'hex');
|
|
122
|
-
sinon.stub(lock, 'command').resolves(resBuf);
|
|
123
|
-
const result = await lock.operateLockPro(key, false);
|
|
124
|
-
expect(result).toBeInstanceOf(Buffer);
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
});
|
|
1
|
+
export {};
|
|
128
2
|
//# sourceMappingURL=wosmartlockpro.test.js.map
|