meross-cli 0.4.0 → 0.6.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 +19 -0
- package/README.md +24 -5
- package/cli/commands/control/execute.js +36 -6
- 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 +38 -43
- package/cli/commands/control/params/trigger.js +43 -40
- package/cli/commands/info.js +218 -17
- 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/meross-cli.js +1 -1
- 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 +9 -52
- package/cli/tests/test-toggle.js +49 -173
- package/cli/tests/test-trigger.js +8 -51
- package/package.json +2 -2
|
@@ -62,8 +62,8 @@ async function runTests(context) {
|
|
|
62
62
|
|
|
63
63
|
// Test 2: Get latest sensor readings
|
|
64
64
|
try {
|
|
65
|
-
if (typeof testDevice.
|
|
66
|
-
const readings = await testDevice.
|
|
65
|
+
if (testDevice.presence && typeof testDevice.presence.get === 'function') {
|
|
66
|
+
const readings = await testDevice.presence.get({ dataTypes: ['presence', 'light'], channel: 0 });
|
|
67
67
|
|
|
68
68
|
if (!readings || !readings.latest) {
|
|
69
69
|
results.push({
|
|
@@ -110,8 +110,8 @@ async function runTests(context) {
|
|
|
110
110
|
|
|
111
111
|
// Test 3: Get presence data
|
|
112
112
|
try {
|
|
113
|
-
if (typeof testDevice.getPresence === 'function') {
|
|
114
|
-
const presence = testDevice.getPresence();
|
|
113
|
+
if (testDevice.presence && typeof testDevice.presence.getPresence === 'function') {
|
|
114
|
+
const presence = testDevice.presence.getPresence({ channel: 0 });
|
|
115
115
|
|
|
116
116
|
// Presence can be null if no data yet, which is acceptable
|
|
117
117
|
if (presence === null) {
|
|
@@ -236,8 +236,8 @@ async function runTests(context) {
|
|
|
236
236
|
|
|
237
237
|
// Test 5: Get light reading
|
|
238
238
|
try {
|
|
239
|
-
if (typeof testDevice.getLight === 'function') {
|
|
240
|
-
const light = testDevice.getLight();
|
|
239
|
+
if (testDevice.presence && typeof testDevice.presence.getLight === 'function') {
|
|
240
|
+
const light = testDevice.presence.getLight({ channel: 0 });
|
|
241
241
|
|
|
242
242
|
// Light can be null if no data yet, which is acceptable
|
|
243
243
|
if (light === null) {
|
|
@@ -291,8 +291,8 @@ async function runTests(context) {
|
|
|
291
291
|
|
|
292
292
|
// Test 6: Get all sensor readings
|
|
293
293
|
try {
|
|
294
|
-
if (typeof testDevice.getAllSensorReadings === 'function') {
|
|
295
|
-
const allReadings = testDevice.getAllSensorReadings();
|
|
294
|
+
if (testDevice.presence && typeof testDevice.presence.getAllSensorReadings === 'function') {
|
|
295
|
+
const allReadings = testDevice.presence.getAllSensorReadings({ channel: 0 });
|
|
296
296
|
|
|
297
297
|
if (!allReadings || typeof allReadings !== 'object') {
|
|
298
298
|
results.push({
|
|
@@ -336,8 +336,8 @@ async function runTests(context) {
|
|
|
336
336
|
|
|
337
337
|
// Test 7: Get presence configuration
|
|
338
338
|
try {
|
|
339
|
-
if (typeof testDevice.
|
|
340
|
-
const config = await testDevice.
|
|
339
|
+
if (testDevice.presence && typeof testDevice.presence.getConfig === 'function') {
|
|
340
|
+
const config = await testDevice.presence.getConfig({ channel: 0 });
|
|
341
341
|
|
|
342
342
|
if (!config) {
|
|
343
343
|
results.push({
|
|
@@ -442,51 +442,6 @@ async function runTests(context) {
|
|
|
442
442
|
}
|
|
443
443
|
}
|
|
444
444
|
|
|
445
|
-
// Test 9: Handle presence push notifications
|
|
446
|
-
try {
|
|
447
|
-
// Set up listener for presence push notifications
|
|
448
|
-
let receivedNotification = false;
|
|
449
|
-
const notificationHandler = (notification) => {
|
|
450
|
-
if (notification.namespace === 'Appliance.Control.Sensor.LatestX') {
|
|
451
|
-
receivedNotification = true;
|
|
452
|
-
}
|
|
453
|
-
};
|
|
454
|
-
|
|
455
|
-
testDevice.on('pushNotification', notificationHandler);
|
|
456
|
-
|
|
457
|
-
// Request latest readings (may trigger a push notification)
|
|
458
|
-
if (typeof testDevice.getLatestSensorReadings === 'function') {
|
|
459
|
-
await testDevice.getLatestSensorReadings(['presence', 'light'], timeout);
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
// Wait a bit for potential push notifications
|
|
463
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
464
|
-
|
|
465
|
-
// Remove listener
|
|
466
|
-
testDevice.removeListener('pushNotification', notificationHandler);
|
|
467
|
-
|
|
468
|
-
// Note: We don't assert on receivedNotification since push notifications
|
|
469
|
-
// are device-initiated and may not occur during testing
|
|
470
|
-
// This test just verifies the listener mechanism works
|
|
471
|
-
results.push({
|
|
472
|
-
name: 'should handle presence push notifications',
|
|
473
|
-
passed: true,
|
|
474
|
-
skipped: false,
|
|
475
|
-
error: null,
|
|
476
|
-
device: deviceName,
|
|
477
|
-
details: { notificationReceived: receivedNotification }
|
|
478
|
-
});
|
|
479
|
-
|
|
480
|
-
} catch (error) {
|
|
481
|
-
results.push({
|
|
482
|
-
name: 'should handle presence push notifications',
|
|
483
|
-
passed: false,
|
|
484
|
-
skipped: false,
|
|
485
|
-
error: error.message,
|
|
486
|
-
device: deviceName
|
|
487
|
-
});
|
|
488
|
-
}
|
|
489
|
-
|
|
490
445
|
return results;
|
|
491
446
|
}
|
|
492
447
|
|
|
@@ -78,7 +78,7 @@ const TEST_METADATA = {
|
|
|
78
78
|
'electricity': {
|
|
79
79
|
file: 'test-electricity.js',
|
|
80
80
|
description: 'Tests power consumption metrics and daily consumption data',
|
|
81
|
-
requiredAbilities: ['Appliance.Control.ConsumptionX', 'Appliance.Control.Consumption', 'Appliance.Control.Electricity'],
|
|
81
|
+
requiredAbilities: ['Appliance.Control.ConsumptionH', 'Appliance.Control.ConsumptionX', 'Appliance.Control.Consumption', 'Appliance.Control.Electricity'],
|
|
82
82
|
minDevices: 1
|
|
83
83
|
},
|
|
84
84
|
'dnd': {
|
|
@@ -178,6 +178,12 @@ const TEST_METADATA = {
|
|
|
178
178
|
description: 'Tests presence detection, light readings, and configuration for presence sensor devices',
|
|
179
179
|
requiredAbilities: ['Appliance.Control.Sensor.LatestX'],
|
|
180
180
|
minDevices: 1
|
|
181
|
+
},
|
|
182
|
+
'system': {
|
|
183
|
+
file: 'test-system.js',
|
|
184
|
+
description: 'Tests system information, hardware, firmware, abilities, and configuration',
|
|
185
|
+
requiredAbilities: ['Appliance.System.All', 'Appliance.System.Ability'],
|
|
186
|
+
minDevices: 1
|
|
181
187
|
}
|
|
182
188
|
};
|
|
183
189
|
|
|
@@ -43,18 +43,21 @@ async function runTests(context) {
|
|
|
43
43
|
const deviceName = getDeviceName(testDevice);
|
|
44
44
|
|
|
45
45
|
await waitForDeviceConnection(testDevice, timeout);
|
|
46
|
-
await testDevice.
|
|
46
|
+
await testDevice.rollerShutter.get({ channel: 0 });
|
|
47
47
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
48
48
|
|
|
49
49
|
// Test 1: Open roller shutter
|
|
50
50
|
try {
|
|
51
|
-
await testDevice.
|
|
51
|
+
await testDevice.rollerShutter.get({ channel: 0 });
|
|
52
52
|
|
|
53
53
|
// Set timers (if method exists)
|
|
54
|
-
if (typeof testDevice.
|
|
55
|
-
await testDevice.
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
if (testDevice.rollerShutter && typeof testDevice.rollerShutter.setConfig === 'function') {
|
|
55
|
+
await testDevice.rollerShutter.setConfig({
|
|
56
|
+
config: [{
|
|
57
|
+
channel: 0,
|
|
58
|
+
open_timer_duration_millis: DEFAULT_OPEN_TIMER * 1000,
|
|
59
|
+
close_timer_duration_millis: DEFAULT_CLOSE_TIMER * 1000
|
|
60
|
+
}]
|
|
58
61
|
});
|
|
59
62
|
}
|
|
60
63
|
|
|
@@ -63,36 +66,28 @@ async function runTests(context) {
|
|
|
63
66
|
let stateIdle = false;
|
|
64
67
|
let positionOpened = false;
|
|
65
68
|
|
|
66
|
-
const
|
|
67
|
-
if (
|
|
68
|
-
if (
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
} else if (state.state === 0) { // IDLE
|
|
74
|
-
stateIdle = true;
|
|
75
|
-
}
|
|
69
|
+
const onStateChange = (event) => {
|
|
70
|
+
if (event.type === 'rollerShutter' && event.channel === 0) {
|
|
71
|
+
if (event.value.state !== undefined) {
|
|
72
|
+
if (event.value.state === 1) { // OPENING
|
|
73
|
+
stateOpening = true;
|
|
74
|
+
} else if (event.value.state === 0) { // IDLE
|
|
75
|
+
stateIdle = true;
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (payload.position) {
|
|
81
|
-
const position = Array.isArray(payload.position) ? payload.position[0] : payload.position;
|
|
82
|
-
if (position.channel === 0 && position.position === 100) {
|
|
83
|
-
positionOpened = true;
|
|
84
|
-
}
|
|
78
|
+
if (event.value.position !== undefined && event.value.position === 100) {
|
|
79
|
+
positionOpened = true;
|
|
85
80
|
}
|
|
86
81
|
}
|
|
87
82
|
};
|
|
88
83
|
|
|
89
|
-
testDevice.on('
|
|
84
|
+
testDevice.on('state', onStateChange);
|
|
90
85
|
|
|
91
86
|
// Trigger the opening
|
|
92
|
-
if (typeof testDevice.
|
|
93
|
-
await testDevice.
|
|
87
|
+
if (testDevice.rollerShutter && typeof testDevice.rollerShutter.open === 'function') {
|
|
88
|
+
await testDevice.rollerShutter.open({ channel: 0 });
|
|
94
89
|
} else {
|
|
95
|
-
await testDevice.
|
|
90
|
+
await testDevice.rollerShutter.set({ position: 100, channel: 0 });
|
|
96
91
|
}
|
|
97
92
|
|
|
98
93
|
// Wait for state changes
|
|
@@ -102,7 +97,7 @@ async function runTests(context) {
|
|
|
102
97
|
}
|
|
103
98
|
|
|
104
99
|
if (!stateOpening) {
|
|
105
|
-
testDevice.removeListener('
|
|
100
|
+
testDevice.removeListener('state', onStateChange);
|
|
106
101
|
results.push({
|
|
107
102
|
name: 'should open roller shutter',
|
|
108
103
|
passed: false,
|
|
@@ -118,7 +113,7 @@ async function runTests(context) {
|
|
|
118
113
|
}
|
|
119
114
|
|
|
120
115
|
if (!stateIdle) {
|
|
121
|
-
testDevice.removeListener('
|
|
116
|
+
testDevice.removeListener('state', onStateChange);
|
|
122
117
|
results.push({
|
|
123
118
|
name: 'should open roller shutter',
|
|
124
119
|
passed: false,
|
|
@@ -133,7 +128,7 @@ async function runTests(context) {
|
|
|
133
128
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
134
129
|
}
|
|
135
130
|
|
|
136
|
-
testDevice.removeListener('
|
|
131
|
+
testDevice.removeListener('state', onStateChange);
|
|
137
132
|
|
|
138
133
|
if (!positionOpened) {
|
|
139
134
|
results.push({
|
|
@@ -165,51 +160,46 @@ async function runTests(context) {
|
|
|
165
160
|
// Test 2: Close roller shutter
|
|
166
161
|
try {
|
|
167
162
|
// Set timers (if method exists)
|
|
168
|
-
if (typeof testDevice.
|
|
169
|
-
await testDevice.
|
|
170
|
-
|
|
171
|
-
|
|
163
|
+
if (testDevice.rollerShutter && typeof testDevice.rollerShutter.setConfig === 'function') {
|
|
164
|
+
await testDevice.rollerShutter.setConfig({
|
|
165
|
+
config: [{
|
|
166
|
+
channel: 0,
|
|
167
|
+
open_timer_duration_millis: DEFAULT_OPEN_TIMER * 1000,
|
|
168
|
+
close_timer_duration_millis: DEFAULT_CLOSE_TIMER * 1000
|
|
169
|
+
}]
|
|
172
170
|
});
|
|
173
171
|
}
|
|
174
172
|
|
|
175
173
|
// Update its status
|
|
176
|
-
await testDevice.
|
|
174
|
+
await testDevice.rollerShutter.get({ channel: 0 });
|
|
177
175
|
|
|
178
176
|
// Set up event listeners for state changes
|
|
179
177
|
let stateClosing = false;
|
|
180
178
|
let stateIdle = false;
|
|
181
179
|
let positionClosed = false;
|
|
182
180
|
|
|
183
|
-
const
|
|
184
|
-
if (
|
|
185
|
-
if (
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
} else if (state.state === 0) { // IDLE
|
|
191
|
-
stateIdle = true;
|
|
192
|
-
}
|
|
181
|
+
const onStateChange = (event) => {
|
|
182
|
+
if (event.type === 'rollerShutter' && event.channel === 0) {
|
|
183
|
+
if (event.value.state !== undefined) {
|
|
184
|
+
if (event.value.state === 2) { // CLOSING
|
|
185
|
+
stateClosing = true;
|
|
186
|
+
} else if (event.value.state === 0) { // IDLE
|
|
187
|
+
stateIdle = true;
|
|
193
188
|
}
|
|
194
189
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
if (payload.position) {
|
|
198
|
-
const position = Array.isArray(payload.position) ? payload.position[0] : payload.position;
|
|
199
|
-
if (position.channel === 0 && position.position === 0) {
|
|
200
|
-
positionClosed = true;
|
|
201
|
-
}
|
|
190
|
+
if (event.value.position !== undefined && event.value.position === 0) {
|
|
191
|
+
positionClosed = true;
|
|
202
192
|
}
|
|
203
193
|
}
|
|
204
194
|
};
|
|
205
195
|
|
|
206
|
-
testDevice.on('
|
|
196
|
+
testDevice.on('state', onStateChange);
|
|
207
197
|
|
|
208
198
|
// Trigger the closing
|
|
209
|
-
if (typeof testDevice.
|
|
210
|
-
await testDevice.
|
|
199
|
+
if (testDevice.rollerShutter && typeof testDevice.rollerShutter.close === 'function') {
|
|
200
|
+
await testDevice.rollerShutter.close({ channel: 0 });
|
|
211
201
|
} else {
|
|
212
|
-
await testDevice.
|
|
202
|
+
await testDevice.rollerShutter.set({ position: 0, channel: 0 });
|
|
213
203
|
}
|
|
214
204
|
|
|
215
205
|
// Wait for state changes
|
|
@@ -219,7 +209,7 @@ async function runTests(context) {
|
|
|
219
209
|
}
|
|
220
210
|
|
|
221
211
|
if (!stateClosing) {
|
|
222
|
-
testDevice.removeListener('
|
|
212
|
+
testDevice.removeListener('state', onStateChange);
|
|
223
213
|
results.push({
|
|
224
214
|
name: 'should close roller shutter',
|
|
225
215
|
passed: false,
|
|
@@ -235,7 +225,7 @@ async function runTests(context) {
|
|
|
235
225
|
}
|
|
236
226
|
|
|
237
227
|
if (!stateIdle) {
|
|
238
|
-
testDevice.removeListener('
|
|
228
|
+
testDevice.removeListener('state', onStateChange);
|
|
239
229
|
results.push({
|
|
240
230
|
name: 'should close roller shutter',
|
|
241
231
|
passed: false,
|
|
@@ -250,7 +240,7 @@ async function runTests(context) {
|
|
|
250
240
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
251
241
|
}
|
|
252
242
|
|
|
253
|
-
testDevice.removeListener('
|
|
243
|
+
testDevice.removeListener('state', onStateChange);
|
|
254
244
|
|
|
255
245
|
if (!positionClosed) {
|
|
256
246
|
results.push({
|
|
@@ -281,9 +271,7 @@ async function runTests(context) {
|
|
|
281
271
|
|
|
282
272
|
// Test 3: Get opening timer duration
|
|
283
273
|
try {
|
|
284
|
-
await testDevice.
|
|
285
|
-
|
|
286
|
-
const state = testDevice.getCachedRollerShutterState(0);
|
|
274
|
+
const state = await testDevice.rollerShutter.get({ channel: 0 });
|
|
287
275
|
|
|
288
276
|
if (!state) {
|
|
289
277
|
results.push({
|
|
@@ -327,9 +315,7 @@ async function runTests(context) {
|
|
|
327
315
|
|
|
328
316
|
// Test 4: Get closing timer duration
|
|
329
317
|
try {
|
|
330
|
-
await testDevice.
|
|
331
|
-
|
|
332
|
-
const state = testDevice.getCachedRollerShutterState(0);
|
|
318
|
+
const state = await testDevice.rollerShutter.get({ channel: 0 });
|
|
333
319
|
|
|
334
320
|
if (!state) {
|
|
335
321
|
results.push({
|
|
@@ -373,10 +359,8 @@ async function runTests(context) {
|
|
|
373
359
|
|
|
374
360
|
// Test 5: Set roller shutter config timers
|
|
375
361
|
try {
|
|
376
|
-
await testDevice.getRollerShutterState();
|
|
377
|
-
|
|
378
362
|
// Retrieve original values
|
|
379
|
-
const originalState = testDevice.
|
|
363
|
+
const originalState = await testDevice.rollerShutter.get({ channel: 0 });
|
|
380
364
|
|
|
381
365
|
if (!originalState) {
|
|
382
366
|
results.push({
|
|
@@ -386,12 +370,12 @@ async function runTests(context) {
|
|
|
386
370
|
error: 'Could not get original state',
|
|
387
371
|
device: deviceName
|
|
388
372
|
});
|
|
389
|
-
} else if (typeof testDevice.
|
|
373
|
+
} else if (!testDevice.rollerShutter || typeof testDevice.rollerShutter.setConfig !== 'function') {
|
|
390
374
|
results.push({
|
|
391
375
|
name: 'should set roller shutter config timers',
|
|
392
376
|
passed: false,
|
|
393
377
|
skipped: true,
|
|
394
|
-
error: 'Device does not support
|
|
378
|
+
error: 'Device does not support setConfig',
|
|
395
379
|
device: deviceName
|
|
396
380
|
});
|
|
397
381
|
} else {
|
|
@@ -402,16 +386,17 @@ async function runTests(context) {
|
|
|
402
386
|
const openTimer = Math.floor(Math.random() * (120 - 10 + 1)) + 10; // 10-120 seconds
|
|
403
387
|
const closeTimer = Math.floor(Math.random() * (120 - 10 + 1)) + 10; // 10-120 seconds
|
|
404
388
|
|
|
405
|
-
await testDevice.
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
389
|
+
await testDevice.rollerShutter.setConfig({
|
|
390
|
+
config: [{
|
|
391
|
+
channel: 0,
|
|
392
|
+
open_timer_duration_millis: openTimer * 1000,
|
|
393
|
+
close_timer_duration_millis: closeTimer * 1000
|
|
394
|
+
}]
|
|
409
395
|
});
|
|
410
396
|
|
|
411
397
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
412
398
|
|
|
413
|
-
await testDevice.
|
|
414
|
-
const newState = testDevice.getCachedRollerShutterState(0);
|
|
399
|
+
const newState = await testDevice.rollerShutter.get({ channel: 0 });
|
|
415
400
|
|
|
416
401
|
if (!newState) {
|
|
417
402
|
results.push({
|
|
@@ -432,10 +417,12 @@ async function runTests(context) {
|
|
|
432
417
|
});
|
|
433
418
|
} else {
|
|
434
419
|
// Restore original values
|
|
435
|
-
await testDevice.
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
420
|
+
await testDevice.rollerShutter.setConfig({
|
|
421
|
+
config: [{
|
|
422
|
+
channel: 0,
|
|
423
|
+
open_timer_duration_millis: originalOpenTimer,
|
|
424
|
+
close_timer_duration_millis: originalCloseTimer
|
|
425
|
+
}]
|
|
439
426
|
});
|
|
440
427
|
|
|
441
428
|
results.push({
|
|
@@ -459,16 +446,17 @@ async function runTests(context) {
|
|
|
459
446
|
|
|
460
447
|
// Test 6: Get roller shutter config
|
|
461
448
|
try {
|
|
462
|
-
if (typeof testDevice.
|
|
449
|
+
if (!testDevice.rollerShutter || typeof testDevice.rollerShutter.getConfig !== 'function') {
|
|
463
450
|
results.push({
|
|
464
451
|
name: 'should get roller shutter config',
|
|
465
452
|
passed: false,
|
|
466
453
|
skipped: true,
|
|
467
|
-
error: 'Device does not support
|
|
454
|
+
error: 'Device does not support getConfig',
|
|
468
455
|
device: deviceName
|
|
469
456
|
});
|
|
470
457
|
} else {
|
|
471
|
-
const
|
|
458
|
+
const response = await testDevice.rollerShutter.getConfig();
|
|
459
|
+
const config = response?.config;
|
|
472
460
|
|
|
473
461
|
if (!config) {
|
|
474
462
|
results.push({
|
|
@@ -501,16 +489,16 @@ async function runTests(context) {
|
|
|
501
489
|
|
|
502
490
|
// Test 7: Get roller shutter position
|
|
503
491
|
try {
|
|
504
|
-
if (typeof testDevice.
|
|
492
|
+
if (!testDevice.rollerShutter || typeof testDevice.rollerShutter.getPosition !== 'function') {
|
|
505
493
|
results.push({
|
|
506
494
|
name: 'should get roller shutter position',
|
|
507
495
|
passed: false,
|
|
508
496
|
skipped: true,
|
|
509
|
-
error: 'Device does not support
|
|
497
|
+
error: 'Device does not support getPosition',
|
|
510
498
|
device: deviceName
|
|
511
499
|
});
|
|
512
500
|
} else {
|
|
513
|
-
const response = await testDevice.
|
|
501
|
+
const response = await testDevice.rollerShutter.getPosition({ channel: 0 });
|
|
514
502
|
|
|
515
503
|
if (!response) {
|
|
516
504
|
results.push({
|
|
@@ -553,7 +541,7 @@ async function runTests(context) {
|
|
|
553
541
|
});
|
|
554
542
|
} else {
|
|
555
543
|
// Get current position first
|
|
556
|
-
await testDevice.
|
|
544
|
+
await testDevice.rollerShutter.getPosition({ channel: 0 });
|
|
557
545
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
558
546
|
|
|
559
547
|
// Note: We don't actually change the position to avoid disrupting the device
|
|
@@ -579,16 +567,16 @@ async function runTests(context) {
|
|
|
579
567
|
|
|
580
568
|
// Test 9: Get roller shutter adjust
|
|
581
569
|
try {
|
|
582
|
-
if (typeof testDevice.
|
|
570
|
+
if (!testDevice.rollerShutter || typeof testDevice.rollerShutter.getAdjust !== 'function') {
|
|
583
571
|
results.push({
|
|
584
572
|
name: 'should get roller shutter adjust',
|
|
585
573
|
passed: false,
|
|
586
574
|
skipped: true,
|
|
587
|
-
error: 'Device does not support
|
|
575
|
+
error: 'Device does not support getAdjust',
|
|
588
576
|
device: deviceName
|
|
589
577
|
});
|
|
590
578
|
} else {
|
|
591
|
-
const response = await testDevice.
|
|
579
|
+
const response = await testDevice.rollerShutter.getAdjust({ channel: 0 });
|
|
592
580
|
|
|
593
581
|
if (!response) {
|
|
594
582
|
results.push({
|
package/cli/tests/test-screen.js
CHANGED
|
@@ -53,7 +53,11 @@ async function runTests(context) {
|
|
|
53
53
|
// Try different capacity values (1, 2, 3 are common)
|
|
54
54
|
for (const capacity of [1, 2, 3]) {
|
|
55
55
|
try {
|
|
56
|
-
|
|
56
|
+
if (!testDevice.sensorHistory) {
|
|
57
|
+
lastError = 'Device does not support sensor history feature';
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const response = await testDevice.sensorHistory.get({ channel: 0, capacity });
|
|
57
61
|
|
|
58
62
|
if (!response) {
|
|
59
63
|
lastError = `getSensorHistory returned null or undefined for capacity ${capacity}`;
|
|
@@ -107,7 +111,7 @@ async function runTests(context) {
|
|
|
107
111
|
try {
|
|
108
112
|
// Note: We don't actually delete history to avoid data loss
|
|
109
113
|
// We just verify the method exists and can be called
|
|
110
|
-
if (typeof testDevice.
|
|
114
|
+
if (testDevice.sensorHistory && typeof testDevice.sensorHistory.delete === 'function') {
|
|
111
115
|
results.push({
|
|
112
116
|
name: 'should delete sensor history',
|
|
113
117
|
passed: true,
|
|
@@ -44,7 +44,17 @@ async function runTests(context) {
|
|
|
44
44
|
|
|
45
45
|
// Test 1: Get smoke config
|
|
46
46
|
try {
|
|
47
|
-
|
|
47
|
+
if (!testDevice.smokeConfig) {
|
|
48
|
+
results.push({
|
|
49
|
+
name: 'should get smoke config',
|
|
50
|
+
passed: false,
|
|
51
|
+
skipped: true,
|
|
52
|
+
error: 'Device does not support smoke config feature',
|
|
53
|
+
device: deviceName
|
|
54
|
+
});
|
|
55
|
+
return results;
|
|
56
|
+
}
|
|
57
|
+
const response = await testDevice.smokeConfig.get({ channel: 0 });
|
|
48
58
|
|
|
49
59
|
if (!response) {
|
|
50
60
|
results.push({
|
|
@@ -84,8 +94,18 @@ async function runTests(context) {
|
|
|
84
94
|
|
|
85
95
|
// Test 2: Control smoke config
|
|
86
96
|
try {
|
|
97
|
+
if (!testDevice.smokeConfig) {
|
|
98
|
+
results.push({
|
|
99
|
+
name: 'should control smoke config',
|
|
100
|
+
passed: false,
|
|
101
|
+
skipped: true,
|
|
102
|
+
error: 'Device does not support smoke config feature',
|
|
103
|
+
device: deviceName
|
|
104
|
+
});
|
|
105
|
+
return results;
|
|
106
|
+
}
|
|
87
107
|
// Get current config first
|
|
88
|
-
const currentResponse = await testDevice.
|
|
108
|
+
const currentResponse = await testDevice.smokeConfig.get({ channel: 0 });
|
|
89
109
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
90
110
|
|
|
91
111
|
if (!currentResponse || !Array.isArray(currentResponse.config)) {
|
|
@@ -96,12 +116,12 @@ async function runTests(context) {
|
|
|
96
116
|
error: 'Could not get current smoke config or config is not an array',
|
|
97
117
|
device: deviceName
|
|
98
118
|
});
|
|
99
|
-
} else if (typeof testDevice.
|
|
119
|
+
} else if (typeof testDevice.smokeConfig.set !== 'function') {
|
|
100
120
|
results.push({
|
|
101
121
|
name: 'should control smoke config',
|
|
102
122
|
passed: false,
|
|
103
123
|
skipped: true,
|
|
104
|
-
error: 'Device does not support
|
|
124
|
+
error: 'Device does not support set',
|
|
105
125
|
device: deviceName
|
|
106
126
|
});
|
|
107
127
|
} else {
|
package/cli/tests/test-spray.js
CHANGED
|
@@ -29,7 +29,7 @@ async function runTests(context) {
|
|
|
29
29
|
// Wait for devices to be connected
|
|
30
30
|
for (const device of testDevices) {
|
|
31
31
|
await waitForDeviceConnection(device, timeout);
|
|
32
|
-
await device.
|
|
32
|
+
await device.spray.get({ channel: 0 });
|
|
33
33
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -50,10 +50,10 @@ async function runTests(context) {
|
|
|
50
50
|
// Test: Set different spray modes
|
|
51
51
|
try {
|
|
52
52
|
// Set CONTINUOUS mode
|
|
53
|
-
await testDevice.
|
|
53
|
+
await testDevice.spray.set({ channel: 0, mode: SprayMode.CONTINUOUS });
|
|
54
54
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
55
|
-
|
|
56
|
-
const mode1 = testDevice.
|
|
55
|
+
await testDevice.spray.get({ channel: 0 });
|
|
56
|
+
const mode1 = testDevice.spray.getMode({ channel: 0 });
|
|
57
57
|
if (mode1 !== SprayMode.CONTINUOUS) {
|
|
58
58
|
results.push({
|
|
59
59
|
name: 'should set different spray modes',
|
|
@@ -66,10 +66,10 @@ async function runTests(context) {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
// Set INTERMITTENT mode
|
|
69
|
-
await testDevice.
|
|
69
|
+
await testDevice.spray.set({ channel: 0, mode: SprayMode.INTERMITTENT });
|
|
70
70
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
71
|
-
|
|
72
|
-
const mode2 = testDevice.
|
|
71
|
+
await testDevice.spray.get({ channel: 0 });
|
|
72
|
+
const mode2 = testDevice.spray.getMode({ channel: 0 });
|
|
73
73
|
if (mode2 !== SprayMode.INTERMITTENT) {
|
|
74
74
|
results.push({
|
|
75
75
|
name: 'should set different spray modes',
|
|
@@ -82,10 +82,10 @@ async function runTests(context) {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
// Set OFF mode
|
|
85
|
-
await testDevice.
|
|
85
|
+
await testDevice.spray.set({ channel: 0, mode: SprayMode.OFF });
|
|
86
86
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
87
|
-
|
|
88
|
-
const mode3 = testDevice.
|
|
87
|
+
await testDevice.spray.get({ channel: 0 });
|
|
88
|
+
const mode3 = testDevice.spray.getMode({ channel: 0 });
|
|
89
89
|
if (mode3 !== SprayMode.OFF) {
|
|
90
90
|
results.push({
|
|
91
91
|
name: 'should set different spray modes',
|
|
@@ -98,7 +98,7 @@ async function runTests(context) {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
// Update state
|
|
101
|
-
await testDevice.
|
|
101
|
+
await testDevice.spray.get({ channel: 0 });
|
|
102
102
|
|
|
103
103
|
results.push({
|
|
104
104
|
name: 'should set different spray modes',
|