node-switchbot 3.6.0-beta.4 → 3.6.0-beta.6
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/dist/device.d.ts +122 -12
- package/dist/device.d.ts.map +1 -1
- package/dist/device.js +318 -0
- package/dist/device.js.map +1 -1
- package/dist/switchbot-ble.d.ts +0 -6
- package/dist/switchbot-ble.d.ts.map +1 -1
- package/dist/switchbot-ble.js +2 -33
- package/dist/switchbot-ble.js.map +1 -1
- package/dist/types/ble.d.ts +29 -1
- package/dist/types/ble.d.ts.map +1 -1
- package/dist/types/openapi.d.ts +58 -0
- package/dist/types/openapi.d.ts.map +1 -1
- package/dist/types/openapi.js.map +1 -1
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/Advertising.html +4 -4
- package/docs/classes/ErrorUtils.html +5 -5
- package/docs/classes/ParameterChecker.html +10 -10
- package/docs/classes/SwitchBotBLE.html +8 -8
- package/docs/classes/SwitchBotOpenAPI.html +7 -7
- package/docs/classes/SwitchbotDevice.html +12 -12
- package/docs/classes/ValidationUtils.html +8 -8
- package/docs/classes/WoAirPurifier.html +83 -0
- package/docs/classes/WoAirPurifierTable.html +83 -0
- package/docs/classes/WoBlindTilt.html +21 -21
- package/docs/classes/WoBulb.html +19 -19
- package/docs/classes/WoCeilingLight.html +22 -22
- package/docs/classes/WoContact.html +13 -13
- package/docs/classes/WoCurtain.html +18 -18
- package/docs/classes/WoHand.html +18 -18
- package/docs/classes/WoHub2.html +13 -13
- package/docs/classes/WoHumi.html +20 -20
- package/docs/classes/WoHumi2.html +20 -20
- package/docs/classes/WoIOSensorTH.html +13 -13
- package/docs/classes/WoKeypad.html +13 -13
- package/docs/classes/WoLeak.html +13 -13
- package/docs/classes/WoPlugMiniJP.html +18 -18
- package/docs/classes/WoPlugMiniUS.html +18 -18
- package/docs/classes/WoPresence.html +13 -13
- package/docs/classes/WoRelaySwitch1.html +15 -15
- package/docs/classes/WoRelaySwitch1PM.html +15 -15
- package/docs/classes/WoRemote.html +13 -13
- package/docs/classes/WoSensorTH.html +12 -12
- package/docs/classes/WoSensorTHPlus.html +12 -12
- package/docs/classes/WoSensorTHPro.html +12 -12
- package/docs/classes/WoSensorTHProCO2.html +12 -12
- package/docs/classes/WoSmartLock.html +23 -23
- package/docs/classes/WoSmartLockPro.html +23 -23
- package/docs/classes/WoStrip.html +20 -20
- package/docs/enums/LogLevel.html +2 -2
- package/docs/enums/SwitchBotBLEModel.html +4 -2
- package/docs/enums/SwitchBotBLEModelFriendlyName.html +8 -2
- package/docs/enums/SwitchBotBLEModelName.html +4 -2
- package/docs/enums/SwitchBotModel.html +4 -2
- package/docs/functions/updateBaseURL.html +1 -1
- package/docs/hierarchy.html +1 -1
- package/docs/interfaces/AdvertisementData.html +2 -2
- package/docs/interfaces/Chars.html +2 -2
- package/docs/interfaces/ColorLightServiceDataBase.html +2 -2
- package/docs/interfaces/ErrorObject.html +2 -2
- package/docs/interfaces/LockBaseServiceData.html +2 -2
- package/docs/interfaces/NobleTypes.html +2 -3
- package/docs/interfaces/Params.html +2 -2
- package/docs/interfaces/PlugMiniServiceDataBase.html +2 -2
- package/docs/interfaces/Rule.html +2 -2
- package/docs/interfaces/ServiceData.html +2 -2
- package/docs/interfaces/SwitchBotBLEDevice.html +4 -2
- package/docs/interfaces/SwitchBotScanner.html +3 -3
- package/docs/interfaces/TemperatureServiceDataBase.html +2 -2
- package/docs/interfaces/WebhookDetail.html +2 -2
- package/docs/interfaces/ad.html +2 -2
- package/docs/interfaces/body.html +2 -2
- package/docs/interfaces/bodyChange.html +2 -2
- package/docs/interfaces/deleteWebhookResponse.html +2 -2
- package/docs/interfaces/device.html +2 -2
- package/docs/interfaces/deviceList.html +2 -2
- package/docs/interfaces/deviceStatus.html +2 -2
- package/docs/interfaces/deviceStatusRequest.html +2 -2
- package/docs/interfaces/deviceWebhook.html +2 -2
- package/docs/interfaces/deviceWebhookContext.html +2 -2
- package/docs/interfaces/devices.html +2 -2
- package/docs/interfaces/infraredRemoteList.html +2 -2
- package/docs/interfaces/irdevice.html +2 -2
- package/docs/interfaces/pushRequest.html +2 -2
- package/docs/interfaces/pushResponse.html +2 -2
- package/docs/interfaces/pushResponseBody.html +2 -2
- package/docs/interfaces/queryWebhookResponse.html +2 -2
- package/docs/interfaces/setupWebhookResponse.html +2 -2
- package/docs/interfaces/updateWebhookResponse.html +2 -2
- package/docs/interfaces/webhookRequest.html +2 -2
- package/docs/modules.html +1 -1
- package/docs/types/BLEDeviceServiceData.html +1 -1
- package/docs/types/IndoorCam.html +1 -1
- package/docs/types/MacAddress.html +1 -1
- package/docs/types/airPurifier.html +1 -0
- package/docs/types/airPurifierPM25WebhookContext.html +1 -0
- package/docs/types/airPurifierServiceData.html +1 -0
- package/docs/types/airPurifierStatus.html +1 -0
- package/docs/types/airPurifierTable.html +1 -0
- package/docs/types/airPurifierTablePM25WebhookContext.html +1 -0
- package/docs/types/airPurifierTableServiceData.html +1 -0
- package/docs/types/airPurifierTableStatus.html +1 -0
- package/docs/types/airPurifierTableVOC.html +1 -0
- package/docs/types/airPurifierTableVOCStatus.html +1 -0
- package/docs/types/airPurifierTableVOCWebhookContext.html +1 -0
- package/docs/types/airPurifierTableWebhookContext.html +1 -0
- package/docs/types/airPurifierVOC.html +1 -0
- package/docs/types/airPurifierVOCStatus.html +1 -0
- package/docs/types/airPurifierVOCWebhookContext.html +1 -0
- package/docs/types/airPurifierWebhookContext.html +1 -0
- package/docs/types/batteryCirculatorFan.html +1 -1
- package/docs/types/batteryCirculatorFanServiceData.html +1 -1
- package/docs/types/batteryCirculatorFanStatus.html +1 -1
- package/docs/types/batteryCirculatorFanWebhookContext.html +1 -1
- package/docs/types/blindTilt.html +1 -1
- package/docs/types/blindTiltServiceData.html +1 -1
- package/docs/types/blindTiltStatus.html +1 -1
- package/docs/types/blindTiltWebhookContext.html +1 -1
- package/docs/types/bot.html +1 -1
- package/docs/types/botServiceData.html +1 -1
- package/docs/types/botStatus.html +1 -1
- package/docs/types/botWebhookContext.html +1 -1
- package/docs/types/ceilingLight.html +1 -1
- package/docs/types/ceilingLightPro.html +1 -1
- package/docs/types/ceilingLightProServiceData.html +1 -1
- package/docs/types/ceilingLightProStatus.html +1 -1
- package/docs/types/ceilingLightProWebhookContext.html +1 -1
- package/docs/types/ceilingLightServiceData.html +1 -1
- package/docs/types/ceilingLightStatus.html +1 -1
- package/docs/types/ceilingLightWebhookContext.html +1 -1
- package/docs/types/circulatorFanStatus.html +1 -1
- package/docs/types/circulatorFanWebhookContext.html +1 -1
- package/docs/types/colorBulb.html +1 -1
- package/docs/types/colorBulbServiceData.html +1 -1
- package/docs/types/colorBulbStatus.html +1 -1
- package/docs/types/colorBulbWebhookContext.html +1 -1
- package/docs/types/commandType.html +1 -1
- package/docs/types/contactSensor.html +1 -1
- package/docs/types/contactSensorServiceData.html +1 -1
- package/docs/types/contactSensorStatus.html +1 -1
- package/docs/types/contactSensorWebhookContext.html +1 -1
- package/docs/types/curtain.html +1 -1
- package/docs/types/curtain3.html +1 -1
- package/docs/types/curtain3ServiceData.html +1 -1
- package/docs/types/curtain3WebhookContext.html +1 -1
- package/docs/types/curtainServiceData.html +1 -1
- package/docs/types/curtainStatus.html +1 -1
- package/docs/types/curtainWebhookContext.html +1 -1
- package/docs/types/floorCleaningRobotS10.html +1 -1
- package/docs/types/floorCleaningRobotS10Status.html +1 -1
- package/docs/types/floorCleaningRobotS10WebhookContext.html +1 -1
- package/docs/types/hub2.html +1 -1
- package/docs/types/hub2ServiceData.html +1 -1
- package/docs/types/hub2Status.html +1 -1
- package/docs/types/hub2WebhookContext.html +1 -1
- package/docs/types/humidifier.html +1 -1
- package/docs/types/humidifier2ServiceData.html +1 -1
- package/docs/types/humidifier2Status.html +1 -1
- package/docs/types/humidifier2WebhookContext.html +1 -1
- package/docs/types/humidifierServiceData.html +1 -1
- package/docs/types/humidifierStatus.html +1 -1
- package/docs/types/humidifierWebhookContext.html +1 -1
- package/docs/types/indoorCameraWebhookContext.html +1 -1
- package/docs/types/keypad.html +1 -1
- package/docs/types/keypadDetectorServiceData.html +1 -1
- package/docs/types/keypadTouch.html +1 -1
- package/docs/types/keypadTouchWebhookContext.html +1 -1
- package/docs/types/keypadWebhookContext.html +1 -1
- package/docs/types/lock.html +1 -1
- package/docs/types/lockPro.html +1 -1
- package/docs/types/lockProServiceData.html +1 -1
- package/docs/types/lockProStatus.html +1 -1
- package/docs/types/lockProWebhookContext.html +1 -1
- package/docs/types/lockServiceData.html +1 -1
- package/docs/types/lockStatus.html +1 -1
- package/docs/types/lockWebhookContext.html +1 -1
- package/docs/types/meter.html +1 -1
- package/docs/types/meterPlus.html +1 -1
- package/docs/types/meterPlusServiceData.html +1 -1
- package/docs/types/meterPlusStatus.html +1 -1
- package/docs/types/meterPlusWebhookContext.html +1 -1
- package/docs/types/meterPro.html +1 -1
- package/docs/types/meterProCO2ServiceData.html +1 -1
- package/docs/types/meterProCO2Status.html +1 -1
- package/docs/types/meterProCO2WebhookContext.html +1 -1
- package/docs/types/meterProServiceData.html +1 -1
- package/docs/types/meterProStatus.html +1 -1
- package/docs/types/meterProWebhookContext.html +1 -1
- package/docs/types/meterServiceData.html +1 -1
- package/docs/types/meterStatus.html +1 -1
- package/docs/types/meterWebhookContext.html +1 -1
- package/docs/types/motionSensor.html +1 -1
- package/docs/types/motionSensorServiceData.html +1 -1
- package/docs/types/motionSensorStatus.html +1 -1
- package/docs/types/motionSensorWebhookContext.html +1 -1
- package/docs/types/onadvertisement.html +1 -1
- package/docs/types/ondiscover.html +1 -1
- package/docs/types/outdoorMeter.html +1 -1
- package/docs/types/outdoorMeterServiceData.html +1 -1
- package/docs/types/outdoorMeterStatus.html +1 -1
- package/docs/types/outdoorMeterWebhookContext.html +1 -1
- package/docs/types/panTiltCamWebhookContext.html +1 -1
- package/docs/types/pantiltCam.html +1 -1
- package/docs/types/pantiltCam2k.html +1 -1
- package/docs/types/plug.html +1 -1
- package/docs/types/plugMini.html +1 -1
- package/docs/types/plugMiniJPServiceData.html +1 -1
- package/docs/types/plugMiniJPWebhookContext.html +1 -1
- package/docs/types/plugMiniStatus.html +1 -1
- package/docs/types/plugMiniUSServiceData.html +1 -1
- package/docs/types/plugMiniUSWebhookContext.html +1 -1
- package/docs/types/plugStatus.html +1 -1
- package/docs/types/plugWebhookContext.html +1 -1
- package/docs/types/relaySwitch1Context.html +1 -1
- package/docs/types/relaySwitch1PMContext.html +1 -1
- package/docs/types/relaySwitch1PMServiceData.html +1 -1
- package/docs/types/relaySwitch1PMStatus.html +1 -1
- package/docs/types/relaySwitch1ServiceData.html +1 -1
- package/docs/types/relaySwitch1Status.html +1 -1
- package/docs/types/remote.html +1 -1
- package/docs/types/remoteServiceData.html +1 -1
- package/docs/types/robotVacuumCleanerS1.html +1 -1
- package/docs/types/robotVacuumCleanerS1Plus.html +1 -1
- package/docs/types/robotVacuumCleanerS1PlusStatus.html +1 -1
- package/docs/types/robotVacuumCleanerS1PlusWebhookContext.html +1 -1
- package/docs/types/robotVacuumCleanerS1Status.html +1 -1
- package/docs/types/robotVacuumCleanerS1WebhookContext.html +1 -1
- package/docs/types/robotVacuumCleanerServiceData.html +1 -1
- package/docs/types/stripLight.html +1 -1
- package/docs/types/stripLightServiceData.html +1 -1
- package/docs/types/stripLightStatus.html +1 -1
- package/docs/types/stripLightWebhookContext.html +1 -1
- package/docs/types/waterLeakDetector.html +1 -1
- package/docs/types/waterLeakDetectorServiceData.html +1 -1
- package/docs/types/waterLeakDetectorStatus.html +1 -1
- package/docs/types/waterLeakDetectorWebhookContext.html +1 -1
- package/docs/variables/parameterChecker.html +1 -1
- package/docs/variables/urls.html +1 -1
- package/package.json +1 -1
package/dist/device.js
CHANGED
|
@@ -31,12 +31,38 @@ const DEVICE_COMMANDS = {
|
|
|
31
31
|
SET_AUTO_MODE: '570105',
|
|
32
32
|
SET_MANUAL_MODE: '570106',
|
|
33
33
|
},
|
|
34
|
+
AIR_PURIFIER: {
|
|
35
|
+
TURN_ON: [0x57, 0x01, 0x01],
|
|
36
|
+
TURN_OFF: [0x57, 0x01, 0x02],
|
|
37
|
+
SET_MODE: [0x57, 0x02],
|
|
38
|
+
SET_SPEED: [0x57, 0x03],
|
|
39
|
+
},
|
|
34
40
|
// Common commands used across multiple devices
|
|
35
41
|
COMMON: {
|
|
36
42
|
POWER_ON: [0x57, 0x01, 0x01],
|
|
37
43
|
POWER_OFF: [0x57, 0x01, 0x02],
|
|
38
44
|
},
|
|
39
45
|
};
|
|
46
|
+
/**
|
|
47
|
+
* Air quality level constants for air purifier devices.
|
|
48
|
+
*/
|
|
49
|
+
const AIR_QUALITY_LEVELS = {
|
|
50
|
+
EXCELLENT: 'excellent',
|
|
51
|
+
GOOD: 'good',
|
|
52
|
+
FAIR: 'fair',
|
|
53
|
+
POOR: 'poor',
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Air purifier mode constants.
|
|
57
|
+
*/
|
|
58
|
+
const AIR_PURIFIER_MODES = {
|
|
59
|
+
MANUAL: 'manual',
|
|
60
|
+
AUTO: 'auto',
|
|
61
|
+
SLEEP: 'sleep',
|
|
62
|
+
LEVEL_1: 'level_1',
|
|
63
|
+
LEVEL_2: 'level_2',
|
|
64
|
+
LEVEL_3: 'level_3',
|
|
65
|
+
};
|
|
40
66
|
// Legacy constants for backward compatibility
|
|
41
67
|
const BLIND_TILT_COMMANDS = DEVICE_COMMANDS.BLIND_TILT;
|
|
42
68
|
const BULB_COMMANDS = DEVICE_COMMANDS.BULB;
|
|
@@ -95,6 +121,8 @@ export var SwitchBotModel;
|
|
|
95
121
|
SwitchBotModel["RelaySwitch1"] = "W5502300";
|
|
96
122
|
SwitchBotModel["RelaySwitch1PM"] = "W5502310";
|
|
97
123
|
SwitchBotModel["Unknown"] = "Unknown";
|
|
124
|
+
SwitchBotModel["AirPurifier"] = "W5302300";
|
|
125
|
+
SwitchBotModel["AirPurifierTable"] = "W5302310";
|
|
98
126
|
})(SwitchBotModel || (SwitchBotModel = {}));
|
|
99
127
|
export var SwitchBotBLEModel;
|
|
100
128
|
(function (SwitchBotBLEModel) {
|
|
@@ -126,6 +154,8 @@ export var SwitchBotBLEModel;
|
|
|
126
154
|
SwitchBotBLEModel["RelaySwitch1PM"] = "<";
|
|
127
155
|
SwitchBotBLEModel["Remote"] = "b";
|
|
128
156
|
SwitchBotBLEModel["Unknown"] = "Unknown";
|
|
157
|
+
SwitchBotBLEModel["AirPurifier"] = "+";
|
|
158
|
+
SwitchBotBLEModel["AirPurifierTable"] = "7";
|
|
129
159
|
})(SwitchBotBLEModel || (SwitchBotBLEModel = {}));
|
|
130
160
|
export var SwitchBotBLEModelName;
|
|
131
161
|
(function (SwitchBotBLEModelName) {
|
|
@@ -155,6 +185,8 @@ export var SwitchBotBLEModelName;
|
|
|
155
185
|
SwitchBotBLEModelName["RelaySwitch1"] = "WoRelaySwitch1Plus";
|
|
156
186
|
SwitchBotBLEModelName["RelaySwitch1PM"] = "WoRelaySwitch1PM";
|
|
157
187
|
SwitchBotBLEModelName["Remote"] = "WoRemote";
|
|
188
|
+
SwitchBotBLEModelName["AirPurifier"] = "WoAirPurifier";
|
|
189
|
+
SwitchBotBLEModelName["AirPurifierTable"] = "WoAirPurifierTable";
|
|
158
190
|
SwitchBotBLEModelName["Unknown"] = "Unknown";
|
|
159
191
|
})(SwitchBotBLEModelName || (SwitchBotBLEModelName = {}));
|
|
160
192
|
export var SwitchBotBLEModelFriendlyName;
|
|
@@ -187,7 +219,13 @@ export var SwitchBotBLEModelFriendlyName;
|
|
|
187
219
|
SwitchBotBLEModelFriendlyName["RelaySwitch1"] = "Relay Switch 1";
|
|
188
220
|
SwitchBotBLEModelFriendlyName["RelaySwitch1PM"] = "Relay Switch 1PM";
|
|
189
221
|
SwitchBotBLEModelFriendlyName["Remote"] = "Remote";
|
|
222
|
+
SwitchBotBLEModelFriendlyName["AirPurifier"] = "Air Purifier";
|
|
223
|
+
SwitchBotBLEModelFriendlyName["AirPurifierTable"] = "Air Purifier Table";
|
|
190
224
|
SwitchBotBLEModelFriendlyName["Unknown"] = "Unknown";
|
|
225
|
+
SwitchBotBLEModelFriendlyName["AirPurifierVOC"] = "Air Purifier VOC";
|
|
226
|
+
SwitchBotBLEModelFriendlyName["AirPurifierTableVOC"] = "Air Purifier Table VOC";
|
|
227
|
+
SwitchBotBLEModelFriendlyName["AirPurifierPM2_5"] = "Air Purifier PM2.5";
|
|
228
|
+
SwitchBotBLEModelFriendlyName["AirPurifierTablePM2_5"] = "Air Purifier Table PM2.5";
|
|
191
229
|
})(SwitchBotBLEModelFriendlyName || (SwitchBotBLEModelFriendlyName = {}));
|
|
192
230
|
/**
|
|
193
231
|
* Enum for log levels.
|
|
@@ -818,6 +856,10 @@ export class Advertising {
|
|
|
818
856
|
return WoHub2.parseServiceData(manufacturerData, emitLog);
|
|
819
857
|
case SwitchBotBLEModel.OutdoorMeter:
|
|
820
858
|
return WoIOSensorTH.parseServiceData(serviceData, manufacturerData, emitLog);
|
|
859
|
+
case SwitchBotBLEModel.AirPurifier:
|
|
860
|
+
return WoAirPurifier.parseServiceData(serviceData, manufacturerData, emitLog);
|
|
861
|
+
case SwitchBotBLEModel.AirPurifierTable:
|
|
862
|
+
return WoAirPurifierTable.parseServiceData(serviceData, manufacturerData, emitLog);
|
|
821
863
|
case SwitchBotBLEModel.MotionSensor:
|
|
822
864
|
return WoPresence.parseServiceData(serviceData, emitLog);
|
|
823
865
|
case SwitchBotBLEModel.ContactSensor:
|
|
@@ -3061,4 +3103,280 @@ export class WoStrip extends SwitchbotDevice {
|
|
|
3061
3103
|
}
|
|
3062
3104
|
}
|
|
3063
3105
|
}
|
|
3106
|
+
/**
|
|
3107
|
+
* Class representing a SwitchBot Air Purifier device.
|
|
3108
|
+
* @extends SwitchbotDevice
|
|
3109
|
+
*/
|
|
3110
|
+
export class WoAirPurifier extends SwitchbotDevice {
|
|
3111
|
+
/**
|
|
3112
|
+
* Parses service data for air purifier devices.
|
|
3113
|
+
* @param {Buffer | null} serviceData - The service data buffer.
|
|
3114
|
+
* @param {Buffer | null} manufacturerData - The manufacturer data buffer.
|
|
3115
|
+
* @param {Function} emitLog - The function to emit log messages.
|
|
3116
|
+
* @returns {airPurifierServiceData | null} - The parsed service data or null.
|
|
3117
|
+
*/
|
|
3118
|
+
static parseServiceData(serviceData, manufacturerData, emitLog) {
|
|
3119
|
+
if (!manufacturerData || manufacturerData.length < 14) {
|
|
3120
|
+
return null;
|
|
3121
|
+
}
|
|
3122
|
+
const deviceData = manufacturerData.subarray(6);
|
|
3123
|
+
if (deviceData.length < 8) {
|
|
3124
|
+
return null;
|
|
3125
|
+
}
|
|
3126
|
+
const sequenceNumber = deviceData[0];
|
|
3127
|
+
const isOn = Boolean(deviceData[1] & 0b10000000);
|
|
3128
|
+
const mode = deviceData[1] & 0b00000111;
|
|
3129
|
+
const isAqiValid = Boolean(deviceData[2] & 0b00000100);
|
|
3130
|
+
const childLock = Boolean(deviceData[2] & 0b00000010);
|
|
3131
|
+
const speed = deviceData[3] & 0b01111111;
|
|
3132
|
+
const aqiLevelRaw = (deviceData[4] & 0b00000110) >> 1;
|
|
3133
|
+
const workTime = (deviceData[5] << 8) | deviceData[6];
|
|
3134
|
+
const errCode = deviceData[7];
|
|
3135
|
+
// Map AQI level to string using the defined constant
|
|
3136
|
+
const aqiLevelValues = [
|
|
3137
|
+
AIR_QUALITY_LEVELS.EXCELLENT,
|
|
3138
|
+
AIR_QUALITY_LEVELS.GOOD,
|
|
3139
|
+
AIR_QUALITY_LEVELS.FAIR,
|
|
3140
|
+
AIR_QUALITY_LEVELS.POOR,
|
|
3141
|
+
];
|
|
3142
|
+
const aqiLevel = aqiLevelValues[aqiLevelRaw] || 'unknown';
|
|
3143
|
+
// Determine mode based on mode value and speed
|
|
3144
|
+
let modeString = null;
|
|
3145
|
+
if (mode === 1) {
|
|
3146
|
+
if (speed >= 0 && speed <= 33) {
|
|
3147
|
+
modeString = AIR_PURIFIER_MODES.LEVEL_1;
|
|
3148
|
+
}
|
|
3149
|
+
else if (speed >= 34 && speed <= 66) {
|
|
3150
|
+
modeString = AIR_PURIFIER_MODES.LEVEL_2;
|
|
3151
|
+
}
|
|
3152
|
+
else {
|
|
3153
|
+
modeString = AIR_PURIFIER_MODES.LEVEL_3;
|
|
3154
|
+
}
|
|
3155
|
+
}
|
|
3156
|
+
else if (mode > 1 && mode <= 4) {
|
|
3157
|
+
const modeMap = [null, null, 'auto', 'sleep', 'manual'];
|
|
3158
|
+
modeString = modeMap[mode + 2] || null;
|
|
3159
|
+
}
|
|
3160
|
+
if (emitLog) {
|
|
3161
|
+
emitLog('debug', `Air Purifier Service Data: isOn=${isOn}, mode=${modeString}, speed=${speed}, AQI=${aqiLevel}`);
|
|
3162
|
+
}
|
|
3163
|
+
return {
|
|
3164
|
+
model: SwitchBotBLEModel.AirPurifier,
|
|
3165
|
+
modelName: SwitchBotBLEModelName.AirPurifier,
|
|
3166
|
+
modelFriendlyName: SwitchBotBLEModelFriendlyName.AirPurifier,
|
|
3167
|
+
isOn,
|
|
3168
|
+
mode: modeString,
|
|
3169
|
+
isAqiValid,
|
|
3170
|
+
child_lock: childLock,
|
|
3171
|
+
speed,
|
|
3172
|
+
aqi_level: aqiLevel,
|
|
3173
|
+
filter_element_working_time: workTime,
|
|
3174
|
+
err_code: errCode,
|
|
3175
|
+
sequence_number: sequenceNumber,
|
|
3176
|
+
};
|
|
3177
|
+
}
|
|
3178
|
+
/**
|
|
3179
|
+
* Sets the state of the air purifier.
|
|
3180
|
+
* @param {number[]} reqByteArray - The request byte array.
|
|
3181
|
+
* @returns {Promise<boolean>} - Resolves with a boolean indicating whether the operation was successful.
|
|
3182
|
+
* @private
|
|
3183
|
+
*/
|
|
3184
|
+
async setState(reqByteArray) {
|
|
3185
|
+
return this.operateAirPurifier(reqByteArray);
|
|
3186
|
+
}
|
|
3187
|
+
/**
|
|
3188
|
+
* Turns the air purifier on.
|
|
3189
|
+
* @returns {Promise<boolean>} - Resolves with true if the air purifier is turned on.
|
|
3190
|
+
*/
|
|
3191
|
+
async turnOn() {
|
|
3192
|
+
return this.setState([...DEVICE_COMMANDS.AIR_PURIFIER.TURN_ON]);
|
|
3193
|
+
}
|
|
3194
|
+
/**
|
|
3195
|
+
* Turns the air purifier off.
|
|
3196
|
+
* @returns {Promise<boolean>} - Resolves with true if the air purifier is turned off.
|
|
3197
|
+
*/
|
|
3198
|
+
async turnOff() {
|
|
3199
|
+
return this.setState([...DEVICE_COMMANDS.AIR_PURIFIER.TURN_OFF]);
|
|
3200
|
+
}
|
|
3201
|
+
/**
|
|
3202
|
+
* Sets the speed of the air purifier.
|
|
3203
|
+
* @param {number} speed - The speed value (0-100).
|
|
3204
|
+
* @returns {Promise<boolean>} - Resolves with true if the operation was successful.
|
|
3205
|
+
*/
|
|
3206
|
+
async setSpeed(speed) {
|
|
3207
|
+
if (typeof speed !== 'number' || speed < 0 || speed > 100) {
|
|
3208
|
+
throw new TypeError(`Invalid speed value: ${speed}`);
|
|
3209
|
+
}
|
|
3210
|
+
return this.setState([...DEVICE_COMMANDS.AIR_PURIFIER.SET_SPEED, speed]);
|
|
3211
|
+
}
|
|
3212
|
+
/**
|
|
3213
|
+
* Sets the mode of the air purifier.
|
|
3214
|
+
* @param {number} mode - The mode value (1-4).
|
|
3215
|
+
* @returns {Promise<boolean>} - Resolves with true if the operation was successful.
|
|
3216
|
+
*/
|
|
3217
|
+
async setMode(mode) {
|
|
3218
|
+
if (typeof mode !== 'number' || mode < 1 || mode > 4) {
|
|
3219
|
+
throw new TypeError(`Invalid mode value: ${mode}`);
|
|
3220
|
+
}
|
|
3221
|
+
return this.setState([...DEVICE_COMMANDS.AIR_PURIFIER.SET_MODE, mode]);
|
|
3222
|
+
}
|
|
3223
|
+
/**
|
|
3224
|
+
* Operates the air purifier with the given byte array.
|
|
3225
|
+
* @public
|
|
3226
|
+
* @param {number[]} bytes - The byte array to send.
|
|
3227
|
+
* @returns {Promise<boolean>} - Resolves with true if the operation was successful.
|
|
3228
|
+
*/
|
|
3229
|
+
async operateAirPurifier(bytes) {
|
|
3230
|
+
const req_buf = Buffer.from(bytes);
|
|
3231
|
+
const res_buf = await this.command(req_buf);
|
|
3232
|
+
if (res_buf.length !== 2) {
|
|
3233
|
+
throw new Error(`Expecting a 2-byte response, got instead: 0x${res_buf.toString('hex')}`);
|
|
3234
|
+
}
|
|
3235
|
+
const code = res_buf.readUInt8(1);
|
|
3236
|
+
if (code === 0x00 || code === 0x80) {
|
|
3237
|
+
return code === 0x80;
|
|
3238
|
+
}
|
|
3239
|
+
else {
|
|
3240
|
+
throw new Error(`The device returned an error: 0x${res_buf.toString('hex')}`);
|
|
3241
|
+
}
|
|
3242
|
+
}
|
|
3243
|
+
}
|
|
3244
|
+
/**
|
|
3245
|
+
* Class representing a SwitchBot Air Purifier Table device.
|
|
3246
|
+
* @extends SwitchbotDevice
|
|
3247
|
+
*/
|
|
3248
|
+
export class WoAirPurifierTable extends SwitchbotDevice {
|
|
3249
|
+
/**
|
|
3250
|
+
* Parses service data for air purifier table devices.
|
|
3251
|
+
* @param {Buffer | null} serviceData - The service data buffer.
|
|
3252
|
+
* @param {Buffer | null} manufacturerData - The manufacturer data buffer.
|
|
3253
|
+
* @param {Function} emitLog - The function to emit log messages.
|
|
3254
|
+
* @returns {airPurifierTableServiceData | null} - The parsed service data or null.
|
|
3255
|
+
*/
|
|
3256
|
+
static parseServiceData(serviceData, manufacturerData, emitLog) {
|
|
3257
|
+
if (!manufacturerData || manufacturerData.length < 14) {
|
|
3258
|
+
return null;
|
|
3259
|
+
}
|
|
3260
|
+
const deviceData = manufacturerData.subarray(6);
|
|
3261
|
+
if (deviceData.length < 8) {
|
|
3262
|
+
return null;
|
|
3263
|
+
}
|
|
3264
|
+
const sequenceNumber = deviceData[0];
|
|
3265
|
+
const isOn = Boolean(deviceData[1] & 0b10000000);
|
|
3266
|
+
const mode = deviceData[1] & 0b00000111;
|
|
3267
|
+
const isAqiValid = Boolean(deviceData[2] & 0b00000100);
|
|
3268
|
+
const childLock = Boolean(deviceData[2] & 0b00000010);
|
|
3269
|
+
const speed = deviceData[3] & 0b01111111;
|
|
3270
|
+
const aqiLevelRaw = (deviceData[4] & 0b00000110) >> 1;
|
|
3271
|
+
const workTime = (deviceData[5] << 8) | deviceData[6];
|
|
3272
|
+
const errCode = deviceData[7];
|
|
3273
|
+
// Map AQI level to string using the defined constant
|
|
3274
|
+
const aqiLevelValues = [
|
|
3275
|
+
AIR_QUALITY_LEVELS.EXCELLENT,
|
|
3276
|
+
AIR_QUALITY_LEVELS.GOOD,
|
|
3277
|
+
AIR_QUALITY_LEVELS.FAIR,
|
|
3278
|
+
AIR_QUALITY_LEVELS.POOR,
|
|
3279
|
+
];
|
|
3280
|
+
const aqiLevel = aqiLevelValues[aqiLevelRaw] || 'unknown';
|
|
3281
|
+
// Determine mode based on mode value and speed
|
|
3282
|
+
let modeString = null;
|
|
3283
|
+
if (mode === 1) {
|
|
3284
|
+
if (speed >= 0 && speed <= 33) {
|
|
3285
|
+
modeString = AIR_PURIFIER_MODES.LEVEL_1;
|
|
3286
|
+
}
|
|
3287
|
+
else if (speed >= 34 && speed <= 66) {
|
|
3288
|
+
modeString = AIR_PURIFIER_MODES.LEVEL_2;
|
|
3289
|
+
}
|
|
3290
|
+
else {
|
|
3291
|
+
modeString = AIR_PURIFIER_MODES.LEVEL_3;
|
|
3292
|
+
}
|
|
3293
|
+
}
|
|
3294
|
+
else if (mode > 1 && mode <= 4) {
|
|
3295
|
+
const modeMap = [null, null, 'auto', 'sleep', 'manual'];
|
|
3296
|
+
modeString = modeMap[mode + 2] || null;
|
|
3297
|
+
}
|
|
3298
|
+
if (emitLog) {
|
|
3299
|
+
emitLog('debug', `Air Purifier Table Service Data: isOn=${isOn}, mode=${modeString}, speed=${speed}, AQI=${aqiLevel}`);
|
|
3300
|
+
}
|
|
3301
|
+
return {
|
|
3302
|
+
model: SwitchBotBLEModel.AirPurifierTable,
|
|
3303
|
+
modelName: SwitchBotBLEModelName.AirPurifierTable,
|
|
3304
|
+
modelFriendlyName: SwitchBotBLEModelFriendlyName.AirPurifierTable,
|
|
3305
|
+
isOn,
|
|
3306
|
+
mode: modeString,
|
|
3307
|
+
isAqiValid,
|
|
3308
|
+
child_lock: childLock,
|
|
3309
|
+
speed,
|
|
3310
|
+
aqi_level: aqiLevel,
|
|
3311
|
+
filter_element_working_time: workTime,
|
|
3312
|
+
err_code: errCode,
|
|
3313
|
+
sequence_number: sequenceNumber,
|
|
3314
|
+
};
|
|
3315
|
+
}
|
|
3316
|
+
/**
|
|
3317
|
+
* Sets the state of the air purifier table.
|
|
3318
|
+
* @param {number[]} reqByteArray - The request byte array.
|
|
3319
|
+
* @returns {Promise<boolean>} - Resolves with a boolean indicating whether the operation was successful.
|
|
3320
|
+
* @private
|
|
3321
|
+
*/
|
|
3322
|
+
async setState(reqByteArray) {
|
|
3323
|
+
return this.operateAirPurifierTable(reqByteArray);
|
|
3324
|
+
}
|
|
3325
|
+
/**
|
|
3326
|
+
* Turns the air purifier table on.
|
|
3327
|
+
* @returns {Promise<boolean>} - Resolves with true if the air purifier table is turned on.
|
|
3328
|
+
*/
|
|
3329
|
+
async turnOn() {
|
|
3330
|
+
return this.setState([...DEVICE_COMMANDS.AIR_PURIFIER.TURN_ON]);
|
|
3331
|
+
}
|
|
3332
|
+
/**
|
|
3333
|
+
* Turns the air purifier table off.
|
|
3334
|
+
* @returns {Promise<boolean>} - Resolves with true if the air purifier table is turned off.
|
|
3335
|
+
*/
|
|
3336
|
+
async turnOff() {
|
|
3337
|
+
return this.setState([...DEVICE_COMMANDS.AIR_PURIFIER.TURN_OFF]);
|
|
3338
|
+
}
|
|
3339
|
+
/**
|
|
3340
|
+
* Sets the speed of the air purifier table.
|
|
3341
|
+
* @param {number} speed - The speed value (0-100).
|
|
3342
|
+
* @returns {Promise<boolean>} - Resolves with true if the operation was successful.
|
|
3343
|
+
*/
|
|
3344
|
+
async setSpeed(speed) {
|
|
3345
|
+
if (typeof speed !== 'number' || speed < 0 || speed > 100) {
|
|
3346
|
+
throw new TypeError(`Invalid speed value: ${speed}`);
|
|
3347
|
+
}
|
|
3348
|
+
return this.setState([...DEVICE_COMMANDS.AIR_PURIFIER.SET_SPEED, speed]);
|
|
3349
|
+
}
|
|
3350
|
+
/**
|
|
3351
|
+
* Sets the mode of the air purifier table.
|
|
3352
|
+
* @param {number} mode - The mode value (1-4).
|
|
3353
|
+
* @returns {Promise<boolean>} - Resolves with true if the operation was successful.
|
|
3354
|
+
*/
|
|
3355
|
+
async setMode(mode) {
|
|
3356
|
+
if (typeof mode !== 'number' || mode < 1 || mode > 4) {
|
|
3357
|
+
throw new TypeError(`Invalid mode value: ${mode}`);
|
|
3358
|
+
}
|
|
3359
|
+
return this.setState([...DEVICE_COMMANDS.AIR_PURIFIER.SET_MODE, mode]);
|
|
3360
|
+
}
|
|
3361
|
+
/**
|
|
3362
|
+
* Operates the air purifier table with the given byte array.
|
|
3363
|
+
* @public
|
|
3364
|
+
* @param {number[]} bytes - The byte array to send.
|
|
3365
|
+
* @returns {Promise<boolean>} - Resolves with true if the operation was successful.
|
|
3366
|
+
*/
|
|
3367
|
+
async operateAirPurifierTable(bytes) {
|
|
3368
|
+
const req_buf = Buffer.from(bytes);
|
|
3369
|
+
const res_buf = await this.command(req_buf);
|
|
3370
|
+
if (res_buf.length !== 2) {
|
|
3371
|
+
throw new Error(`Expecting a 2-byte response, got instead: 0x${res_buf.toString('hex')}`);
|
|
3372
|
+
}
|
|
3373
|
+
const code = res_buf.readUInt8(1);
|
|
3374
|
+
if (code === 0x00 || code === 0x80) {
|
|
3375
|
+
return code === 0x80;
|
|
3376
|
+
}
|
|
3377
|
+
else {
|
|
3378
|
+
throw new Error(`The device returned an error: 0x${res_buf.toString('hex')}`);
|
|
3379
|
+
}
|
|
3380
|
+
}
|
|
3381
|
+
}
|
|
3064
3382
|
//# sourceMappingURL=device.js.map
|