meross-iot 0.1.0
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/CHANGELOG.md +30 -0
- package/LICENSE +21 -0
- package/README.md +153 -0
- package/index.d.ts +2344 -0
- package/index.js +131 -0
- package/lib/controller/device.js +1317 -0
- package/lib/controller/features/alarm-feature.js +89 -0
- package/lib/controller/features/child-lock-feature.js +61 -0
- package/lib/controller/features/config-feature.js +54 -0
- package/lib/controller/features/consumption-feature.js +210 -0
- package/lib/controller/features/control-feature.js +62 -0
- package/lib/controller/features/diffuser-feature.js +411 -0
- package/lib/controller/features/digest-timer-feature.js +22 -0
- package/lib/controller/features/digest-trigger-feature.js +22 -0
- package/lib/controller/features/dnd-feature.js +79 -0
- package/lib/controller/features/electricity-feature.js +144 -0
- package/lib/controller/features/encryption-feature.js +259 -0
- package/lib/controller/features/garage-feature.js +337 -0
- package/lib/controller/features/hub-feature.js +687 -0
- package/lib/controller/features/light-feature.js +408 -0
- package/lib/controller/features/presence-sensor-feature.js +297 -0
- package/lib/controller/features/roller-shutter-feature.js +456 -0
- package/lib/controller/features/runtime-feature.js +74 -0
- package/lib/controller/features/screen-feature.js +67 -0
- package/lib/controller/features/sensor-history-feature.js +47 -0
- package/lib/controller/features/smoke-config-feature.js +50 -0
- package/lib/controller/features/spray-feature.js +166 -0
- package/lib/controller/features/system-feature.js +269 -0
- package/lib/controller/features/temp-unit-feature.js +55 -0
- package/lib/controller/features/thermostat-feature.js +804 -0
- package/lib/controller/features/timer-feature.js +507 -0
- package/lib/controller/features/toggle-feature.js +223 -0
- package/lib/controller/features/trigger-feature.js +333 -0
- package/lib/controller/hub-device.js +185 -0
- package/lib/controller/subdevice.js +1537 -0
- package/lib/device-factory.js +463 -0
- package/lib/error-budget.js +138 -0
- package/lib/http-api.js +766 -0
- package/lib/manager.js +1609 -0
- package/lib/model/channel-info.js +79 -0
- package/lib/model/constants.js +119 -0
- package/lib/model/enums.js +819 -0
- package/lib/model/exception.js +363 -0
- package/lib/model/http/device.js +215 -0
- package/lib/model/http/error-codes.js +121 -0
- package/lib/model/http/exception.js +151 -0
- package/lib/model/http/subdevice.js +133 -0
- package/lib/model/push/alarm.js +112 -0
- package/lib/model/push/bind.js +97 -0
- package/lib/model/push/common.js +282 -0
- package/lib/model/push/diffuser-light.js +100 -0
- package/lib/model/push/diffuser-spray.js +83 -0
- package/lib/model/push/factory.js +229 -0
- package/lib/model/push/generic.js +115 -0
- package/lib/model/push/hub-battery.js +59 -0
- package/lib/model/push/hub-mts100-all.js +64 -0
- package/lib/model/push/hub-mts100-mode.js +59 -0
- package/lib/model/push/hub-mts100-temperature.js +62 -0
- package/lib/model/push/hub-online.js +59 -0
- package/lib/model/push/hub-sensor-alert.js +61 -0
- package/lib/model/push/hub-sensor-all.js +59 -0
- package/lib/model/push/hub-sensor-smoke.js +110 -0
- package/lib/model/push/hub-sensor-temphum.js +62 -0
- package/lib/model/push/hub-subdevicelist.js +50 -0
- package/lib/model/push/hub-togglex.js +60 -0
- package/lib/model/push/index.js +81 -0
- package/lib/model/push/online.js +53 -0
- package/lib/model/push/presence-study.js +61 -0
- package/lib/model/push/sensor-latestx.js +106 -0
- package/lib/model/push/timerx.js +63 -0
- package/lib/model/push/togglex.js +78 -0
- package/lib/model/push/triggerx.js +62 -0
- package/lib/model/push/unbind.js +34 -0
- package/lib/model/push/water-leak.js +107 -0
- package/lib/model/states/diffuser-light-state.js +119 -0
- package/lib/model/states/diffuser-spray-state.js +58 -0
- package/lib/model/states/garage-door-state.js +71 -0
- package/lib/model/states/index.js +38 -0
- package/lib/model/states/light-state.js +134 -0
- package/lib/model/states/presence-sensor-state.js +239 -0
- package/lib/model/states/roller-shutter-state.js +82 -0
- package/lib/model/states/spray-state.js +58 -0
- package/lib/model/states/thermostat-state.js +297 -0
- package/lib/model/states/timer-state.js +192 -0
- package/lib/model/states/toggle-state.js +105 -0
- package/lib/model/states/trigger-state.js +155 -0
- package/lib/subscription.js +587 -0
- package/lib/utilities/conversion.js +62 -0
- package/lib/utilities/debug.js +165 -0
- package/lib/utilities/mqtt.js +152 -0
- package/lib/utilities/network.js +53 -0
- package/lib/utilities/options.js +64 -0
- package/lib/utilities/request-queue.js +161 -0
- package/lib/utilities/ssid.js +37 -0
- package/lib/utilities/state-changes.js +66 -0
- package/lib/utilities/stats.js +687 -0
- package/lib/utilities/timer.js +310 -0
- package/lib/utilities/trigger.js +286 -0
- package/package.json +73 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { normalizeChannel } = require('../../utilities/options');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Smoke sensor configuration feature module.
|
|
7
|
+
* Provides control over smoke sensor settings including detection and do-not-disturb modes.
|
|
8
|
+
*/
|
|
9
|
+
module.exports = {
|
|
10
|
+
/**
|
|
11
|
+
* Gets the smoke sensor configuration from the device.
|
|
12
|
+
*
|
|
13
|
+
* @param {Object} [options={}] - Get options
|
|
14
|
+
* @param {number} [options.channel=0] - Channel to get config for (default: 0)
|
|
15
|
+
* @param {string} [options.subId=null] - Optional subdevice ID
|
|
16
|
+
* @returns {Promise<Object>} Response containing smoke sensor configuration with `config` array
|
|
17
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
18
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
19
|
+
*/
|
|
20
|
+
async getSmokeConfig(options = {}) {
|
|
21
|
+
const channel = normalizeChannel(options);
|
|
22
|
+
const payload = {
|
|
23
|
+
config: [{
|
|
24
|
+
channel
|
|
25
|
+
}]
|
|
26
|
+
};
|
|
27
|
+
if (options.subId) {
|
|
28
|
+
payload.config[0].subId = options.subId;
|
|
29
|
+
}
|
|
30
|
+
return await this.publishMessage('GET', 'Appliance.Control.Smoke.Config', payload);
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Controls the smoke sensor configuration.
|
|
35
|
+
*
|
|
36
|
+
* @param {Object|Array<Object>} configData - Config data object or array of config items
|
|
37
|
+
* @param {number} [configData.channel] - Channel to configure
|
|
38
|
+
* @param {string} [configData.subId] - Optional subdevice ID
|
|
39
|
+
* @param {boolean} [configData.dnd] - Do not disturb mode
|
|
40
|
+
* @param {boolean} [configData.detect] - Detection enabled
|
|
41
|
+
* @returns {Promise<Object>} Response from the device
|
|
42
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
43
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
44
|
+
*/
|
|
45
|
+
async setSmokeConfig(configData) {
|
|
46
|
+
const payload = { config: Array.isArray(configData) ? configData : [configData] };
|
|
47
|
+
return await this.publishMessage('SET', 'Appliance.Control.Smoke.Config', payload);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const SprayState = require('../../model/states/spray-state');
|
|
4
|
+
const { SprayMode } = require('../../model/enums');
|
|
5
|
+
const { normalizeChannel } = require('../../utilities/options');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Spray feature module.
|
|
9
|
+
* Provides control over spray/mist functionality for devices that support it.
|
|
10
|
+
*/
|
|
11
|
+
module.exports = {
|
|
12
|
+
/**
|
|
13
|
+
* Controls the spray mode.
|
|
14
|
+
*
|
|
15
|
+
* Supports both SprayMode enum objects and numeric values. If an enum object is provided,
|
|
16
|
+
* extracts the numeric value automatically.
|
|
17
|
+
*
|
|
18
|
+
* @param {Object} options - Spray options
|
|
19
|
+
* @param {number} [options.channel=0] - Channel to control (default: 0)
|
|
20
|
+
* @param {number|import('../lib/enums').SprayMode} options.mode - Spray mode value or SprayMode enum
|
|
21
|
+
* @returns {Promise<Object>} Response from the device containing the updated spray state
|
|
22
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
23
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
24
|
+
*/
|
|
25
|
+
async setSpray(options = {}) {
|
|
26
|
+
if (options.mode === undefined) {
|
|
27
|
+
throw new Error('mode is required');
|
|
28
|
+
}
|
|
29
|
+
const channel = normalizeChannel(options);
|
|
30
|
+
const modeValue = options.mode || 0;
|
|
31
|
+
|
|
32
|
+
const payload = { 'spray': { channel, 'mode': modeValue } };
|
|
33
|
+
const response = await this.publishMessage('SET', 'Appliance.Control.Spray', payload);
|
|
34
|
+
|
|
35
|
+
if (response && response.spray) {
|
|
36
|
+
this._updateSprayState(response.spray, 'response');
|
|
37
|
+
this._lastFullUpdateTimestamp = Date.now();
|
|
38
|
+
} else {
|
|
39
|
+
this._updateSprayState({ channel, mode: modeValue }, 'response');
|
|
40
|
+
this._lastFullUpdateTimestamp = Date.now();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return response;
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Gets the current spray state from the device.
|
|
48
|
+
*
|
|
49
|
+
* Use {@link getCachedSprayState} to get cached state without making a request.
|
|
50
|
+
* @param {Object} [options={}] - Get options
|
|
51
|
+
* @returns {Promise<Object>} Response containing spray state with `spray` object
|
|
52
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
53
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
54
|
+
*/
|
|
55
|
+
async getSprayState(_options = {}) {
|
|
56
|
+
const response = await this.publishMessage('GET', 'Appliance.Control.Spray', {});
|
|
57
|
+
if (response && response.spray) {
|
|
58
|
+
this._updateSprayState(response.spray, 'response');
|
|
59
|
+
this._lastFullUpdateTimestamp = Date.now();
|
|
60
|
+
}
|
|
61
|
+
return response;
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Gets the cached spray state for the specified channel.
|
|
66
|
+
*
|
|
67
|
+
* Returns cached state without making a request. Use {@link getSprayState} to fetch
|
|
68
|
+
* fresh state from the device. State is automatically updated when commands are sent or
|
|
69
|
+
* push notifications are received.
|
|
70
|
+
*
|
|
71
|
+
* @param {number} [channel=0] - Channel to get state for (default: 0)
|
|
72
|
+
* @returns {import('../lib/model/states/spray-state').SprayState|undefined} Cached spray state or undefined if not available
|
|
73
|
+
* @throws {Error} If state has not been initialized (call refreshState() first)
|
|
74
|
+
*/
|
|
75
|
+
getCachedSprayState(channel = 0) {
|
|
76
|
+
this.validateState();
|
|
77
|
+
return this._sprayStateByChannel.get(channel);
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Gets the current spray mode for the specified channel (cached).
|
|
82
|
+
*
|
|
83
|
+
* Returns the spray mode enum from cached state. Use {@link getRawSprayMode} to get
|
|
84
|
+
* the raw numeric value.
|
|
85
|
+
*
|
|
86
|
+
* @param {number} [channel=0] - Channel to get mode for (default: 0)
|
|
87
|
+
* @returns {import('../lib/enums').SprayMode|undefined} SprayMode enum object (e.g., SprayMode.OFF) or undefined if not available
|
|
88
|
+
* @throws {Error} If state has not been initialized (call refreshState() first)
|
|
89
|
+
* @see getRawSprayMode
|
|
90
|
+
*/
|
|
91
|
+
getCurrentSprayMode(channel = 0) {
|
|
92
|
+
this.validateState();
|
|
93
|
+
const sprayState = this._sprayStateByChannel.get(channel);
|
|
94
|
+
if (sprayState && sprayState.mode !== undefined && sprayState.mode !== null) {
|
|
95
|
+
const enumKey = Object.keys(SprayMode).find(key => SprayMode[key] === sprayState.mode);
|
|
96
|
+
return enumKey ? SprayMode[enumKey] : undefined;
|
|
97
|
+
}
|
|
98
|
+
return undefined;
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Gets the raw numeric spray mode value for the specified channel (cached).
|
|
103
|
+
*
|
|
104
|
+
* Returns the raw numeric mode value. For enum object, use {@link getCurrentSprayMode} instead.
|
|
105
|
+
*
|
|
106
|
+
* @param {number} [channel=0] - Channel to get mode for (default: 0)
|
|
107
|
+
* @returns {number|undefined} Raw numeric mode value or undefined if not available
|
|
108
|
+
* @throws {Error} If state has not been initialized (call refreshState() first)
|
|
109
|
+
* @see getCurrentSprayMode
|
|
110
|
+
*/
|
|
111
|
+
getRawSprayMode(channel = 0) {
|
|
112
|
+
this.validateState();
|
|
113
|
+
const sprayState = this._sprayStateByChannel.get(channel);
|
|
114
|
+
if (sprayState) {
|
|
115
|
+
return sprayState.mode;
|
|
116
|
+
}
|
|
117
|
+
return undefined;
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Updates the cached spray state from spray data.
|
|
122
|
+
*
|
|
123
|
+
* Called automatically when spray push notifications are received or commands complete.
|
|
124
|
+
* Handles both single objects and arrays of spray data.
|
|
125
|
+
*
|
|
126
|
+
* @param {Object|Array} sprayData - Spray data (single object or array)
|
|
127
|
+
* @param {string} [source='response'] - Source of the update ('push' | 'poll' | 'response')
|
|
128
|
+
* @private
|
|
129
|
+
*/
|
|
130
|
+
_updateSprayState(sprayData, source = 'response') {
|
|
131
|
+
if (!sprayData) {return;}
|
|
132
|
+
|
|
133
|
+
const sprayArray = Array.isArray(sprayData) ? sprayData : [sprayData];
|
|
134
|
+
|
|
135
|
+
for (const sprayItem of sprayArray) {
|
|
136
|
+
const channelIndex = sprayItem.channel;
|
|
137
|
+
if (channelIndex === undefined || channelIndex === null) {continue;}
|
|
138
|
+
|
|
139
|
+
const oldState = this._sprayStateByChannel.get(channelIndex);
|
|
140
|
+
const oldValue = oldState ? {
|
|
141
|
+
mode: oldState.mode
|
|
142
|
+
} : undefined;
|
|
143
|
+
|
|
144
|
+
let state = this._sprayStateByChannel.get(channelIndex);
|
|
145
|
+
if (!state) {
|
|
146
|
+
state = new SprayState(sprayItem);
|
|
147
|
+
this._sprayStateByChannel.set(channelIndex, state);
|
|
148
|
+
} else {
|
|
149
|
+
state.update(sprayItem);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const newValue = { mode: state.mode };
|
|
153
|
+
if (oldValue === undefined || oldValue.mode !== state.mode) {
|
|
154
|
+
this.emit('stateChange', {
|
|
155
|
+
type: 'spray',
|
|
156
|
+
channel: channelIndex,
|
|
157
|
+
value: newValue,
|
|
158
|
+
oldValue,
|
|
159
|
+
source,
|
|
160
|
+
timestamp: Date.now()
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* System feature module.
|
|
5
|
+
* Provides access to device system information including hardware, firmware, online status, and configuration.
|
|
6
|
+
*/
|
|
7
|
+
module.exports = {
|
|
8
|
+
/**
|
|
9
|
+
* Gets all system data from the device.
|
|
10
|
+
*
|
|
11
|
+
* Returns comprehensive system information including hardware, firmware, and online status.
|
|
12
|
+
* Automatically extracts and caches MAC address, LAN IP, MQTT host/port, and online status
|
|
13
|
+
* from the response.
|
|
14
|
+
*
|
|
15
|
+
* @returns {Promise<Object>} Response containing all system data
|
|
16
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
17
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
18
|
+
*/
|
|
19
|
+
async getSystemAllData() {
|
|
20
|
+
const response = await this.publishMessage('GET', 'Appliance.System.All', {});
|
|
21
|
+
|
|
22
|
+
if (response && response.all && response.all.system) {
|
|
23
|
+
const { system } = response.all;
|
|
24
|
+
|
|
25
|
+
if (system.hardware && system.hardware.macAddress) {
|
|
26
|
+
this.updateMacAddress(system.hardware.macAddress);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (system.firmware) {
|
|
30
|
+
const { firmware } = system;
|
|
31
|
+
if (firmware.innerIp) {
|
|
32
|
+
this._lanIp = firmware.innerIp;
|
|
33
|
+
}
|
|
34
|
+
if (firmware.server) {
|
|
35
|
+
this._mqttHost = firmware.server;
|
|
36
|
+
}
|
|
37
|
+
if (firmware.port) {
|
|
38
|
+
this._mqttPort = firmware.port;
|
|
39
|
+
}
|
|
40
|
+
this._lastFullUpdateTimestamp = Date.now();
|
|
41
|
+
}
|
|
42
|
+
if (system.online) {
|
|
43
|
+
const onlineStatus = system.online.status;
|
|
44
|
+
this._updateOnlineStatus(onlineStatus);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return response;
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Gets system debug information from the device.
|
|
53
|
+
*
|
|
54
|
+
* @returns {Promise<Object>} Response containing debug information
|
|
55
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
56
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
57
|
+
*/
|
|
58
|
+
async getSystemDebug() {
|
|
59
|
+
return await this.publishMessage('GET', 'Appliance.System.Debug', {});
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Gets the device abilities (supported namespaces).
|
|
64
|
+
*
|
|
65
|
+
* Automatically updates the internal abilities cache when the response is received.
|
|
66
|
+
*
|
|
67
|
+
* @returns {Promise<Object>} Response containing device abilities
|
|
68
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
69
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
70
|
+
*/
|
|
71
|
+
async getSystemAbilities() {
|
|
72
|
+
const response = await this.publishMessage('GET', 'Appliance.System.Ability', {});
|
|
73
|
+
if (response && response.ability) {
|
|
74
|
+
this.updateAbilities(response.ability);
|
|
75
|
+
}
|
|
76
|
+
return response;
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Gets encryption suite information from the device.
|
|
81
|
+
*
|
|
82
|
+
* @returns {Promise<Object>} Response containing encryption suite info
|
|
83
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
84
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
85
|
+
*/
|
|
86
|
+
async getEncryptSuite() {
|
|
87
|
+
return await this.publishMessage('GET', 'Appliance.Encrypt.Suite', {});
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Gets ECDHE encryption information from the device.
|
|
92
|
+
*
|
|
93
|
+
* @returns {Promise<Object>} Response containing ECDHE encryption info
|
|
94
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
95
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
96
|
+
*/
|
|
97
|
+
async getEncryptECDHE() {
|
|
98
|
+
return await this.publishMessage('GET', 'Appliance.Encrypt.ECDHE', {});
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Gets the online status from the device.
|
|
103
|
+
*
|
|
104
|
+
* @returns {Promise<Object>} Response containing online status
|
|
105
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
106
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
107
|
+
*/
|
|
108
|
+
async getOnlineStatus() {
|
|
109
|
+
return await this.publishMessage('GET', 'Appliance.System.Online', {});
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Gets the WiFi list configuration from the device.
|
|
114
|
+
*
|
|
115
|
+
* Automatically decodes SSIDs from base64 encoding in the response.
|
|
116
|
+
*
|
|
117
|
+
* @returns {Promise<Object>} Response containing WiFi list with decoded SSIDs
|
|
118
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
119
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
120
|
+
*/
|
|
121
|
+
async getConfigWifiList() {
|
|
122
|
+
const response = await this.publishMessage('GET', 'Appliance.Config.WifiList', {});
|
|
123
|
+
|
|
124
|
+
if (response && response.wifiList) {
|
|
125
|
+
const { decodeSSID } = require('../../utilities/ssid');
|
|
126
|
+
const wifiList = Array.isArray(response.wifiList) ? response.wifiList : [response.wifiList];
|
|
127
|
+
wifiList.forEach(wifi => {
|
|
128
|
+
if (wifi.ssid) {
|
|
129
|
+
wifi.ssid = decodeSSID(wifi.ssid);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return response;
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Gets trace configuration from the device.
|
|
139
|
+
*
|
|
140
|
+
* Automatically decodes SSID from base64 encoding in the response.
|
|
141
|
+
*
|
|
142
|
+
* @returns {Promise<Object>} Response containing trace config with decoded SSID
|
|
143
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
144
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
145
|
+
*/
|
|
146
|
+
async getConfigTrace() {
|
|
147
|
+
const response = await this.publishMessage('GET', 'Appliance.Config.Trace', {});
|
|
148
|
+
|
|
149
|
+
if (response && response.trace && response.trace.ssid) {
|
|
150
|
+
const { decodeSSID } = require('../../utilities/ssid');
|
|
151
|
+
response.trace.ssid = decodeSSID(response.trace.ssid);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return response;
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Gets system hardware information from the device.
|
|
159
|
+
*
|
|
160
|
+
* Automatically updates the MAC address cache if available in the response.
|
|
161
|
+
*
|
|
162
|
+
* @returns {Promise<Object>} Response containing hardware information
|
|
163
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
164
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
165
|
+
*/
|
|
166
|
+
async getSystemHardware() {
|
|
167
|
+
const response = await this.publishMessage('GET', 'Appliance.System.Hardware', {});
|
|
168
|
+
if (response && response.hardware) {
|
|
169
|
+
this._systemHardware = response.hardware;
|
|
170
|
+
if (response.hardware.macAddress) {
|
|
171
|
+
this.updateMacAddress(response.hardware.macAddress);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return response;
|
|
175
|
+
},
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Gets system firmware information from the device.
|
|
179
|
+
*
|
|
180
|
+
* Automatically extracts and caches LAN IP and MQTT connection information if available.
|
|
181
|
+
*
|
|
182
|
+
* @returns {Promise<Object>} Response containing firmware information
|
|
183
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
184
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
185
|
+
*/
|
|
186
|
+
async getSystemFirmware() {
|
|
187
|
+
const response = await this.publishMessage('GET', 'Appliance.System.Firmware', {});
|
|
188
|
+
if (response && response.firmware) {
|
|
189
|
+
this._systemFirmware = response.firmware;
|
|
190
|
+
if (response.firmware.innerIp) {
|
|
191
|
+
this._lanIp = response.firmware.innerIp;
|
|
192
|
+
}
|
|
193
|
+
if (response.firmware.server) {
|
|
194
|
+
this._mqttHost = response.firmware.server;
|
|
195
|
+
}
|
|
196
|
+
if (response.firmware.port) {
|
|
197
|
+
this._mqttPort = response.firmware.port;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return response;
|
|
201
|
+
},
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Gets system time information from the device.
|
|
205
|
+
* * @returns {Promise<Object>} Response containing time information
|
|
206
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
207
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
208
|
+
*/
|
|
209
|
+
async getSystemTime() {
|
|
210
|
+
return await this.publishMessage('GET', 'Appliance.System.Time', {});
|
|
211
|
+
},
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Gets system position information from the device.
|
|
215
|
+
*
|
|
216
|
+
* @returns {Promise<Object>} Response containing position information
|
|
217
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
218
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
219
|
+
*/
|
|
220
|
+
async getSystemPosition() {
|
|
221
|
+
return await this.publishMessage('GET', 'Appliance.System.Position', {});
|
|
222
|
+
},
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Gets system factory test information from the device.
|
|
226
|
+
* * @returns {Promise<Object>} Response containing factory test information
|
|
227
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
228
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
229
|
+
*/
|
|
230
|
+
async getSystemFactory() {
|
|
231
|
+
return await this.publishMessage('GET', 'Appliance.System.Factory', {});
|
|
232
|
+
},
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Gets system LED mode configuration from the device.
|
|
236
|
+
*
|
|
237
|
+
* @returns {Promise<Object>} Response containing LED mode configuration
|
|
238
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
239
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
240
|
+
*/
|
|
241
|
+
async getSystemLedMode() {
|
|
242
|
+
return await this.publishMessage('GET', 'Appliance.System.LedMode', {});
|
|
243
|
+
},
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Controls the system LED mode configuration.
|
|
247
|
+
*
|
|
248
|
+
* @param {Object} ledModeData - LED mode data object with mode property (0=off, 1=match power, 2=opposite power) *
|
|
249
|
+
* @returns {Promise<Object>} Response from the device
|
|
250
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
251
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
252
|
+
*/
|
|
253
|
+
async setSystemLedMode(ledModeData) {
|
|
254
|
+
const payload = { LedMode: ledModeData };
|
|
255
|
+
return await this.publishMessage('SET', 'Appliance.System.LedMode', payload);
|
|
256
|
+
},
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Gets MCU firmware information from the device.
|
|
260
|
+
*
|
|
261
|
+
* @returns {Promise<Object>} Response containing MCU firmware information
|
|
262
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
263
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
264
|
+
*/
|
|
265
|
+
async getMcuFirmware() {
|
|
266
|
+
return await this.publishMessage('GET', 'Appliance.Mcu.Firmware', {});
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { normalizeChannel } = require('../../utilities/options');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Temperature unit feature module.
|
|
7
|
+
* Provides control over the temperature unit display preference (Celsius or Fahrenheit).
|
|
8
|
+
*/
|
|
9
|
+
module.exports = {
|
|
10
|
+
/**
|
|
11
|
+
* Gets the temperature unit configuration from the device.
|
|
12
|
+
*
|
|
13
|
+
* @param {Object} [options={}] - Get options
|
|
14
|
+
* @param {number} [options.channel=0] - Channel to get temperature unit for (default: 0)
|
|
15
|
+
* @returns {Promise<Object>} Response containing temperature unit configuration with `tempUnit` array
|
|
16
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
17
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
18
|
+
*/
|
|
19
|
+
async getTempUnit(options = {}) {
|
|
20
|
+
const channel = normalizeChannel(options);
|
|
21
|
+
const payload = {
|
|
22
|
+
tempUnit: [{
|
|
23
|
+
channel
|
|
24
|
+
}]
|
|
25
|
+
};
|
|
26
|
+
return await this.publishMessage('GET', 'Appliance.Control.TempUnit', payload);
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Controls the temperature unit configuration.
|
|
31
|
+
*
|
|
32
|
+
* @param {Object} options - Temperature unit options
|
|
33
|
+
* @param {Object|Array<Object>} [options.tempUnitData] - Temperature unit data object or array of tempUnit items (if provided, used directly)
|
|
34
|
+
* @param {number} [options.channel] - Channel to configure
|
|
35
|
+
* @param {number} [options.tempUnit] - Temperature unit (1 = Celsius, 2 = Fahrenheit)
|
|
36
|
+
* @returns {Promise<Object>} Response from the device
|
|
37
|
+
* @throws {import('../lib/errors/errors').UnconnectedError} If device is not connected
|
|
38
|
+
* @throws {import('../lib/errors/errors').CommandTimeoutError} If command times out
|
|
39
|
+
*/
|
|
40
|
+
async setTempUnit(options = {}) {
|
|
41
|
+
let tempUnitData;
|
|
42
|
+
if (options.tempUnitData) {
|
|
43
|
+
tempUnitData = Array.isArray(options.tempUnitData) ? options.tempUnitData : [options.tempUnitData];
|
|
44
|
+
} else {
|
|
45
|
+
const channel = normalizeChannel(options);
|
|
46
|
+
tempUnitData = [{
|
|
47
|
+
channel,
|
|
48
|
+
tempUnit: options.tempUnit
|
|
49
|
+
}];
|
|
50
|
+
}
|
|
51
|
+
const payload = { tempUnit: tempUnitData };
|
|
52
|
+
return await this.publishMessage('SET', 'Appliance.Control.TempUnit', payload);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|