meross-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/LICENSE +21 -0
- package/README.md +110 -0
- package/cli/commands/control/execute.js +23 -0
- package/cli/commands/control/index.js +12 -0
- package/cli/commands/control/menu.js +193 -0
- package/cli/commands/control/params/generic.js +229 -0
- package/cli/commands/control/params/index.js +56 -0
- package/cli/commands/control/params/light.js +188 -0
- package/cli/commands/control/params/thermostat.js +166 -0
- package/cli/commands/control/params/timer.js +242 -0
- package/cli/commands/control/params/trigger.js +206 -0
- package/cli/commands/dump.js +35 -0
- package/cli/commands/index.js +34 -0
- package/cli/commands/info.js +221 -0
- package/cli/commands/list.js +112 -0
- package/cli/commands/mqtt.js +187 -0
- package/cli/commands/sniffer/device-sniffer.js +217 -0
- package/cli/commands/sniffer/fake-app.js +233 -0
- package/cli/commands/sniffer/index.js +7 -0
- package/cli/commands/sniffer/message-queue.js +65 -0
- package/cli/commands/sniffer/sniffer-menu.js +676 -0
- package/cli/commands/stats.js +90 -0
- package/cli/commands/status/device-status.js +1403 -0
- package/cli/commands/status/hub-status.js +72 -0
- package/cli/commands/status/index.js +50 -0
- package/cli/commands/status/subdevices/hub-smoke-detector.js +82 -0
- package/cli/commands/status/subdevices/hub-temp-hum-sensor.js +43 -0
- package/cli/commands/status/subdevices/hub-thermostat-valve.js +83 -0
- package/cli/commands/status/subdevices/hub-water-leak-sensor.js +27 -0
- package/cli/commands/status/subdevices/index.js +23 -0
- package/cli/commands/test/index.js +185 -0
- package/cli/config/users.js +108 -0
- package/cli/control-registry.js +875 -0
- package/cli/helpers/client.js +89 -0
- package/cli/helpers/meross.js +106 -0
- package/cli/menu/index.js +10 -0
- package/cli/menu/main.js +648 -0
- package/cli/menu/settings.js +789 -0
- package/cli/meross-cli.js +547 -0
- package/cli/tests/README.md +365 -0
- package/cli/tests/test-alarm.js +144 -0
- package/cli/tests/test-child-lock.js +248 -0
- package/cli/tests/test-config.js +133 -0
- package/cli/tests/test-control.js +189 -0
- package/cli/tests/test-diffuser.js +505 -0
- package/cli/tests/test-dnd.js +246 -0
- package/cli/tests/test-electricity.js +209 -0
- package/cli/tests/test-encryption.js +281 -0
- package/cli/tests/test-garage.js +259 -0
- package/cli/tests/test-helper.js +313 -0
- package/cli/tests/test-hub-mts100.js +355 -0
- package/cli/tests/test-hub-sensors.js +489 -0
- package/cli/tests/test-light.js +253 -0
- package/cli/tests/test-presence.js +497 -0
- package/cli/tests/test-registry.js +419 -0
- package/cli/tests/test-roller-shutter.js +628 -0
- package/cli/tests/test-runner.js +415 -0
- package/cli/tests/test-runtime.js +234 -0
- package/cli/tests/test-screen.js +133 -0
- package/cli/tests/test-sensor-history.js +146 -0
- package/cli/tests/test-smoke-config.js +138 -0
- package/cli/tests/test-spray.js +131 -0
- package/cli/tests/test-temp-unit.js +133 -0
- package/cli/tests/test-template.js +238 -0
- package/cli/tests/test-thermostat.js +919 -0
- package/cli/tests/test-timer.js +372 -0
- package/cli/tests/test-toggle.js +342 -0
- package/cli/tests/test-trigger.js +279 -0
- package/cli/utils/display.js +86 -0
- package/cli/utils/terminal.js +137 -0
- package/package.json +53 -0
|
@@ -0,0 +1,628 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Roller Shutter Device Tests
|
|
5
|
+
* Tests open/close control, position, timers, and configuration for roller shutters
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { findDevicesByAbility, waitForDeviceConnection, getDeviceName, OnlineStatus } = require('./test-helper');
|
|
9
|
+
|
|
10
|
+
const DEFAULT_OPEN_TIMER = 15;
|
|
11
|
+
const DEFAULT_CLOSE_TIMER = 15;
|
|
12
|
+
|
|
13
|
+
const metadata = {
|
|
14
|
+
name: 'roller-shutter',
|
|
15
|
+
description: 'Tests open/close control, position, timers, and configuration for roller shutters',
|
|
16
|
+
requiredAbilities: ['Appliance.RollerShutter.State'],
|
|
17
|
+
minDevices: 1
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
async function runTests(context) {
|
|
21
|
+
const { manager, devices, options = {} } = context;
|
|
22
|
+
const timeout = options.timeout || 120000; // Roller shutters take time
|
|
23
|
+
const results = [];
|
|
24
|
+
|
|
25
|
+
// If no devices provided, discover them
|
|
26
|
+
let testDevices = devices || [];
|
|
27
|
+
if (testDevices.length === 0) {
|
|
28
|
+
testDevices = await findDevicesByAbility(manager, 'Appliance.RollerShutter.State', OnlineStatus.ONLINE);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (testDevices.length === 0) {
|
|
32
|
+
results.push({
|
|
33
|
+
name: 'should open roller shutter',
|
|
34
|
+
passed: false,
|
|
35
|
+
skipped: true,
|
|
36
|
+
error: 'No RollerShutter device has been found to run this test on',
|
|
37
|
+
device: null
|
|
38
|
+
});
|
|
39
|
+
return results;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const testDevice = testDevices[0];
|
|
43
|
+
const deviceName = getDeviceName(testDevice);
|
|
44
|
+
|
|
45
|
+
await waitForDeviceConnection(testDevice, timeout);
|
|
46
|
+
await testDevice.getRollerShutterState();
|
|
47
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
48
|
+
|
|
49
|
+
// Test 1: Open roller shutter
|
|
50
|
+
try {
|
|
51
|
+
await testDevice.getRollerShutterState();
|
|
52
|
+
|
|
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
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Set up event listeners for state changes
|
|
62
|
+
let stateOpening = false;
|
|
63
|
+
let stateIdle = false;
|
|
64
|
+
let positionOpened = false;
|
|
65
|
+
|
|
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
|
+
}
|
|
76
|
+
}
|
|
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
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
testDevice.on('data', onData);
|
|
90
|
+
|
|
91
|
+
// Trigger the opening
|
|
92
|
+
if (typeof testDevice.openRollerShutter === 'function') {
|
|
93
|
+
await testDevice.openRollerShutter({ channel: 0 });
|
|
94
|
+
} else {
|
|
95
|
+
await testDevice.setRollerShutterPosition({ position: 100, channel: 0 });
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Wait for state changes
|
|
99
|
+
const startTime = Date.now();
|
|
100
|
+
while (!stateOpening && Date.now() - startTime < 30000) {
|
|
101
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!stateOpening) {
|
|
105
|
+
testDevice.removeListener('data', onData);
|
|
106
|
+
results.push({
|
|
107
|
+
name: 'should open roller shutter',
|
|
108
|
+
passed: false,
|
|
109
|
+
skipped: false,
|
|
110
|
+
error: 'Did not receive OPENING state within 30 seconds',
|
|
111
|
+
device: deviceName
|
|
112
|
+
});
|
|
113
|
+
return results;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
while (!stateIdle && Date.now() - startTime < 90000) {
|
|
117
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (!stateIdle) {
|
|
121
|
+
testDevice.removeListener('data', onData);
|
|
122
|
+
results.push({
|
|
123
|
+
name: 'should open roller shutter',
|
|
124
|
+
passed: false,
|
|
125
|
+
skipped: false,
|
|
126
|
+
error: 'Did not receive IDLE state within 90 seconds',
|
|
127
|
+
device: deviceName
|
|
128
|
+
});
|
|
129
|
+
return results;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
while (!positionOpened && Date.now() - startTime < 120000) {
|
|
133
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
testDevice.removeListener('data', onData);
|
|
137
|
+
|
|
138
|
+
if (!positionOpened) {
|
|
139
|
+
results.push({
|
|
140
|
+
name: 'should open roller shutter',
|
|
141
|
+
passed: false,
|
|
142
|
+
skipped: false,
|
|
143
|
+
error: 'Did not receive position 100 within 120 seconds',
|
|
144
|
+
device: deviceName
|
|
145
|
+
});
|
|
146
|
+
} else {
|
|
147
|
+
results.push({
|
|
148
|
+
name: 'should open roller shutter',
|
|
149
|
+
passed: true,
|
|
150
|
+
skipped: false,
|
|
151
|
+
error: null,
|
|
152
|
+
device: deviceName
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
} catch (error) {
|
|
156
|
+
results.push({
|
|
157
|
+
name: 'should open roller shutter',
|
|
158
|
+
passed: false,
|
|
159
|
+
skipped: false,
|
|
160
|
+
error: error.message,
|
|
161
|
+
device: deviceName
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Test 2: Close roller shutter
|
|
166
|
+
try {
|
|
167
|
+
// 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
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Update its status
|
|
176
|
+
await testDevice.getRollerShutterState();
|
|
177
|
+
|
|
178
|
+
// Set up event listeners for state changes
|
|
179
|
+
let stateClosing = false;
|
|
180
|
+
let stateIdle = false;
|
|
181
|
+
let positionClosed = false;
|
|
182
|
+
|
|
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
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
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
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
testDevice.on('data', onData);
|
|
207
|
+
|
|
208
|
+
// Trigger the closing
|
|
209
|
+
if (typeof testDevice.closeRollerShutter === 'function') {
|
|
210
|
+
await testDevice.closeRollerShutter({ channel: 0 });
|
|
211
|
+
} else {
|
|
212
|
+
await testDevice.setRollerShutterPosition({ position: 0, channel: 0 });
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Wait for state changes
|
|
216
|
+
const startTime = Date.now();
|
|
217
|
+
while (!stateClosing && Date.now() - startTime < 30000) {
|
|
218
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (!stateClosing) {
|
|
222
|
+
testDevice.removeListener('data', onData);
|
|
223
|
+
results.push({
|
|
224
|
+
name: 'should close roller shutter',
|
|
225
|
+
passed: false,
|
|
226
|
+
skipped: false,
|
|
227
|
+
error: 'Did not receive CLOSING state within 30 seconds',
|
|
228
|
+
device: deviceName
|
|
229
|
+
});
|
|
230
|
+
return results;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
while (!stateIdle && Date.now() - startTime < 90000) {
|
|
234
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (!stateIdle) {
|
|
238
|
+
testDevice.removeListener('data', onData);
|
|
239
|
+
results.push({
|
|
240
|
+
name: 'should close roller shutter',
|
|
241
|
+
passed: false,
|
|
242
|
+
skipped: false,
|
|
243
|
+
error: 'Did not receive IDLE state within 90 seconds',
|
|
244
|
+
device: deviceName
|
|
245
|
+
});
|
|
246
|
+
return results;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
while (!positionClosed && Date.now() - startTime < 120000) {
|
|
250
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
testDevice.removeListener('data', onData);
|
|
254
|
+
|
|
255
|
+
if (!positionClosed) {
|
|
256
|
+
results.push({
|
|
257
|
+
name: 'should close roller shutter',
|
|
258
|
+
passed: false,
|
|
259
|
+
skipped: false,
|
|
260
|
+
error: 'Did not receive position 0 within 120 seconds',
|
|
261
|
+
device: deviceName
|
|
262
|
+
});
|
|
263
|
+
} else {
|
|
264
|
+
results.push({
|
|
265
|
+
name: 'should close roller shutter',
|
|
266
|
+
passed: true,
|
|
267
|
+
skipped: false,
|
|
268
|
+
error: null,
|
|
269
|
+
device: deviceName
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
} catch (error) {
|
|
273
|
+
results.push({
|
|
274
|
+
name: 'should close roller shutter',
|
|
275
|
+
passed: false,
|
|
276
|
+
skipped: false,
|
|
277
|
+
error: error.message,
|
|
278
|
+
device: deviceName
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Test 3: Get opening timer duration
|
|
283
|
+
try {
|
|
284
|
+
await testDevice.getRollerShutterState();
|
|
285
|
+
|
|
286
|
+
const state = testDevice.getCachedRollerShutterState(0);
|
|
287
|
+
|
|
288
|
+
if (!state) {
|
|
289
|
+
results.push({
|
|
290
|
+
name: 'should get opening timer duration',
|
|
291
|
+
passed: false,
|
|
292
|
+
skipped: false,
|
|
293
|
+
error: 'Could not get cached roller shutter state',
|
|
294
|
+
device: deviceName
|
|
295
|
+
});
|
|
296
|
+
} else {
|
|
297
|
+
const openingTimer = state.open_timer_duration_millis;
|
|
298
|
+
|
|
299
|
+
if (!openingTimer || openingTimer <= 0) {
|
|
300
|
+
results.push({
|
|
301
|
+
name: 'should get opening timer duration',
|
|
302
|
+
passed: false,
|
|
303
|
+
skipped: false,
|
|
304
|
+
error: `Invalid opening timer: ${openingTimer}`,
|
|
305
|
+
device: deviceName
|
|
306
|
+
});
|
|
307
|
+
} else {
|
|
308
|
+
results.push({
|
|
309
|
+
name: 'should get opening timer duration',
|
|
310
|
+
passed: true,
|
|
311
|
+
skipped: false,
|
|
312
|
+
error: null,
|
|
313
|
+
device: deviceName,
|
|
314
|
+
details: { openingTimer: openingTimer }
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
} catch (error) {
|
|
319
|
+
results.push({
|
|
320
|
+
name: 'should get opening timer duration',
|
|
321
|
+
passed: false,
|
|
322
|
+
skipped: false,
|
|
323
|
+
error: error.message,
|
|
324
|
+
device: deviceName
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Test 4: Get closing timer duration
|
|
329
|
+
try {
|
|
330
|
+
await testDevice.getRollerShutterState();
|
|
331
|
+
|
|
332
|
+
const state = testDevice.getCachedRollerShutterState(0);
|
|
333
|
+
|
|
334
|
+
if (!state) {
|
|
335
|
+
results.push({
|
|
336
|
+
name: 'should get closing timer duration',
|
|
337
|
+
passed: false,
|
|
338
|
+
skipped: false,
|
|
339
|
+
error: 'Could not get cached roller shutter state',
|
|
340
|
+
device: deviceName
|
|
341
|
+
});
|
|
342
|
+
} else {
|
|
343
|
+
const closingTimer = state.close_timer_duration_millis;
|
|
344
|
+
|
|
345
|
+
if (!closingTimer || closingTimer <= 0) {
|
|
346
|
+
results.push({
|
|
347
|
+
name: 'should get closing timer duration',
|
|
348
|
+
passed: false,
|
|
349
|
+
skipped: false,
|
|
350
|
+
error: `Invalid closing timer: ${closingTimer}`,
|
|
351
|
+
device: deviceName
|
|
352
|
+
});
|
|
353
|
+
} else {
|
|
354
|
+
results.push({
|
|
355
|
+
name: 'should get closing timer duration',
|
|
356
|
+
passed: true,
|
|
357
|
+
skipped: false,
|
|
358
|
+
error: null,
|
|
359
|
+
device: deviceName,
|
|
360
|
+
details: { closingTimer: closingTimer }
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
} catch (error) {
|
|
365
|
+
results.push({
|
|
366
|
+
name: 'should get closing timer duration',
|
|
367
|
+
passed: false,
|
|
368
|
+
skipped: false,
|
|
369
|
+
error: error.message,
|
|
370
|
+
device: deviceName
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Test 5: Set roller shutter config timers
|
|
375
|
+
try {
|
|
376
|
+
await testDevice.getRollerShutterState();
|
|
377
|
+
|
|
378
|
+
// Retrieve original values
|
|
379
|
+
const originalState = testDevice.getCachedRollerShutterState(0);
|
|
380
|
+
|
|
381
|
+
if (!originalState) {
|
|
382
|
+
results.push({
|
|
383
|
+
name: 'should set roller shutter config timers',
|
|
384
|
+
passed: false,
|
|
385
|
+
skipped: true,
|
|
386
|
+
error: 'Could not get original state',
|
|
387
|
+
device: deviceName
|
|
388
|
+
});
|
|
389
|
+
} else if (typeof testDevice.setRollerShutterConfig !== 'function') {
|
|
390
|
+
results.push({
|
|
391
|
+
name: 'should set roller shutter config timers',
|
|
392
|
+
passed: false,
|
|
393
|
+
skipped: true,
|
|
394
|
+
error: 'Device does not support setRollerShutterConfig',
|
|
395
|
+
device: deviceName
|
|
396
|
+
});
|
|
397
|
+
} else {
|
|
398
|
+
const originalOpenTimer = originalState.open_timer_duration_millis;
|
|
399
|
+
const originalCloseTimer = originalState.close_timer_duration_millis;
|
|
400
|
+
|
|
401
|
+
// Set new random values
|
|
402
|
+
const openTimer = Math.floor(Math.random() * (120 - 10 + 1)) + 10; // 10-120 seconds
|
|
403
|
+
const closeTimer = Math.floor(Math.random() * (120 - 10 + 1)) + 10; // 10-120 seconds
|
|
404
|
+
|
|
405
|
+
await testDevice.setRollerShutterConfig({
|
|
406
|
+
openTimerSeconds: openTimer,
|
|
407
|
+
closeTimerSeconds: closeTimer,
|
|
408
|
+
channel: 0
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
412
|
+
|
|
413
|
+
await testDevice.getRollerShutterState();
|
|
414
|
+
const newState = testDevice.getCachedRollerShutterState(0);
|
|
415
|
+
|
|
416
|
+
if (!newState) {
|
|
417
|
+
results.push({
|
|
418
|
+
name: 'should set roller shutter config timers',
|
|
419
|
+
passed: false,
|
|
420
|
+
skipped: false,
|
|
421
|
+
error: 'Could not get new state after setting config',
|
|
422
|
+
device: deviceName
|
|
423
|
+
});
|
|
424
|
+
} else if (newState.open_timer_duration_millis !== openTimer * 1000 ||
|
|
425
|
+
newState.close_timer_duration_millis !== closeTimer * 1000) {
|
|
426
|
+
results.push({
|
|
427
|
+
name: 'should set roller shutter config timers',
|
|
428
|
+
passed: false,
|
|
429
|
+
skipped: false,
|
|
430
|
+
error: `Timer mismatch. Expected open=${openTimer * 1000}, close=${closeTimer * 1000}, got open=${newState.open_timer_duration_millis}, close=${newState.close_timer_duration_millis}`,
|
|
431
|
+
device: deviceName
|
|
432
|
+
});
|
|
433
|
+
} else {
|
|
434
|
+
// Restore original values
|
|
435
|
+
await testDevice.setRollerShutterConfig({
|
|
436
|
+
openTimerSeconds: Math.floor(originalOpenTimer / 1000),
|
|
437
|
+
closeTimerSeconds: Math.floor(originalCloseTimer / 1000),
|
|
438
|
+
channel: 0
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
results.push({
|
|
442
|
+
name: 'should set roller shutter config timers',
|
|
443
|
+
passed: true,
|
|
444
|
+
skipped: false,
|
|
445
|
+
error: null,
|
|
446
|
+
device: deviceName
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
} catch (error) {
|
|
451
|
+
results.push({
|
|
452
|
+
name: 'should set roller shutter config timers',
|
|
453
|
+
passed: false,
|
|
454
|
+
skipped: false,
|
|
455
|
+
error: error.message,
|
|
456
|
+
device: deviceName
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// Test 6: Get roller shutter config
|
|
461
|
+
try {
|
|
462
|
+
if (typeof testDevice.getRollerShutterConfig !== 'function') {
|
|
463
|
+
results.push({
|
|
464
|
+
name: 'should get roller shutter config',
|
|
465
|
+
passed: false,
|
|
466
|
+
skipped: true,
|
|
467
|
+
error: 'Device does not support getRollerShutterConfig',
|
|
468
|
+
device: deviceName
|
|
469
|
+
});
|
|
470
|
+
} else {
|
|
471
|
+
const config = await testDevice.getRollerShutterConfig();
|
|
472
|
+
|
|
473
|
+
if (!config) {
|
|
474
|
+
results.push({
|
|
475
|
+
name: 'should get roller shutter config',
|
|
476
|
+
passed: false,
|
|
477
|
+
skipped: false,
|
|
478
|
+
error: 'getRollerShutterConfig returned null or undefined',
|
|
479
|
+
device: deviceName
|
|
480
|
+
});
|
|
481
|
+
} else {
|
|
482
|
+
results.push({
|
|
483
|
+
name: 'should get roller shutter config',
|
|
484
|
+
passed: true,
|
|
485
|
+
skipped: false,
|
|
486
|
+
error: null,
|
|
487
|
+
device: deviceName,
|
|
488
|
+
details: { config: config.config || config }
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
} catch (error) {
|
|
493
|
+
results.push({
|
|
494
|
+
name: 'should get roller shutter config',
|
|
495
|
+
passed: false,
|
|
496
|
+
skipped: false,
|
|
497
|
+
error: error.message,
|
|
498
|
+
device: deviceName
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// Test 7: Get roller shutter position
|
|
503
|
+
try {
|
|
504
|
+
if (typeof testDevice.getRollerShutterPosition !== 'function') {
|
|
505
|
+
results.push({
|
|
506
|
+
name: 'should get roller shutter position',
|
|
507
|
+
passed: false,
|
|
508
|
+
skipped: true,
|
|
509
|
+
error: 'Device does not support getRollerShutterPosition',
|
|
510
|
+
device: deviceName
|
|
511
|
+
});
|
|
512
|
+
} else {
|
|
513
|
+
const response = await testDevice.getRollerShutterPosition({ channel: 0 });
|
|
514
|
+
|
|
515
|
+
if (!response) {
|
|
516
|
+
results.push({
|
|
517
|
+
name: 'should get roller shutter position',
|
|
518
|
+
passed: false,
|
|
519
|
+
skipped: false,
|
|
520
|
+
error: 'getRollerShutterPosition returned null or undefined',
|
|
521
|
+
device: deviceName
|
|
522
|
+
});
|
|
523
|
+
} else {
|
|
524
|
+
results.push({
|
|
525
|
+
name: 'should get roller shutter position',
|
|
526
|
+
passed: true,
|
|
527
|
+
skipped: false,
|
|
528
|
+
error: null,
|
|
529
|
+
device: deviceName,
|
|
530
|
+
details: { position: response }
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
} catch (error) {
|
|
535
|
+
results.push({
|
|
536
|
+
name: 'should get roller shutter position',
|
|
537
|
+
passed: false,
|
|
538
|
+
skipped: false,
|
|
539
|
+
error: error.message,
|
|
540
|
+
device: deviceName
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// Test 8: Control roller shutter position
|
|
545
|
+
try {
|
|
546
|
+
if (typeof testDevice.controlRollerShutterPosition !== 'function') {
|
|
547
|
+
results.push({
|
|
548
|
+
name: 'should control roller shutter position',
|
|
549
|
+
passed: false,
|
|
550
|
+
skipped: true,
|
|
551
|
+
error: 'Device does not support controlRollerShutterPosition',
|
|
552
|
+
device: deviceName
|
|
553
|
+
});
|
|
554
|
+
} else {
|
|
555
|
+
// Get current position first
|
|
556
|
+
await testDevice.getRollerShutterPosition({ channel: 0 });
|
|
557
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
558
|
+
|
|
559
|
+
// Note: We don't actually change the position to avoid disrupting the device
|
|
560
|
+
// We just verify the method exists
|
|
561
|
+
results.push({
|
|
562
|
+
name: 'should control roller shutter position',
|
|
563
|
+
passed: true,
|
|
564
|
+
skipped: false,
|
|
565
|
+
error: null,
|
|
566
|
+
device: deviceName,
|
|
567
|
+
details: { note: 'Method exists, but not changing position to avoid disruption' }
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
} catch (error) {
|
|
571
|
+
results.push({
|
|
572
|
+
name: 'should control roller shutter position',
|
|
573
|
+
passed: false,
|
|
574
|
+
skipped: false,
|
|
575
|
+
error: error.message,
|
|
576
|
+
device: deviceName
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// Test 9: Get roller shutter adjust
|
|
581
|
+
try {
|
|
582
|
+
if (typeof testDevice.getRollerShutterAdjust !== 'function') {
|
|
583
|
+
results.push({
|
|
584
|
+
name: 'should get roller shutter adjust',
|
|
585
|
+
passed: false,
|
|
586
|
+
skipped: true,
|
|
587
|
+
error: 'Device does not support getRollerShutterAdjust',
|
|
588
|
+
device: deviceName
|
|
589
|
+
});
|
|
590
|
+
} else {
|
|
591
|
+
const response = await testDevice.getRollerShutterAdjust({ channel: 0 });
|
|
592
|
+
|
|
593
|
+
if (!response) {
|
|
594
|
+
results.push({
|
|
595
|
+
name: 'should get roller shutter adjust',
|
|
596
|
+
passed: false,
|
|
597
|
+
skipped: false,
|
|
598
|
+
error: 'getRollerShutterAdjust returned null or undefined',
|
|
599
|
+
device: deviceName
|
|
600
|
+
});
|
|
601
|
+
} else {
|
|
602
|
+
results.push({
|
|
603
|
+
name: 'should get roller shutter adjust',
|
|
604
|
+
passed: true,
|
|
605
|
+
skipped: false,
|
|
606
|
+
error: null,
|
|
607
|
+
device: deviceName,
|
|
608
|
+
details: { adjust: response }
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
} catch (error) {
|
|
613
|
+
results.push({
|
|
614
|
+
name: 'should get roller shutter adjust',
|
|
615
|
+
passed: false,
|
|
616
|
+
skipped: false,
|
|
617
|
+
error: error.message,
|
|
618
|
+
device: deviceName
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
return results;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
module.exports = {
|
|
626
|
+
metadata,
|
|
627
|
+
runTests
|
|
628
|
+
};
|