meross-cli 0.3.0 → 0.5.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 +26 -0
- package/README.md +46 -5
- package/cli/commands/control/execute.js +50 -7
- package/cli/commands/control/menu.js +3 -5
- package/cli/commands/control/params/index.js +16 -12
- package/cli/commands/control/params/light.js +55 -25
- package/cli/commands/control/params/thermostat.js +24 -22
- package/cli/commands/control/params/timer.js +18 -15
- package/cli/commands/control/params/trigger.js +24 -13
- package/cli/commands/info.js +39 -15
- package/cli/commands/sniffer/sniffer-menu.js +2 -2
- package/cli/commands/status/device-status.js +418 -1292
- package/cli/commands/status/hub-status.js +14 -6
- package/cli/control-registry.js +211 -406
- package/cli/helpers/client.js +16 -10
- package/cli/helpers/meross.js +18 -14
- package/cli/menu/main.js +170 -13
- package/cli/menu/settings.js +2 -2
- package/cli/meross-cli.js +13 -47
- package/cli/tests/README.md +2 -0
- package/cli/tests/test-alarm.js +22 -2
- package/cli/tests/test-child-lock.js +40 -10
- package/cli/tests/test-config.js +22 -2
- package/cli/tests/test-control.js +8 -8
- package/cli/tests/test-diffuser.js +7 -7
- package/cli/tests/test-dnd.js +87 -66
- package/cli/tests/test-electricity.js +37 -33
- package/cli/tests/test-encryption.js +13 -13
- package/cli/tests/test-garage.js +12 -14
- package/cli/tests/test-helper.js +1 -1
- package/cli/tests/test-hub-sensors.js +3 -3
- package/cli/tests/test-light.js +497 -105
- package/cli/tests/test-presence.js +10 -55
- package/cli/tests/test-registry.js +7 -1
- package/cli/tests/test-roller-shutter.js +78 -90
- package/cli/tests/test-screen.js +1 -1
- package/cli/tests/test-sensor-history.js +6 -2
- package/cli/tests/test-smoke-config.js +24 -4
- package/cli/tests/test-spray.js +11 -11
- package/cli/tests/test-system.js +375 -0
- package/cli/tests/test-temp-unit.js +22 -2
- package/cli/tests/test-template.js +61 -73
- package/cli/tests/test-thermostat.js +126 -89
- package/cli/tests/test-timer.js +8 -51
- package/cli/tests/test-toggle.js +49 -173
- package/cli/tests/test-trigger.js +7 -50
- package/cli/utils/error-handler.js +257 -0
- package/package.json +2 -2
package/cli/tests/test-config.js
CHANGED
|
@@ -47,7 +47,17 @@ async function runTests(context) {
|
|
|
47
47
|
|
|
48
48
|
// Test 1: Get config over temp
|
|
49
49
|
try {
|
|
50
|
-
|
|
50
|
+
if (!testDevice.config) {
|
|
51
|
+
results.push({
|
|
52
|
+
name: 'should get config over temp',
|
|
53
|
+
passed: false,
|
|
54
|
+
skipped: true,
|
|
55
|
+
error: 'Device does not support config feature',
|
|
56
|
+
device: deviceName
|
|
57
|
+
});
|
|
58
|
+
return results;
|
|
59
|
+
}
|
|
60
|
+
const response = await testDevice.config.get();
|
|
51
61
|
|
|
52
62
|
if (!response) {
|
|
53
63
|
results.push({
|
|
@@ -87,8 +97,18 @@ async function runTests(context) {
|
|
|
87
97
|
|
|
88
98
|
// Test 2: Control config over temp
|
|
89
99
|
try {
|
|
100
|
+
if (!testDevice.config) {
|
|
101
|
+
results.push({
|
|
102
|
+
name: 'should control config over temp',
|
|
103
|
+
passed: false,
|
|
104
|
+
skipped: true,
|
|
105
|
+
error: 'Device does not support config feature',
|
|
106
|
+
device: deviceName
|
|
107
|
+
});
|
|
108
|
+
return results;
|
|
109
|
+
}
|
|
90
110
|
// Get current config first
|
|
91
|
-
const currentResponse = await testDevice.
|
|
111
|
+
const currentResponse = await testDevice.config.get();
|
|
92
112
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
93
113
|
|
|
94
114
|
if (!currentResponse || !currentResponse.overTemp) {
|
|
@@ -63,12 +63,12 @@ async function runTests(context) {
|
|
|
63
63
|
|
|
64
64
|
// Test 1: Control Multiple
|
|
65
65
|
try {
|
|
66
|
-
if (typeof device.setMultiple !== 'function') {
|
|
66
|
+
if (!device.control || typeof device.control.setMultiple !== 'function') {
|
|
67
67
|
results.push({
|
|
68
68
|
name: 'should execute multiple commands',
|
|
69
69
|
passed: false,
|
|
70
70
|
skipped: true,
|
|
71
|
-
error: 'Device does not support setMultiple',
|
|
71
|
+
error: 'Device does not support control.setMultiple',
|
|
72
72
|
device: deviceName
|
|
73
73
|
});
|
|
74
74
|
} else {
|
|
@@ -85,14 +85,14 @@ async function runTests(context) {
|
|
|
85
85
|
}
|
|
86
86
|
];
|
|
87
87
|
|
|
88
|
-
const response = await device.setMultiple(commands);
|
|
88
|
+
const response = await device.control.setMultiple({ commands });
|
|
89
89
|
|
|
90
90
|
if (!response) {
|
|
91
91
|
results.push({
|
|
92
92
|
name: 'should execute multiple commands',
|
|
93
93
|
passed: false,
|
|
94
94
|
skipped: false,
|
|
95
|
-
error: 'setMultiple returned null or undefined',
|
|
95
|
+
error: 'control.setMultiple returned null or undefined',
|
|
96
96
|
device: deviceName
|
|
97
97
|
});
|
|
98
98
|
} else {
|
|
@@ -117,12 +117,12 @@ async function runTests(context) {
|
|
|
117
117
|
|
|
118
118
|
// Test 2: Control Over Temp
|
|
119
119
|
try {
|
|
120
|
-
if (typeof device.
|
|
120
|
+
if (!device.control || typeof device.control.acknowledgeOverTemp !== 'function') {
|
|
121
121
|
results.push({
|
|
122
122
|
name: 'should acknowledge over temp event',
|
|
123
123
|
passed: false,
|
|
124
124
|
skipped: true,
|
|
125
|
-
error: 'Device does not support
|
|
125
|
+
error: 'Device does not support control.acknowledgeOverTemp',
|
|
126
126
|
device: deviceName
|
|
127
127
|
});
|
|
128
128
|
} else {
|
|
@@ -149,12 +149,12 @@ async function runTests(context) {
|
|
|
149
149
|
|
|
150
150
|
// Test 3: Control Upgrade
|
|
151
151
|
try {
|
|
152
|
-
if (typeof device.setUpgrade !== 'function') {
|
|
152
|
+
if (!device.control || typeof device.control.setUpgrade !== 'function') {
|
|
153
153
|
results.push({
|
|
154
154
|
name: 'should have upgrade method available',
|
|
155
155
|
passed: false,
|
|
156
156
|
skipped: true,
|
|
157
|
-
error: 'Device does not support setUpgrade',
|
|
157
|
+
error: 'Device does not support control.setUpgrade',
|
|
158
158
|
device: deviceName
|
|
159
159
|
});
|
|
160
160
|
} else {
|
|
@@ -43,13 +43,13 @@ async function runTests(context) {
|
|
|
43
43
|
// Wait for devices to be connected
|
|
44
44
|
for (const device of lightDevices) {
|
|
45
45
|
await waitForDeviceConnection(device, timeout);
|
|
46
|
-
await device.
|
|
46
|
+
await device.diffuser.get({ type: 'light', channel: 0 });
|
|
47
47
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
for (const device of sprayDevices) {
|
|
51
51
|
await waitForDeviceConnection(device, timeout);
|
|
52
|
-
await device.
|
|
52
|
+
await device.diffuser.get({ type: 'spray', channel: 0 });
|
|
53
53
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -67,7 +67,7 @@ async function runTests(context) {
|
|
|
67
67
|
const deviceName = getDeviceName(light);
|
|
68
68
|
|
|
69
69
|
try {
|
|
70
|
-
await light.
|
|
70
|
+
await light.diffuser.get({ type: 'light', channel: 0 });
|
|
71
71
|
|
|
72
72
|
// Set mode to FIXED_RGB
|
|
73
73
|
await light.setDiffuserLight({
|
|
@@ -142,7 +142,7 @@ async function runTests(context) {
|
|
|
142
142
|
const deviceName = getDeviceName(light);
|
|
143
143
|
|
|
144
144
|
try {
|
|
145
|
-
await light.
|
|
145
|
+
await light.diffuser.get({ type: 'light', channel: 0 });
|
|
146
146
|
|
|
147
147
|
// Set mode to FIXED RGB
|
|
148
148
|
await light.setDiffuserLight({
|
|
@@ -275,7 +275,7 @@ async function runTests(context) {
|
|
|
275
275
|
const deviceName = getDeviceName(light);
|
|
276
276
|
|
|
277
277
|
try {
|
|
278
|
-
await light.
|
|
278
|
+
await light.diffuser.get({ type: 'light', channel: 0 });
|
|
279
279
|
|
|
280
280
|
await light.setDiffuserLight({
|
|
281
281
|
channel: 0,
|
|
@@ -365,7 +365,7 @@ async function runTests(context) {
|
|
|
365
365
|
const deviceName = getDeviceName(light);
|
|
366
366
|
|
|
367
367
|
try {
|
|
368
|
-
await light.
|
|
368
|
+
await light.diffuser.get({ type: 'light', channel: 0 });
|
|
369
369
|
|
|
370
370
|
await light.setDiffuserLight({
|
|
371
371
|
channel: 0,
|
|
@@ -430,7 +430,7 @@ async function runTests(context) {
|
|
|
430
430
|
const deviceName = getDeviceName(spray);
|
|
431
431
|
|
|
432
432
|
try {
|
|
433
|
-
await spray.
|
|
433
|
+
await spray.diffuser.getSpray({ channel: 0 });
|
|
434
434
|
|
|
435
435
|
await spray.setDiffuserSpray(0, DiffuserSprayMode.LIGHT);
|
|
436
436
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
package/cli/tests/test-dnd.js
CHANGED
|
@@ -27,8 +27,9 @@ async function runTests(context) {
|
|
|
27
27
|
const allDevices = manager.devices.list();
|
|
28
28
|
testDevices = allDevices.filter(d => {
|
|
29
29
|
return d.onlineStatus === OnlineStatus.ONLINE &&
|
|
30
|
-
|
|
31
|
-
typeof d.
|
|
30
|
+
d.dnd &&
|
|
31
|
+
typeof d.dnd.get === 'function' &&
|
|
32
|
+
typeof d.dnd.set === 'function';
|
|
32
33
|
});
|
|
33
34
|
}
|
|
34
35
|
|
|
@@ -56,67 +57,77 @@ async function runTests(context) {
|
|
|
56
57
|
|
|
57
58
|
// Test 1: Get and set DND mode
|
|
58
59
|
try {
|
|
59
|
-
|
|
60
|
-
const initialMode = await testDevice.getDNDMode();
|
|
61
|
-
|
|
62
|
-
if (initialMode === null || initialMode === undefined) {
|
|
60
|
+
if (!testDevice.dnd) {
|
|
63
61
|
results.push({
|
|
64
62
|
name: 'should get and set DND mode',
|
|
65
63
|
passed: false,
|
|
66
|
-
skipped:
|
|
67
|
-
error: '
|
|
68
|
-
device: deviceName
|
|
69
|
-
});
|
|
70
|
-
} else if (initialMode !== DNDMode.DND_DISABLED && initialMode !== DNDMode.DND_ENABLED) {
|
|
71
|
-
results.push({
|
|
72
|
-
name: 'should get and set DND mode',
|
|
73
|
-
passed: false,
|
|
74
|
-
skipped: false,
|
|
75
|
-
error: `Invalid DND mode value: ${initialMode}`,
|
|
64
|
+
skipped: true,
|
|
65
|
+
error: 'Device does not support DND feature',
|
|
76
66
|
device: deviceName
|
|
77
67
|
});
|
|
78
68
|
} else {
|
|
79
|
-
//
|
|
80
|
-
const
|
|
81
|
-
await testDevice.setDNDMode({ mode: newMode });
|
|
69
|
+
// Get current DND mode
|
|
70
|
+
const initialMode = await testDevice.dnd.get();
|
|
82
71
|
|
|
83
|
-
|
|
84
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
85
|
-
|
|
86
|
-
// Verify the change
|
|
87
|
-
const updatedMode = await testDevice.getDNDMode();
|
|
88
|
-
|
|
89
|
-
if (updatedMode !== newMode) {
|
|
72
|
+
if (initialMode === null || initialMode === undefined) {
|
|
90
73
|
results.push({
|
|
91
74
|
name: 'should get and set DND mode',
|
|
92
75
|
passed: false,
|
|
93
76
|
skipped: false,
|
|
94
|
-
error:
|
|
77
|
+
error: 'dnd.get() returned null or undefined',
|
|
78
|
+
device: deviceName
|
|
79
|
+
});
|
|
80
|
+
} else if (initialMode !== DNDMode.DND_DISABLED && initialMode !== DNDMode.DND_ENABLED) {
|
|
81
|
+
results.push({
|
|
82
|
+
name: 'should get and set DND mode',
|
|
83
|
+
passed: false,
|
|
84
|
+
skipped: false,
|
|
85
|
+
error: `Invalid DND mode value: ${initialMode}`,
|
|
95
86
|
device: deviceName
|
|
96
87
|
});
|
|
97
88
|
} else {
|
|
98
|
-
//
|
|
99
|
-
|
|
89
|
+
// Toggle DND mode
|
|
90
|
+
const newMode = initialMode === DNDMode.DND_ENABLED ? DNDMode.DND_DISABLED : DNDMode.DND_ENABLED;
|
|
91
|
+
await testDevice.dnd.set({ mode: newMode });
|
|
92
|
+
|
|
93
|
+
// Wait for the change to take effect
|
|
100
94
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
101
95
|
|
|
102
|
-
|
|
96
|
+
// Verify the change
|
|
97
|
+
const updatedMode = await testDevice.dnd.get();
|
|
103
98
|
|
|
104
|
-
if (
|
|
99
|
+
if (updatedMode !== newMode) {
|
|
105
100
|
results.push({
|
|
106
101
|
name: 'should get and set DND mode',
|
|
107
102
|
passed: false,
|
|
108
103
|
skipped: false,
|
|
109
|
-
error: `
|
|
104
|
+
error: `DND mode did not change. Expected ${newMode}, got ${updatedMode}`,
|
|
110
105
|
device: deviceName
|
|
111
106
|
});
|
|
112
107
|
} else {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
108
|
+
// Restore original mode
|
|
109
|
+
await testDevice.dnd.set({ mode: initialMode });
|
|
110
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
111
|
+
|
|
112
|
+
const restoredMode = await testDevice.dnd.get();
|
|
113
|
+
|
|
114
|
+
if (restoredMode !== initialMode) {
|
|
115
|
+
results.push({
|
|
116
|
+
name: 'should get and set DND mode',
|
|
117
|
+
passed: false,
|
|
118
|
+
skipped: false,
|
|
119
|
+
error: `Failed to restore DND mode. Expected ${initialMode}, got ${restoredMode}`,
|
|
120
|
+
device: deviceName
|
|
121
|
+
});
|
|
122
|
+
} else {
|
|
123
|
+
results.push({
|
|
124
|
+
name: 'should get and set DND mode',
|
|
125
|
+
passed: true,
|
|
126
|
+
skipped: false,
|
|
127
|
+
error: null,
|
|
128
|
+
device: deviceName
|
|
129
|
+
});
|
|
130
|
+
}
|
|
120
131
|
}
|
|
121
132
|
}
|
|
122
133
|
}
|
|
@@ -132,37 +143,47 @@ async function runTests(context) {
|
|
|
132
143
|
|
|
133
144
|
// Test 2: Accept boolean values for DND mode
|
|
134
145
|
try {
|
|
135
|
-
|
|
136
|
-
const initialMode = await testDevice.getDNDMode();
|
|
137
|
-
const initialBoolean = initialMode === DNDMode.DND_ENABLED;
|
|
138
|
-
|
|
139
|
-
// Set using boolean (true = enabled)
|
|
140
|
-
await testDevice.setDNDMode({ mode: !initialBoolean });
|
|
141
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
142
|
-
|
|
143
|
-
const updatedMode = await testDevice.getDNDMode();
|
|
144
|
-
const expectedMode = !initialBoolean ? DNDMode.DND_ENABLED : DNDMode.DND_DISABLED;
|
|
145
|
-
|
|
146
|
-
if (updatedMode !== expectedMode) {
|
|
146
|
+
if (!testDevice.dnd) {
|
|
147
147
|
results.push({
|
|
148
148
|
name: 'should accept boolean values for DND mode',
|
|
149
149
|
passed: false,
|
|
150
|
-
skipped:
|
|
151
|
-
error:
|
|
150
|
+
skipped: true,
|
|
151
|
+
error: 'Device does not support DND feature',
|
|
152
152
|
device: deviceName
|
|
153
153
|
});
|
|
154
154
|
} else {
|
|
155
|
-
//
|
|
156
|
-
await testDevice.
|
|
155
|
+
// Get current mode
|
|
156
|
+
const initialMode = await testDevice.dnd.get();
|
|
157
|
+
const initialBoolean = initialMode === DNDMode.DND_ENABLED;
|
|
158
|
+
|
|
159
|
+
// Set using boolean (true = enabled)
|
|
160
|
+
await testDevice.dnd.set({ mode: !initialBoolean });
|
|
157
161
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
158
162
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
163
|
+
const updatedMode = await testDevice.dnd.get();
|
|
164
|
+
const expectedMode = !initialBoolean ? DNDMode.DND_ENABLED : DNDMode.DND_DISABLED;
|
|
165
|
+
|
|
166
|
+
if (updatedMode !== expectedMode) {
|
|
167
|
+
results.push({
|
|
168
|
+
name: 'should accept boolean values for DND mode',
|
|
169
|
+
passed: false,
|
|
170
|
+
skipped: false,
|
|
171
|
+
error: `Boolean set failed. Expected ${expectedMode}, got ${updatedMode}`,
|
|
172
|
+
device: deviceName
|
|
173
|
+
});
|
|
174
|
+
} else {
|
|
175
|
+
// Restore original mode
|
|
176
|
+
await testDevice.dnd.set({ mode: initialBoolean });
|
|
177
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
178
|
+
|
|
179
|
+
results.push({
|
|
180
|
+
name: 'should accept boolean values for DND mode',
|
|
181
|
+
passed: true,
|
|
182
|
+
skipped: false,
|
|
183
|
+
error: null,
|
|
184
|
+
device: deviceName
|
|
185
|
+
});
|
|
186
|
+
}
|
|
166
187
|
}
|
|
167
188
|
} catch (error) {
|
|
168
189
|
results.push({
|
|
@@ -176,16 +197,16 @@ async function runTests(context) {
|
|
|
176
197
|
|
|
177
198
|
// Test 3: Get raw DND mode value
|
|
178
199
|
try {
|
|
179
|
-
if (typeof testDevice.
|
|
200
|
+
if (!testDevice.dnd || typeof testDevice.dnd.getRaw !== 'function') {
|
|
180
201
|
results.push({
|
|
181
202
|
name: 'should get raw DND mode value',
|
|
182
203
|
passed: false,
|
|
183
204
|
skipped: true,
|
|
184
|
-
error: 'Device does not support
|
|
205
|
+
error: 'Device does not support dnd.getRaw',
|
|
185
206
|
device: deviceName
|
|
186
207
|
});
|
|
187
208
|
} else {
|
|
188
|
-
const rawMode = await testDevice.
|
|
209
|
+
const rawMode = await testDevice.dnd.getRaw();
|
|
189
210
|
|
|
190
211
|
if (typeof rawMode !== 'number') {
|
|
191
212
|
results.push({
|
|
@@ -205,7 +226,7 @@ async function runTests(context) {
|
|
|
205
226
|
});
|
|
206
227
|
} else {
|
|
207
228
|
// Verify it matches enum value
|
|
208
|
-
const enumMode = await testDevice.
|
|
229
|
+
const enumMode = await testDevice.dnd.get();
|
|
209
230
|
|
|
210
231
|
if (rawMode !== enumMode) {
|
|
211
232
|
results.push({
|
|
@@ -10,7 +10,7 @@ const { findDevicesByAbility, waitForDeviceConnection, getDeviceName, OnlineStat
|
|
|
10
10
|
const metadata = {
|
|
11
11
|
name: 'electricity',
|
|
12
12
|
description: 'Tests electricity metrics and power consumption tracking',
|
|
13
|
-
requiredAbilities: ['Appliance.Control.ConsumptionX', 'Appliance.Control.Consumption', 'Appliance.Control.Electricity'],
|
|
13
|
+
requiredAbilities: ['Appliance.Control.ConsumptionH', 'Appliance.Control.ConsumptionX', 'Appliance.Control.Consumption', 'Appliance.Control.Electricity'],
|
|
14
14
|
minDevices: 1
|
|
15
15
|
};
|
|
16
16
|
|
|
@@ -22,8 +22,12 @@ async function runTests(context) {
|
|
|
22
22
|
// If no devices provided, discover them
|
|
23
23
|
let testDevices = devices || [];
|
|
24
24
|
if (testDevices.length === 0) {
|
|
25
|
-
// Find consumption/electricity devices (try
|
|
26
|
-
testDevices = await findDevicesByAbility(manager, 'Appliance.Control.
|
|
25
|
+
// Find consumption/electricity devices (try ConsumptionH first, then ConsumptionX, then Consumption, then Electricity)
|
|
26
|
+
testDevices = await findDevicesByAbility(manager, 'Appliance.Control.ConsumptionH', OnlineStatus.ONLINE);
|
|
27
|
+
|
|
28
|
+
if (testDevices.length === 0) {
|
|
29
|
+
testDevices = await findDevicesByAbility(manager, 'Appliance.Control.ConsumptionX', OnlineStatus.ONLINE);
|
|
30
|
+
}
|
|
27
31
|
|
|
28
32
|
if (testDevices.length === 0) {
|
|
29
33
|
testDevices = await findDevicesByAbility(manager, 'Appliance.Control.Consumption', OnlineStatus.ONLINE);
|
|
@@ -39,7 +43,7 @@ async function runTests(context) {
|
|
|
39
43
|
name: 'should get instant electricity metrics',
|
|
40
44
|
passed: false,
|
|
41
45
|
skipped: true,
|
|
42
|
-
error: 'No ConsumptionX/Electricity device has been found to run this test on',
|
|
46
|
+
error: 'No ConsumptionH/ConsumptionX/Consumption/Electricity device has been found to run this test on',
|
|
43
47
|
device: null
|
|
44
48
|
});
|
|
45
49
|
return results;
|
|
@@ -53,35 +57,35 @@ async function runTests(context) {
|
|
|
53
57
|
|
|
54
58
|
// Test 1: Get instant electricity metrics
|
|
55
59
|
try {
|
|
56
|
-
|
|
57
|
-
let metrics = null;
|
|
58
|
-
|
|
59
|
-
// Check which method is available
|
|
60
|
-
if (typeof testDevice.getElectricity === 'function') {
|
|
61
|
-
metrics = await testDevice.getElectricity();
|
|
62
|
-
} else if (typeof testDevice.getPowerConsumptionX === 'function') {
|
|
63
|
-
metrics = await testDevice.getPowerConsumptionX();
|
|
64
|
-
} else if (typeof testDevice.getPowerConsumption === 'function') {
|
|
65
|
-
metrics = await testDevice.getPowerConsumption();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (!metrics || typeof metrics !== 'object') {
|
|
60
|
+
if (!testDevice.electricity || typeof testDevice.electricity.get !== 'function') {
|
|
69
61
|
results.push({
|
|
70
62
|
name: 'should get instant electricity metrics',
|
|
71
63
|
passed: false,
|
|
72
|
-
skipped:
|
|
73
|
-
error: '
|
|
64
|
+
skipped: true,
|
|
65
|
+
error: 'Device does not support electricity feature',
|
|
74
66
|
device: deviceName
|
|
75
67
|
});
|
|
76
68
|
} else {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
69
|
+
const metrics = await testDevice.electricity.get({ channel: 0 });
|
|
70
|
+
|
|
71
|
+
if (!metrics || typeof metrics !== 'object') {
|
|
72
|
+
results.push({
|
|
73
|
+
name: 'should get instant electricity metrics',
|
|
74
|
+
passed: false,
|
|
75
|
+
skipped: false,
|
|
76
|
+
error: 'electricity.get() returned null, undefined, or non-object',
|
|
77
|
+
device: deviceName
|
|
78
|
+
});
|
|
79
|
+
} else {
|
|
80
|
+
results.push({
|
|
81
|
+
name: 'should get instant electricity metrics',
|
|
82
|
+
passed: true,
|
|
83
|
+
skipped: false,
|
|
84
|
+
error: null,
|
|
85
|
+
device: deviceName,
|
|
86
|
+
details: { metrics: metrics }
|
|
87
|
+
});
|
|
88
|
+
}
|
|
85
89
|
}
|
|
86
90
|
} catch (error) {
|
|
87
91
|
results.push({
|
|
@@ -95,7 +99,7 @@ async function runTests(context) {
|
|
|
95
99
|
|
|
96
100
|
// Test 2: Get daily power consumption
|
|
97
101
|
try {
|
|
98
|
-
if (
|
|
102
|
+
if (!testDevice.consumption) {
|
|
99
103
|
results.push({
|
|
100
104
|
name: 'should get daily power consumption',
|
|
101
105
|
passed: false,
|
|
@@ -104,7 +108,7 @@ async function runTests(context) {
|
|
|
104
108
|
device: deviceName
|
|
105
109
|
});
|
|
106
110
|
} else {
|
|
107
|
-
const consumption = await testDevice.
|
|
111
|
+
const consumption = await testDevice.consumption.get({ channel: 0 });
|
|
108
112
|
|
|
109
113
|
if (!Array.isArray(consumption)) {
|
|
110
114
|
results.push({
|
|
@@ -160,23 +164,23 @@ async function runTests(context) {
|
|
|
160
164
|
|
|
161
165
|
// Test 3: Get consumption config
|
|
162
166
|
try {
|
|
163
|
-
if (
|
|
167
|
+
if (!testDevice.consumption) {
|
|
164
168
|
results.push({
|
|
165
169
|
name: 'should get consumption config',
|
|
166
170
|
passed: false,
|
|
167
171
|
skipped: true,
|
|
168
|
-
error: 'Device does not support
|
|
172
|
+
error: 'Device does not support consumption config',
|
|
169
173
|
device: deviceName
|
|
170
174
|
});
|
|
171
175
|
} else {
|
|
172
|
-
const response = await testDevice.
|
|
176
|
+
const response = await testDevice.consumption.getConfig();
|
|
173
177
|
|
|
174
178
|
if (!response) {
|
|
175
179
|
results.push({
|
|
176
180
|
name: 'should get consumption config',
|
|
177
181
|
passed: false,
|
|
178
182
|
skipped: false,
|
|
179
|
-
error: '
|
|
183
|
+
error: 'getConfig returned null or undefined',
|
|
180
184
|
device: deviceName
|
|
181
185
|
});
|
|
182
186
|
} else {
|
|
@@ -61,21 +61,21 @@ async function runTests(context) {
|
|
|
61
61
|
|
|
62
62
|
// Test 1: Detect encryption support
|
|
63
63
|
try {
|
|
64
|
-
if (typeof testDevice.supportEncryption !== 'function') {
|
|
64
|
+
if (!testDevice.encryption || typeof testDevice.encryption.supportEncryption !== 'function') {
|
|
65
65
|
results.push({
|
|
66
66
|
name: 'should detect encryption support',
|
|
67
67
|
passed: false,
|
|
68
68
|
skipped: true,
|
|
69
|
-
error: 'Device does not have encryption feature
|
|
69
|
+
error: 'Device does not have encryption feature',
|
|
70
70
|
device: deviceName
|
|
71
71
|
});
|
|
72
72
|
} else {
|
|
73
|
-
const supportsEncryption = testDevice.supportEncryption();
|
|
73
|
+
const supportsEncryption = testDevice.encryption.supportEncryption();
|
|
74
74
|
|
|
75
75
|
// Check if encryption key is set
|
|
76
76
|
let isKeySet = false;
|
|
77
77
|
if (supportsEncryption) {
|
|
78
|
-
isKeySet = testDevice.isEncryptionKeySet();
|
|
78
|
+
isKeySet = testDevice.encryption.isEncryptionKeySet();
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
results.push({
|
|
@@ -102,7 +102,7 @@ async function runTests(context) {
|
|
|
102
102
|
|
|
103
103
|
// Test 2: Set encryption key if supported
|
|
104
104
|
try {
|
|
105
|
-
if (typeof testDevice.supportEncryption !== 'function' || !testDevice.supportEncryption()) {
|
|
105
|
+
if (!testDevice.encryption || typeof testDevice.encryption.supportEncryption !== 'function' || !testDevice.encryption.supportEncryption()) {
|
|
106
106
|
results.push({
|
|
107
107
|
name: 'should set encryption key if supported',
|
|
108
108
|
passed: false,
|
|
@@ -112,13 +112,13 @@ async function runTests(context) {
|
|
|
112
112
|
});
|
|
113
113
|
} else {
|
|
114
114
|
// Check if key is already set
|
|
115
|
-
const isKeySet = testDevice.isEncryptionKeySet();
|
|
115
|
+
const isKeySet = testDevice.encryption.isEncryptionKeySet();
|
|
116
116
|
|
|
117
117
|
// If key is not set and we have the required info, set it
|
|
118
118
|
if (!isKeySet && testDevice.uuid && manager.key && testDevice.macAddress) {
|
|
119
|
-
testDevice.setEncryptionKey(testDevice.uuid, manager.key, testDevice.macAddress);
|
|
119
|
+
testDevice.encryption.setEncryptionKey(testDevice.uuid, manager.key, testDevice.macAddress);
|
|
120
120
|
|
|
121
|
-
const keySetAfter = testDevice.isEncryptionKeySet();
|
|
121
|
+
const keySetAfter = testDevice.encryption.isEncryptionKeySet();
|
|
122
122
|
|
|
123
123
|
if (!keySetAfter) {
|
|
124
124
|
results.push({
|
|
@@ -169,7 +169,7 @@ async function runTests(context) {
|
|
|
169
169
|
|
|
170
170
|
// Test 3: Encrypt and decrypt messages if encryption key is set
|
|
171
171
|
try {
|
|
172
|
-
if (typeof testDevice.supportEncryption !== 'function' || !testDevice.supportEncryption()) {
|
|
172
|
+
if (!testDevice.encryption || typeof testDevice.encryption.supportEncryption !== 'function' || !testDevice.encryption.supportEncryption()) {
|
|
173
173
|
results.push({
|
|
174
174
|
name: 'should encrypt and decrypt messages if encryption key is set',
|
|
175
175
|
passed: false,
|
|
@@ -179,9 +179,9 @@ async function runTests(context) {
|
|
|
179
179
|
});
|
|
180
180
|
} else {
|
|
181
181
|
// Ensure encryption key is set
|
|
182
|
-
if (!testDevice.isEncryptionKeySet()) {
|
|
182
|
+
if (!testDevice.encryption.isEncryptionKeySet()) {
|
|
183
183
|
if (testDevice.uuid && manager.key && testDevice.macAddress) {
|
|
184
|
-
testDevice.setEncryptionKey(testDevice.uuid, manager.key, testDevice.macAddress);
|
|
184
|
+
testDevice.encryption.setEncryptionKey(testDevice.uuid, manager.key, testDevice.macAddress);
|
|
185
185
|
} else {
|
|
186
186
|
results.push({
|
|
187
187
|
name: 'should encrypt and decrypt messages if encryption key is set',
|
|
@@ -198,7 +198,7 @@ async function runTests(context) {
|
|
|
198
198
|
const testMessage = { test: 'data', value: 123 };
|
|
199
199
|
|
|
200
200
|
try {
|
|
201
|
-
const encrypted = testDevice.encryptMessage(testMessage);
|
|
201
|
+
const encrypted = testDevice.encryption.encryptMessage(testMessage);
|
|
202
202
|
|
|
203
203
|
if (!encrypted) {
|
|
204
204
|
results.push({
|
|
@@ -223,7 +223,7 @@ async function runTests(context) {
|
|
|
223
223
|
return results;
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
-
const decrypted = testDevice.decryptMessage(encrypted);
|
|
226
|
+
const decrypted = testDevice.encryption.decryptMessage(encrypted);
|
|
227
227
|
|
|
228
228
|
if (!decrypted) {
|
|
229
229
|
results.push({
|