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.
Files changed (42) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +24 -5
  3. package/cli/commands/control/execute.js +36 -6
  4. package/cli/commands/control/params/index.js +16 -12
  5. package/cli/commands/control/params/light.js +55 -25
  6. package/cli/commands/control/params/thermostat.js +24 -22
  7. package/cli/commands/control/params/timer.js +38 -43
  8. package/cli/commands/control/params/trigger.js +43 -40
  9. package/cli/commands/info.js +218 -17
  10. package/cli/commands/sniffer/sniffer-menu.js +2 -2
  11. package/cli/commands/status/device-status.js +418 -1292
  12. package/cli/commands/status/hub-status.js +14 -6
  13. package/cli/control-registry.js +211 -406
  14. package/cli/meross-cli.js +1 -1
  15. package/cli/tests/README.md +2 -0
  16. package/cli/tests/test-alarm.js +22 -2
  17. package/cli/tests/test-child-lock.js +40 -10
  18. package/cli/tests/test-config.js +22 -2
  19. package/cli/tests/test-control.js +8 -8
  20. package/cli/tests/test-diffuser.js +7 -7
  21. package/cli/tests/test-dnd.js +87 -66
  22. package/cli/tests/test-electricity.js +37 -33
  23. package/cli/tests/test-encryption.js +13 -13
  24. package/cli/tests/test-garage.js +12 -14
  25. package/cli/tests/test-helper.js +1 -1
  26. package/cli/tests/test-hub-sensors.js +3 -3
  27. package/cli/tests/test-light.js +497 -105
  28. package/cli/tests/test-presence.js +10 -55
  29. package/cli/tests/test-registry.js +7 -1
  30. package/cli/tests/test-roller-shutter.js +78 -90
  31. package/cli/tests/test-screen.js +1 -1
  32. package/cli/tests/test-sensor-history.js +6 -2
  33. package/cli/tests/test-smoke-config.js +24 -4
  34. package/cli/tests/test-spray.js +11 -11
  35. package/cli/tests/test-system.js +375 -0
  36. package/cli/tests/test-temp-unit.js +22 -2
  37. package/cli/tests/test-template.js +61 -73
  38. package/cli/tests/test-thermostat.js +126 -89
  39. package/cli/tests/test-timer.js +9 -52
  40. package/cli/tests/test-toggle.js +49 -173
  41. package/cli/tests/test-trigger.js +8 -51
  42. 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.getLatestSensorReadings === 'function') {
66
- const readings = await testDevice.getLatestSensorReadings(['presence', 'light'], timeout);
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.getPresenceConfig === 'function') {
340
- const config = await testDevice.getPresenceConfig(0, timeout);
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.getRollerShutterState();
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.getRollerShutterState();
51
+ await testDevice.rollerShutter.get({ channel: 0 });
52
52
 
53
53
  // Set timers (if method exists)
54
- if (typeof testDevice.setRollerShutterConfig === 'function') {
55
- await testDevice.setRollerShutterConfig({
56
- openTimerSeconds: DEFAULT_OPEN_TIMER,
57
- closeTimerSeconds: DEFAULT_CLOSE_TIMER
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 onData = (namespace, payload) => {
67
- if (namespace === 'Appliance.RollerShutter.State') {
68
- if (payload.state) {
69
- const state = Array.isArray(payload.state) ? payload.state[0] : payload.state;
70
- if (state.channel === 0) {
71
- if (state.state === 1) { // OPENING
72
- stateOpening = true;
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
- if (namespace === 'Appliance.RollerShutter.Position') {
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('data', onData);
84
+ testDevice.on('state', onStateChange);
90
85
 
91
86
  // Trigger the opening
92
- if (typeof testDevice.openRollerShutter === 'function') {
93
- await testDevice.openRollerShutter({ channel: 0 });
87
+ if (testDevice.rollerShutter && typeof testDevice.rollerShutter.open === 'function') {
88
+ await testDevice.rollerShutter.open({ channel: 0 });
94
89
  } else {
95
- await testDevice.setRollerShutterPosition({ position: 100, channel: 0 });
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('data', onData);
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('data', onData);
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('data', onData);
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.setRollerShutterConfig === 'function') {
169
- await testDevice.setRollerShutterConfig({
170
- openTimerSeconds: DEFAULT_OPEN_TIMER,
171
- closeTimerSeconds: DEFAULT_CLOSE_TIMER
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.getRollerShutterState();
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 onData = (namespace, payload) => {
184
- if (namespace === 'Appliance.RollerShutter.State') {
185
- if (payload.state) {
186
- const state = Array.isArray(payload.state) ? payload.state[0] : payload.state;
187
- if (state.channel === 0) {
188
- if (state.state === 2) { // CLOSING
189
- stateClosing = true;
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
- if (namespace === 'Appliance.RollerShutter.Position') {
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('data', onData);
196
+ testDevice.on('state', onStateChange);
207
197
 
208
198
  // Trigger the closing
209
- if (typeof testDevice.closeRollerShutter === 'function') {
210
- await testDevice.closeRollerShutter({ channel: 0 });
199
+ if (testDevice.rollerShutter && typeof testDevice.rollerShutter.close === 'function') {
200
+ await testDevice.rollerShutter.close({ channel: 0 });
211
201
  } else {
212
- await testDevice.setRollerShutterPosition({ position: 0, channel: 0 });
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('data', onData);
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('data', onData);
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('data', onData);
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.getRollerShutterState();
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.getRollerShutterState();
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.getCachedRollerShutterState(0);
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.setRollerShutterConfig !== 'function') {
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 setRollerShutterConfig',
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.setRollerShutterConfig({
406
- openTimerSeconds: openTimer,
407
- closeTimerSeconds: closeTimer,
408
- channel: 0
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.getRollerShutterState();
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.setRollerShutterConfig({
436
- openTimerSeconds: Math.floor(originalOpenTimer / 1000),
437
- closeTimerSeconds: Math.floor(originalCloseTimer / 1000),
438
- channel: 0
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.getRollerShutterConfig !== 'function') {
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 getRollerShutterConfig',
454
+ error: 'Device does not support getConfig',
468
455
  device: deviceName
469
456
  });
470
457
  } else {
471
- const config = await testDevice.getRollerShutterConfig();
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.getRollerShutterPosition !== 'function') {
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 getRollerShutterPosition',
497
+ error: 'Device does not support getPosition',
510
498
  device: deviceName
511
499
  });
512
500
  } else {
513
- const response = await testDevice.getRollerShutterPosition({ channel: 0 });
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.getRollerShutterPosition({ channel: 0 });
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.getRollerShutterAdjust !== 'function') {
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 getRollerShutterAdjust',
575
+ error: 'Device does not support getAdjust',
588
576
  device: deviceName
589
577
  });
590
578
  } else {
591
- const response = await testDevice.getRollerShutterAdjust({ channel: 0 });
579
+ const response = await testDevice.rollerShutter.getAdjust({ channel: 0 });
592
580
 
593
581
  if (!response) {
594
582
  results.push({
@@ -47,7 +47,7 @@ async function runTests(context) {
47
47
 
48
48
  // Test 1: Get screen brightness
49
49
  try {
50
- const response = await testDevice.getScreenBrightness(0);
50
+ const response = await testDevice.screen.get({ channel: 0 });
51
51
 
52
52
  if (!response) {
53
53
  results.push({
@@ -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
- const response = await testDevice.getSensorHistory({ channel: 0, capacity });
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.deleteSensorHistory === 'function') {
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
- const response = await testDevice.getSmokeConfig(0);
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.getSmokeConfig(0);
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.setSmokeConfig !== 'function') {
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 setSmokeConfig',
124
+ error: 'Device does not support set',
105
125
  device: deviceName
106
126
  });
107
127
  } else {
@@ -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.getSprayState();
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.setSpray(0, SprayMode.CONTINUOUS);
53
+ await testDevice.spray.set({ channel: 0, mode: SprayMode.CONTINUOUS });
54
54
  await new Promise(resolve => setTimeout(resolve, 1000));
55
-
56
- const mode1 = testDevice.getCurrentSprayMode(0);
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.setSpray(0, SprayMode.INTERMITTENT);
69
+ await testDevice.spray.set({ channel: 0, mode: SprayMode.INTERMITTENT });
70
70
  await new Promise(resolve => setTimeout(resolve, 1000));
71
-
72
- const mode2 = testDevice.getCurrentSprayMode(0);
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.setSpray(0, SprayMode.OFF);
85
+ await testDevice.spray.set({ channel: 0, mode: SprayMode.OFF });
86
86
  await new Promise(resolve => setTimeout(resolve, 1000));
87
-
88
- const mode3 = testDevice.getCurrentSprayMode(0);
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.getSprayState();
101
+ await testDevice.spray.get({ channel: 0 });
102
102
 
103
103
  results.push({
104
104
  name: 'should set different spray modes',