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.
Files changed (48) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +46 -5
  3. package/cli/commands/control/execute.js +50 -7
  4. package/cli/commands/control/menu.js +3 -5
  5. package/cli/commands/control/params/index.js +16 -12
  6. package/cli/commands/control/params/light.js +55 -25
  7. package/cli/commands/control/params/thermostat.js +24 -22
  8. package/cli/commands/control/params/timer.js +18 -15
  9. package/cli/commands/control/params/trigger.js +24 -13
  10. package/cli/commands/info.js +39 -15
  11. package/cli/commands/sniffer/sniffer-menu.js +2 -2
  12. package/cli/commands/status/device-status.js +418 -1292
  13. package/cli/commands/status/hub-status.js +14 -6
  14. package/cli/control-registry.js +211 -406
  15. package/cli/helpers/client.js +16 -10
  16. package/cli/helpers/meross.js +18 -14
  17. package/cli/menu/main.js +170 -13
  18. package/cli/menu/settings.js +2 -2
  19. package/cli/meross-cli.js +13 -47
  20. package/cli/tests/README.md +2 -0
  21. package/cli/tests/test-alarm.js +22 -2
  22. package/cli/tests/test-child-lock.js +40 -10
  23. package/cli/tests/test-config.js +22 -2
  24. package/cli/tests/test-control.js +8 -8
  25. package/cli/tests/test-diffuser.js +7 -7
  26. package/cli/tests/test-dnd.js +87 -66
  27. package/cli/tests/test-electricity.js +37 -33
  28. package/cli/tests/test-encryption.js +13 -13
  29. package/cli/tests/test-garage.js +12 -14
  30. package/cli/tests/test-helper.js +1 -1
  31. package/cli/tests/test-hub-sensors.js +3 -3
  32. package/cli/tests/test-light.js +497 -105
  33. package/cli/tests/test-presence.js +10 -55
  34. package/cli/tests/test-registry.js +7 -1
  35. package/cli/tests/test-roller-shutter.js +78 -90
  36. package/cli/tests/test-screen.js +1 -1
  37. package/cli/tests/test-sensor-history.js +6 -2
  38. package/cli/tests/test-smoke-config.js +24 -4
  39. package/cli/tests/test-spray.js +11 -11
  40. package/cli/tests/test-system.js +375 -0
  41. package/cli/tests/test-temp-unit.js +22 -2
  42. package/cli/tests/test-template.js +61 -73
  43. package/cli/tests/test-thermostat.js +126 -89
  44. package/cli/tests/test-timer.js +8 -51
  45. package/cli/tests/test-toggle.js +49 -173
  46. package/cli/tests/test-trigger.js +7 -50
  47. package/cli/utils/error-handler.js +257 -0
  48. package/package.json +2 -2
@@ -47,7 +47,17 @@ async function runTests(context) {
47
47
 
48
48
  // Test 1: Get config over temp
49
49
  try {
50
- const response = await testDevice.getConfigOverTemp();
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.getConfigOverTemp();
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.acknowledgeControlOverTemp !== 'function') {
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 acknowledgeControlOverTemp',
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.getDiffuserLightState();
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.getDiffuserSprayState();
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.getDiffuserLightState();
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.getDiffuserLightState();
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.getDiffuserLightState();
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.getDiffuserLightState();
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.getDiffuserSprayState();
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));
@@ -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
- typeof d.getDNDMode === 'function' &&
31
- typeof d.setDNDMode === 'function';
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
- // Get current DND mode
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: false,
67
- error: 'getDNDMode returned null or undefined',
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
- // Toggle DND mode
80
- const newMode = initialMode === DNDMode.DND_ENABLED ? DNDMode.DND_DISABLED : DNDMode.DND_ENABLED;
81
- await testDevice.setDNDMode({ mode: newMode });
69
+ // Get current DND mode
70
+ const initialMode = await testDevice.dnd.get();
82
71
 
83
- // Wait for the change to take effect
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: `DND mode did not change. Expected ${newMode}, got ${updatedMode}`,
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
- // Restore original mode
99
- await testDevice.setDNDMode({ mode: initialMode });
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
- const restoredMode = await testDevice.getDNDMode();
96
+ // Verify the change
97
+ const updatedMode = await testDevice.dnd.get();
103
98
 
104
- if (restoredMode !== initialMode) {
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: `Failed to restore DND mode. Expected ${initialMode}, got ${restoredMode}`,
104
+ error: `DND mode did not change. Expected ${newMode}, got ${updatedMode}`,
110
105
  device: deviceName
111
106
  });
112
107
  } else {
113
- results.push({
114
- name: 'should get and set DND mode',
115
- passed: true,
116
- skipped: false,
117
- error: null,
118
- device: deviceName
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
- // Get current mode
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: false,
151
- error: `Boolean set failed. Expected ${expectedMode}, got ${updatedMode}`,
150
+ skipped: true,
151
+ error: 'Device does not support DND feature',
152
152
  device: deviceName
153
153
  });
154
154
  } else {
155
- // Restore original mode
156
- await testDevice.setDNDMode({ mode: initialBoolean });
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
- results.push({
160
- name: 'should accept boolean values for DND mode',
161
- passed: true,
162
- skipped: false,
163
- error: null,
164
- device: deviceName
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.getRawDNDMode !== 'function') {
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 getRawDNDMode',
205
+ error: 'Device does not support dnd.getRaw',
185
206
  device: deviceName
186
207
  });
187
208
  } else {
188
- const rawMode = await testDevice.getRawDNDMode();
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.getDNDMode();
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 ConsumptionX first, then Consumption, then Electricity)
26
- testDevices = await findDevicesByAbility(manager, 'Appliance.Control.ConsumptionX', OnlineStatus.ONLINE);
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
- // Try to get electricity data
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: false,
73
- error: 'Metrics is not an object or is null',
64
+ skipped: true,
65
+ error: 'Device does not support electricity feature',
74
66
  device: deviceName
75
67
  });
76
68
  } else {
77
- results.push({
78
- name: 'should get instant electricity metrics',
79
- passed: true,
80
- skipped: false,
81
- error: null,
82
- device: deviceName,
83
- details: { metrics: metrics }
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 (typeof testDevice.getPowerConsumptionX !== 'function') {
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.getPowerConsumptionX();
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 (typeof testDevice.getConsumptionConfig !== 'function') {
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 getConsumptionConfig',
172
+ error: 'Device does not support consumption config',
169
173
  device: deviceName
170
174
  });
171
175
  } else {
172
- const response = await testDevice.getConsumptionConfig();
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: 'getConsumptionConfig returned null or undefined',
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 methods',
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({