meross-cli 0.1.0 → 0.2.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 +9 -1
- package/README.md +11 -1
- package/cli/commands/control/execute.js +1 -1
- package/cli/commands/control/menu.js +5 -5
- package/cli/commands/dump.js +1 -1
- package/cli/commands/info.js +1 -1
- package/cli/commands/list.js +2 -2
- package/cli/commands/mqtt.js +2 -2
- package/cli/commands/sniffer/sniffer-menu.js +3 -3
- package/cli/commands/status/device-status.js +2 -2
- package/cli/commands/status/index.js +1 -1
- package/cli/helpers/meross.js +2 -2
- package/cli/menu/main.js +6 -6
- package/cli/menu/settings.js +11 -11
- package/cli/meross-cli.js +3 -3
- package/cli/tests/README.md +1 -1
- package/cli/tests/test-control.js +1 -1
- package/cli/tests/test-dnd.js +1 -1
- package/cli/tests/test-helper.js +5 -5
- package/cli/tests/test-light.js +2 -2
- package/cli/tests/test-runner.js +3 -3
- package/cli/tests/test-runtime.js +1 -1
- package/cli/tests/test-template.js +1 -1
- package/cli/tests/test-toggle.js +2 -2
- package/package.json +2 -3
package/CHANGELOG.md
CHANGED
|
@@ -5,7 +5,15 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [
|
|
8
|
+
## [0.2.0] - 2026-01-15
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- **BREAKING**: Updated to use new Manager-prefix naming pattern from `meross-iot` package
|
|
12
|
+
- `MerossManager` → `ManagerMeross` (internal usage)
|
|
13
|
+
- `SubscriptionManager` → `ManagerSubscription` (internal usage)
|
|
14
|
+
- **BREAKING**: Updated to use new property-based access patterns from `meross-iot` package
|
|
15
|
+
- Uses `meross.subscription` instead of `getSubscriptionManager()`
|
|
16
|
+
- Uses `meross.devices.get()`, `meross.devices.find()`, and `meross.devices.list()` instead of wrapper methods
|
|
9
17
|
|
|
10
18
|
## [0.1.0] - 2026-01-10
|
|
11
19
|
|
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ Command-line interface for controlling and managing Meross smart home devices.
|
|
|
23
23
|
npm install -g meross-cli@alpha
|
|
24
24
|
|
|
25
25
|
# Or install specific version
|
|
26
|
-
npm install -g meross-cli@0.
|
|
26
|
+
npm install -g meross-cli@0.2.0
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
Or use via npx:
|
|
@@ -77,6 +77,16 @@ The CLI supports all devices that are supported by the underlying `meross-iot` l
|
|
|
77
77
|
|
|
78
78
|
## Changelog
|
|
79
79
|
|
|
80
|
+
### [0.2.0] - 2026-01-15
|
|
81
|
+
|
|
82
|
+
#### Changed
|
|
83
|
+
- **BREAKING**: Updated to use new Manager-prefix naming pattern from `meross-iot` package
|
|
84
|
+
- `MerossManager` → `ManagerMeross` (internal usage)
|
|
85
|
+
- `SubscriptionManager` → `ManagerSubscription` (internal usage)
|
|
86
|
+
- **BREAKING**: Updated to use new property-based access patterns from `meross-iot` package
|
|
87
|
+
- Uses `meross.subscription` instead of `getSubscriptionManager()`
|
|
88
|
+
- Uses `meross.devices.get()`, `meross.devices.find()`, and `meross.devices.list()` instead of wrapper methods
|
|
89
|
+
|
|
80
90
|
### [0.1.0] - 2026-01-10
|
|
81
91
|
|
|
82
92
|
#### Added
|
|
@@ -23,12 +23,12 @@ async function question(rl, query) {
|
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Interactive device control menu.
|
|
26
|
-
* @param {Object} manager -
|
|
26
|
+
* @param {Object} manager - ManagerMeross instance
|
|
27
27
|
* @param {Object} rl - Readline interface
|
|
28
28
|
* @param {string|null} currentUser - Current logged in user name
|
|
29
29
|
*/
|
|
30
30
|
async function controlDeviceMenu(manager, rl, currentUser = null) {
|
|
31
|
-
const devices = manager.
|
|
31
|
+
const devices = manager.devices.list().filter(d => !(d instanceof MerossSubDevice));
|
|
32
32
|
if (devices.length === 0) {
|
|
33
33
|
console.log('\nNo devices found.');
|
|
34
34
|
return;
|
|
@@ -50,7 +50,7 @@ async function controlDeviceMenu(manager, rl, currentUser = null) {
|
|
|
50
50
|
choices: deviceChoices
|
|
51
51
|
}]);
|
|
52
52
|
|
|
53
|
-
const device = manager.
|
|
53
|
+
const device = manager.devices.get(uuid);
|
|
54
54
|
|
|
55
55
|
// Wait for device to connect if needed
|
|
56
56
|
if (!device.deviceConnected) {
|
|
@@ -92,11 +92,11 @@ async function controlDeviceMenu(manager, rl, currentUser = null) {
|
|
|
92
92
|
// Control loop
|
|
93
93
|
while (true) {
|
|
94
94
|
clearScreen();
|
|
95
|
-
const deviceCount = manager.
|
|
95
|
+
const deviceCount = manager.devices.list().filter(d => !(d instanceof MerossSubDevice)).length;
|
|
96
96
|
renderSimpleHeader(currentUser, deviceCount);
|
|
97
97
|
clearMenuArea(SIMPLE_CONTENT_START_LINE);
|
|
98
98
|
|
|
99
|
-
const info = formatDevice(manager.
|
|
99
|
+
const info = formatDevice(manager.devices.get(uuid));
|
|
100
100
|
console.log(chalk.bold(`=== Control Device: ${info.name} ===\n`));
|
|
101
101
|
|
|
102
102
|
// Build choices grouped by category
|
package/cli/commands/dump.js
CHANGED
package/cli/commands/info.js
CHANGED
|
@@ -197,7 +197,7 @@ function _displayCapabilities(device) {
|
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
async function showDeviceInfo(manager, uuid) {
|
|
200
|
-
const device = manager.
|
|
200
|
+
const device = manager.devices.get(uuid);
|
|
201
201
|
|
|
202
202
|
if (!device) {
|
|
203
203
|
console.error(`Device with UUID ${chalk.cyan(uuid)} not found.`);
|
package/cli/commands/list.js
CHANGED
|
@@ -6,7 +6,7 @@ const { MerossHubDevice, MerossSubDevice, OnlineStatus, parsePushNotification }
|
|
|
6
6
|
const { formatDevice } = require('../utils/display');
|
|
7
7
|
|
|
8
8
|
async function listDevices(manager) {
|
|
9
|
-
const hubs = manager.
|
|
9
|
+
const hubs = manager.devices.list().filter(device => device instanceof MerossHubDevice);
|
|
10
10
|
if (hubs.length > 0) {
|
|
11
11
|
const spinner = ora('Loading devices and refreshing hub status').start();
|
|
12
12
|
// Refresh hub state to update subdevice online status
|
|
@@ -48,7 +48,7 @@ async function listDevices(manager) {
|
|
|
48
48
|
spinner.stop();
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
const allDevices = manager.
|
|
51
|
+
const allDevices = manager.devices.list();
|
|
52
52
|
const devices = allDevices.filter(device => !(device instanceof MerossSubDevice));
|
|
53
53
|
|
|
54
54
|
if (devices.length === 0) {
|
package/cli/commands/mqtt.js
CHANGED
|
@@ -42,7 +42,7 @@ async function listMqttConnections(manager, options = {}) {
|
|
|
42
42
|
|
|
43
43
|
const namespaces = new Set();
|
|
44
44
|
deviceUuids.forEach(uuid => {
|
|
45
|
-
const device = manager.
|
|
45
|
+
const device = manager.devices.get(uuid);
|
|
46
46
|
if (device && device.abilities) {
|
|
47
47
|
Object.keys(device.abilities).forEach(namespace => {
|
|
48
48
|
namespaces.add(namespace);
|
|
@@ -170,7 +170,7 @@ async function listMqttConnections(manager, options = {}) {
|
|
|
170
170
|
if (conn.deviceUuids.length > 0) {
|
|
171
171
|
console.log(`\n ${chalk.white.bold(`Device UUIDs (${chalk.cyan(conn.deviceUuids.length)}):`)}`);
|
|
172
172
|
conn.deviceUuids.forEach((uuid) => {
|
|
173
|
-
const device = manager.
|
|
173
|
+
const device = manager.devices.get(uuid);
|
|
174
174
|
const deviceName = device ? (device.name || 'Unknown') : 'Unknown';
|
|
175
175
|
console.log(` ${chalk.cyan(uuid)} ${chalk.gray(`(${deviceName})`)}`);
|
|
176
176
|
});
|
|
@@ -447,7 +447,7 @@ async function _createZipArchive(options) {
|
|
|
447
447
|
|
|
448
448
|
/**
|
|
449
449
|
* Main sniffer menu function
|
|
450
|
-
* @param {Object} manager -
|
|
450
|
+
* @param {Object} manager - ManagerMeross instance
|
|
451
451
|
* @param {Object} rl - Readline interface
|
|
452
452
|
* @param {string|null} currentUser - Current logged in user name
|
|
453
453
|
*/
|
|
@@ -464,7 +464,7 @@ async function snifferMenu(manager, rl, currentUser = null) {
|
|
|
464
464
|
logStream.write(`[${timestamp}] ${msg}\n`);
|
|
465
465
|
};
|
|
466
466
|
|
|
467
|
-
const deviceCount = manager.
|
|
467
|
+
const deviceCount = manager.devices.list().filter(d => {
|
|
468
468
|
const { MerossSubDevice } = require('meross-iot');
|
|
469
469
|
return !(d instanceof MerossSubDevice);
|
|
470
470
|
}).length;
|
|
@@ -473,7 +473,7 @@ async function snifferMenu(manager, rl, currentUser = null) {
|
|
|
473
473
|
_printWelcomeMessage(currentUser, deviceCount);
|
|
474
474
|
|
|
475
475
|
// Select device
|
|
476
|
-
const devices = manager.
|
|
476
|
+
const devices = manager.devices.list().filter(d => {
|
|
477
477
|
// Filter out subdevices
|
|
478
478
|
const { MerossSubDevice } = require('meross-iot');
|
|
479
479
|
return !(d instanceof MerossSubDevice);
|
|
@@ -410,7 +410,7 @@ function _mapRollerShutterFeatureNamespace(namespace, device) {
|
|
|
410
410
|
|
|
411
411
|
/**
|
|
412
412
|
* Feature namespace mapping registry organized by feature type.
|
|
413
|
-
* Matches the
|
|
413
|
+
* Matches the ManagerMeross class structure where features are organized by type.
|
|
414
414
|
*/
|
|
415
415
|
const FEATURE_NAMESPACE_MAPPERS = [
|
|
416
416
|
{ prefix: 'Appliance.Control.Toggle', mapper: _mapToggleFeatureNamespace },
|
|
@@ -433,7 +433,7 @@ const FEATURE_NAMESPACE_MAPPERS = [
|
|
|
433
433
|
/**
|
|
434
434
|
* Maps a namespace to its feature method and arguments.
|
|
435
435
|
* Returns { featureMethod, featureArgs } or { featureMethod: null, featureArgs: [] } if no feature method exists.
|
|
436
|
-
* Organized by feature type to match
|
|
436
|
+
* Organized by feature type to match ManagerMeross class structure.
|
|
437
437
|
*/
|
|
438
438
|
function _mapNamespaceToFeatureMethod(namespace, device) {
|
|
439
439
|
for (const { prefix, mapper } of FEATURE_NAMESPACE_MAPPERS) {
|
|
@@ -6,7 +6,7 @@ const { displayHubStatus } = require('./hub-status');
|
|
|
6
6
|
const { displayDeviceStatus } = require('./device-status');
|
|
7
7
|
|
|
8
8
|
async function getDeviceStatus(manager, filterUuid = null, filterSubdeviceId = null) {
|
|
9
|
-
const allDevices = filterUuid ? [manager.
|
|
9
|
+
const allDevices = filterUuid ? [manager.devices.get(filterUuid)].filter(Boolean) : manager.devices.list();
|
|
10
10
|
const devices = allDevices.filter(device => !(device instanceof MerossSubDevice));
|
|
11
11
|
|
|
12
12
|
if (devices.length === 0) {
|
package/cli/helpers/meross.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const ManagerMeross = require('meross-iot');
|
|
4
4
|
const { MerossHttpClient, TransportMode } = require('meross-iot');
|
|
5
5
|
const ora = require('ora');
|
|
6
6
|
|
|
@@ -41,7 +41,7 @@ async function createMerossInstance(optionsOrEmail, password, mfaCode, transport
|
|
|
41
41
|
});
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
const instance = new
|
|
44
|
+
const instance = new ManagerMeross({
|
|
45
45
|
httpClient,
|
|
46
46
|
transportMode: finalTransportMode,
|
|
47
47
|
timeout: finalTimeout,
|
package/cli/menu/main.js
CHANGED
|
@@ -14,7 +14,7 @@ const { showSettingsMenu } = require('./settings');
|
|
|
14
14
|
// Helper functions
|
|
15
15
|
function _getDeviceCount(manager) {
|
|
16
16
|
if (!manager) {return 0;}
|
|
17
|
-
return manager.
|
|
17
|
+
return manager.devices.list().filter(d => !(d instanceof MerossSubDevice)).length;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
function _renderMainMenuHeader(currentUser, manager) {
|
|
@@ -170,7 +170,7 @@ async function _saveCredentialsPrompt(rl, currentCredentials) {
|
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
async function _selectDevice(manager, message = 'Select device:') {
|
|
173
|
-
const devices = manager.
|
|
173
|
+
const devices = manager.devices.list().filter(d => !(d instanceof MerossSubDevice));
|
|
174
174
|
if (devices.length === 0) {
|
|
175
175
|
return null;
|
|
176
176
|
}
|
|
@@ -194,7 +194,7 @@ async function _selectDevice(manager, message = 'Select device:') {
|
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
async function _selectDeviceOrAll(manager) {
|
|
197
|
-
const devices = manager.
|
|
197
|
+
const devices = manager.devices.list().filter(d => !(d instanceof MerossSubDevice));
|
|
198
198
|
if (devices.length === 0) {
|
|
199
199
|
return null;
|
|
200
200
|
}
|
|
@@ -225,7 +225,7 @@ async function _selectSubdevice(manager, uuid) {
|
|
|
225
225
|
return null;
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
-
const device = manager.
|
|
228
|
+
const device = manager.devices.get(uuid);
|
|
229
229
|
if (!(device instanceof MerossHubDevice)) {
|
|
230
230
|
return null;
|
|
231
231
|
}
|
|
@@ -262,7 +262,7 @@ async function _handleListCommand(manager, rl) {
|
|
|
262
262
|
}
|
|
263
263
|
|
|
264
264
|
async function _handleInfoCommand(manager, rl) {
|
|
265
|
-
const devices = manager.
|
|
265
|
+
const devices = manager.devices.list().filter(d => !(d instanceof MerossSubDevice));
|
|
266
266
|
if (devices.length === 0) {
|
|
267
267
|
console.log('\nNo devices found.');
|
|
268
268
|
await question(rl, '\nPress Enter to return to menu...');
|
|
@@ -277,7 +277,7 @@ async function _handleInfoCommand(manager, rl) {
|
|
|
277
277
|
}
|
|
278
278
|
|
|
279
279
|
async function _handleStatusCommand(manager, rl) {
|
|
280
|
-
const devices = manager.
|
|
280
|
+
const devices = manager.devices.list().filter(d => !(d instanceof MerossSubDevice));
|
|
281
281
|
if (devices.length === 0) {
|
|
282
282
|
console.log('\nNo devices found.');
|
|
283
283
|
await question(rl, '\nPress Enter to return to menu...');
|
package/cli/menu/settings.js
CHANGED
|
@@ -25,7 +25,7 @@ async function showSettingsMenu(rl, currentManager, currentUser, timeout, enable
|
|
|
25
25
|
while (true) {
|
|
26
26
|
// Clear screen and render simple header
|
|
27
27
|
clearScreen();
|
|
28
|
-
const deviceCount = currentManager ? currentManager.
|
|
28
|
+
const deviceCount = currentManager ? currentManager.devices.list().filter(d => !(d instanceof MerossSubDevice)).length : 0;
|
|
29
29
|
renderSimpleHeader(currentUser, deviceCount);
|
|
30
30
|
clearMenuArea(SIMPLE_CONTENT_START_LINE);
|
|
31
31
|
|
|
@@ -102,7 +102,7 @@ async function showSettingsMenu(rl, currentManager, currentUser, timeout, enable
|
|
|
102
102
|
async function showTransportModeSettings(rl, currentManager, currentUser, setTransportMode) {
|
|
103
103
|
// Clear screen and render simple header
|
|
104
104
|
clearScreen();
|
|
105
|
-
const deviceCount = currentManager ? currentManager.
|
|
105
|
+
const deviceCount = currentManager ? currentManager.devices.list().filter(d => !(d instanceof MerossSubDevice)).length : 0;
|
|
106
106
|
renderSimpleHeader(currentUser, deviceCount);
|
|
107
107
|
clearMenuArea(SIMPLE_CONTENT_START_LINE);
|
|
108
108
|
|
|
@@ -135,7 +135,7 @@ async function showTransportModeSettings(rl, currentManager, currentUser, setTra
|
|
|
135
135
|
async function showStatisticsSettings(rl, currentManager, currentUser, enableStats, setEnableStats) {
|
|
136
136
|
// Clear screen and render simple header
|
|
137
137
|
clearScreen();
|
|
138
|
-
const deviceCount = currentManager ? currentManager.
|
|
138
|
+
const deviceCount = currentManager ? currentManager.devices.list().filter(d => !(d instanceof MerossSubDevice)).length : 0;
|
|
139
139
|
renderSimpleHeader(currentUser, deviceCount);
|
|
140
140
|
clearMenuArea(SIMPLE_CONTENT_START_LINE);
|
|
141
141
|
|
|
@@ -190,7 +190,7 @@ async function showStatisticsSettings(rl, currentManager, currentUser, enableSta
|
|
|
190
190
|
// Helper functions for user management menu
|
|
191
191
|
function _renderUserManagementHeader(currentManager, currentUser) {
|
|
192
192
|
clearScreen();
|
|
193
|
-
const deviceCount = currentManager ? currentManager.
|
|
193
|
+
const deviceCount = currentManager ? currentManager.devices.list().filter(d => !(d instanceof MerossSubDevice)).length : 0;
|
|
194
194
|
renderSimpleHeader(currentUser, deviceCount);
|
|
195
195
|
clearMenuArea(SIMPLE_CONTENT_START_LINE);
|
|
196
196
|
process.stdout.write(chalk.bold('=== User Management ===\n\n'));
|
|
@@ -478,7 +478,7 @@ async function showUserManagementMenu(rl, currentManager, currentUser, callbacks
|
|
|
478
478
|
async function showTimeoutSettings(rl, currentManager, currentUser, timeout, setTimeout) {
|
|
479
479
|
// Clear screen and render simple header
|
|
480
480
|
clearScreen();
|
|
481
|
-
const deviceCount = currentManager ? currentManager.
|
|
481
|
+
const deviceCount = currentManager ? currentManager.devices.list().filter(d => !(d instanceof MerossSubDevice)).length : 0;
|
|
482
482
|
renderSimpleHeader(currentUser, deviceCount);
|
|
483
483
|
clearMenuArea(SIMPLE_CONTENT_START_LINE);
|
|
484
484
|
|
|
@@ -521,7 +521,7 @@ async function showTimeoutSettings(rl, currentManager, currentUser, timeout, set
|
|
|
521
521
|
async function showVerboseSettings(rl, currentManager, currentUser, verbose, setVerbose) {
|
|
522
522
|
// Clear screen and render simple header
|
|
523
523
|
clearScreen();
|
|
524
|
-
const deviceCount = currentManager ? currentManager.
|
|
524
|
+
const deviceCount = currentManager ? currentManager.devices.list().filter(d => !(d instanceof MerossSubDevice)).length : 0;
|
|
525
525
|
renderSimpleHeader(currentUser, deviceCount);
|
|
526
526
|
clearMenuArea(SIMPLE_CONTENT_START_LINE);
|
|
527
527
|
|
|
@@ -574,7 +574,7 @@ async function showErrorBudgetSettings(rl, currentManager, currentUser) {
|
|
|
574
574
|
while (true) {
|
|
575
575
|
// Clear screen and render simple header
|
|
576
576
|
clearScreen();
|
|
577
|
-
const deviceCount = currentManager.
|
|
577
|
+
const deviceCount = currentManager.devices.list().filter(d => !(d instanceof MerossSubDevice)).length;
|
|
578
578
|
renderSimpleHeader(currentUser, deviceCount);
|
|
579
579
|
clearMenuArea(SIMPLE_CONTENT_START_LINE);
|
|
580
580
|
|
|
@@ -619,7 +619,7 @@ async function showErrorBudgetSettings(rl, currentManager, currentUser) {
|
|
|
619
619
|
if (action === 'back') {
|
|
620
620
|
break;
|
|
621
621
|
} else if (action === 'view-all') {
|
|
622
|
-
const devices = currentManager.
|
|
622
|
+
const devices = currentManager.devices.list().filter(d => !(d instanceof MerossSubDevice));
|
|
623
623
|
if (devices.length === 0) {
|
|
624
624
|
console.log(chalk.yellow('\n No devices found.\n'));
|
|
625
625
|
} else {
|
|
@@ -642,7 +642,7 @@ async function showErrorBudgetSettings(rl, currentManager, currentUser) {
|
|
|
642
642
|
message: 'Press Enter to continue...'
|
|
643
643
|
}]);
|
|
644
644
|
} else if (action === 'view-device') {
|
|
645
|
-
const devices = currentManager.
|
|
645
|
+
const devices = currentManager.devices.list().filter(d => !(d instanceof MerossSubDevice));
|
|
646
646
|
if (devices.length === 0) {
|
|
647
647
|
console.log(chalk.yellow('\n No devices found.\n'));
|
|
648
648
|
await inquirer.prompt([{
|
|
@@ -693,7 +693,7 @@ async function showErrorBudgetSettings(rl, currentManager, currentUser) {
|
|
|
693
693
|
message: 'Press Enter to continue...'
|
|
694
694
|
}]);
|
|
695
695
|
} else if (action === 'reset-device') {
|
|
696
|
-
const devices = currentManager.
|
|
696
|
+
const devices = currentManager.devices.list().filter(d => !(d instanceof MerossSubDevice));
|
|
697
697
|
if (devices.length === 0) {
|
|
698
698
|
console.log(chalk.yellow('\n No devices found.\n'));
|
|
699
699
|
await inquirer.prompt([{
|
|
@@ -756,7 +756,7 @@ async function showErrorBudgetSettings(rl, currentManager, currentUser) {
|
|
|
756
756
|
}]);
|
|
757
757
|
|
|
758
758
|
if (confirm) {
|
|
759
|
-
const devices = currentManager.
|
|
759
|
+
const devices = currentManager.devices.list().filter(d => !(d instanceof MerossSubDevice));
|
|
760
760
|
let resetCount = 0;
|
|
761
761
|
devices.forEach(device => {
|
|
762
762
|
const uuid = device.uuid;
|
package/cli/meross-cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
const
|
|
4
|
+
const ManagerMeross = require('meross-iot');
|
|
5
5
|
const { MerossHubDevice } = require('meross-iot');
|
|
6
6
|
const path = require('path');
|
|
7
7
|
const testRunner = require('./tests/test-runner');
|
|
@@ -85,7 +85,7 @@ Examples:
|
|
|
85
85
|
|
|
86
86
|
const { options, config } = processed;
|
|
87
87
|
|
|
88
|
-
const manager = new
|
|
88
|
+
const manager = new ManagerMeross(options);
|
|
89
89
|
|
|
90
90
|
// Handle device events
|
|
91
91
|
manager.on('deviceInitialized', (deviceId) => {
|
|
@@ -280,7 +280,7 @@ Examples:
|
|
|
280
280
|
}
|
|
281
281
|
|
|
282
282
|
function _resolveDevice(manager, uuid, subdeviceId) {
|
|
283
|
-
let device = manager.
|
|
283
|
+
let device = manager.devices.get(uuid.trim());
|
|
284
284
|
if (!device) {
|
|
285
285
|
console.error(chalk.red(`Error: Device not found: ${uuid}`));
|
|
286
286
|
process.exit(1);
|
package/cli/tests/README.md
CHANGED
|
@@ -210,7 +210,7 @@ module.exports = {
|
|
|
210
210
|
- `minDevices`: Minimum number of devices required (default: 1)
|
|
211
211
|
|
|
212
212
|
2. **runTests Function**: Must accept a `context` object with:
|
|
213
|
-
- `manager`:
|
|
213
|
+
- `manager`: ManagerMeross instance
|
|
214
214
|
- `devices`: Array of pre-selected devices (optional, will auto-discover if not provided)
|
|
215
215
|
- `options`: Test options (timeout, verbose, etc.)
|
|
216
216
|
|
|
@@ -26,7 +26,7 @@ async function runTests(context) {
|
|
|
26
26
|
const multipleDevices = await findDevicesByAbility(manager, 'Appliance.Control.Multiple', OnlineStatus.ONLINE);
|
|
27
27
|
|
|
28
28
|
// Also get any online device for testing control features
|
|
29
|
-
const allDevices = manager.
|
|
29
|
+
const allDevices = manager.devices.list();
|
|
30
30
|
const onlineDevices = allDevices.filter(device => {
|
|
31
31
|
const status = device.onlineStatus !== undefined ? device.onlineStatus : (device.dev?.onlineStatus);
|
|
32
32
|
return status === OnlineStatus.ONLINE;
|
package/cli/tests/test-dnd.js
CHANGED
|
@@ -24,7 +24,7 @@ async function runTests(context) {
|
|
|
24
24
|
let testDevices = devices || [];
|
|
25
25
|
if (testDevices.length === 0) {
|
|
26
26
|
// Find devices that support DND mode (most devices support this)
|
|
27
|
-
const allDevices = manager.
|
|
27
|
+
const allDevices = manager.devices.list();
|
|
28
28
|
testDevices = allDevices.filter(d => {
|
|
29
29
|
const status = d.onlineStatus !== undefined ? d.onlineStatus : (d.dev?.onlineStatus);
|
|
30
30
|
return status === OnlineStatus.ONLINE &&
|
package/cli/tests/test-helper.js
CHANGED
|
@@ -11,14 +11,14 @@ const { OnlineStatus } = require('meross-iot');
|
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Waits for devices to be discovered
|
|
14
|
-
* @param {Object} manager -
|
|
14
|
+
* @param {Object} manager - ManagerMeross instance
|
|
15
15
|
* @param {number} timeout - Timeout in milliseconds (default: 5000)
|
|
16
16
|
* @returns {Promise<Array>} Array of device objects with structure: { deviceId, deviceDef, device }
|
|
17
17
|
*/
|
|
18
18
|
function waitForDevices(manager, timeout = 5000) {
|
|
19
19
|
return new Promise((resolve) => {
|
|
20
20
|
// If devices already exist, return them immediately
|
|
21
|
-
const existingDevices = manager.
|
|
21
|
+
const existingDevices = manager.devices.list();
|
|
22
22
|
if (existingDevices && existingDevices.length > 0) {
|
|
23
23
|
const devices = [];
|
|
24
24
|
const deviceIds = new Set();
|
|
@@ -63,7 +63,7 @@ function waitForDevices(manager, timeout = 5000) {
|
|
|
63
63
|
|
|
64
64
|
// Also check periodically if devices were added (in case event was missed)
|
|
65
65
|
const checkInterval = setInterval(() => {
|
|
66
|
-
const currentDevices = manager.
|
|
66
|
+
const currentDevices = manager.devices.list();
|
|
67
67
|
if (currentDevices && currentDevices.length > 0) {
|
|
68
68
|
clearInterval(checkInterval);
|
|
69
69
|
if (timeoutId) {
|
|
@@ -119,7 +119,7 @@ function deviceHasAbility(device, namespace) {
|
|
|
119
119
|
|
|
120
120
|
/**
|
|
121
121
|
* Finds devices by ability namespace
|
|
122
|
-
* @param {Object} manager -
|
|
122
|
+
* @param {Object} manager - ManagerMeross instance
|
|
123
123
|
* @param {string} namespace - Ability namespace (e.g., 'Appliance.Control.ToggleX')
|
|
124
124
|
* @param {number|null} onlineStatus - OnlineStatus filter (optional, null = any status)
|
|
125
125
|
* @param {Array<Object>} deviceFilter - Optional pre-filtered device list (for CLI device selection)
|
|
@@ -166,7 +166,7 @@ async function findDevicesByAbility(manager, namespace, onlineStatus = null, dev
|
|
|
166
166
|
|
|
167
167
|
/**
|
|
168
168
|
* Finds devices by device type
|
|
169
|
-
* @param {Object} manager -
|
|
169
|
+
* @param {Object} manager - ManagerMeross instance
|
|
170
170
|
* @param {string} deviceType - Device type (e.g., 'mss310', 'msg100')
|
|
171
171
|
* @param {number|null} onlineStatus - OnlineStatus filter (optional, null = any status)
|
|
172
172
|
* @param {Array<Object>} deviceFilter - Optional pre-filtered device list (for CLI device selection)
|
package/cli/tests/test-light.js
CHANGED
|
@@ -233,13 +233,13 @@ async function runTests(context) {
|
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
// Test 3: RGB Push Notification
|
|
236
|
-
// Note: This test requires a second
|
|
236
|
+
// Note: This test requires a second ManagerMeross instance which is complex to set up
|
|
237
237
|
// For now, we'll skip this test or simplify it
|
|
238
238
|
results.push({
|
|
239
239
|
name: 'should receive push notification when RGB color changes',
|
|
240
240
|
passed: true,
|
|
241
241
|
skipped: true,
|
|
242
|
-
error: 'Push notification test requires second
|
|
242
|
+
error: 'Push notification test requires second ManagerMeross instance - skipped for simplicity',
|
|
243
243
|
device: deviceName,
|
|
244
244
|
details: { note: 'Test can be implemented later if needed' }
|
|
245
245
|
});
|
package/cli/tests/test-runner.js
CHANGED
|
@@ -157,7 +157,7 @@ async function runTest(testType, context) {
|
|
|
157
157
|
const { manager, devices = [], options = {} } = context;
|
|
158
158
|
|
|
159
159
|
if (!manager) {
|
|
160
|
-
throw new Error('
|
|
160
|
+
throw new Error('ManagerMeross instance is required in context');
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
// Resolve test type (handles aliases)
|
|
@@ -310,7 +310,7 @@ function getTestFile(testType) {
|
|
|
310
310
|
/**
|
|
311
311
|
* Finds devices for a given test type
|
|
312
312
|
* @param {string} testType - Test type name or alias
|
|
313
|
-
* @param {Object} manager -
|
|
313
|
+
* @param {Object} manager - ManagerMeross instance
|
|
314
314
|
* @returns {Promise<Array>} Array of matching devices
|
|
315
315
|
*/
|
|
316
316
|
async function findDevicesForTestType(testType, manager) {
|
|
@@ -321,7 +321,7 @@ async function findDevicesForTestType(testType, manager) {
|
|
|
321
321
|
return [];
|
|
322
322
|
}
|
|
323
323
|
|
|
324
|
-
const allDevices = manager.
|
|
324
|
+
const allDevices = manager.devices.list();
|
|
325
325
|
if (!allDevices || allDevices.length === 0) {
|
|
326
326
|
const { waitForDevices } = require('./test-helper');
|
|
327
327
|
const deviceList = await waitForDevices(manager, 1000);
|
|
@@ -23,7 +23,7 @@ async function runTests(context) {
|
|
|
23
23
|
let testDevices = devices || [];
|
|
24
24
|
if (testDevices.length === 0) {
|
|
25
25
|
// Runtime is typically available on most devices, so we'll test with any online device
|
|
26
|
-
const allDevices = manager.
|
|
26
|
+
const allDevices = manager.devices.list();
|
|
27
27
|
testDevices = allDevices.filter(device => {
|
|
28
28
|
const status = device.onlineStatus !== undefined ? device.onlineStatus : (device.dev?.onlineStatus);
|
|
29
29
|
if (status !== OnlineStatus.ONLINE) return false;
|
|
@@ -32,7 +32,7 @@ const metadata = {
|
|
|
32
32
|
/**
|
|
33
33
|
* Runs all tests for this test type
|
|
34
34
|
* @param {Object} context - Test context object
|
|
35
|
-
* @param {Object} context.manager -
|
|
35
|
+
* @param {Object} context.manager - ManagerMeross instance (already connected)
|
|
36
36
|
* @param {Array<Object>} context.devices - Pre-filtered devices (from CLI selection or auto-discovery)
|
|
37
37
|
* @param {Object} context.options - Test options (timeout, verbose, etc.)
|
|
38
38
|
* @returns {Promise<Array>} Array of test result objects
|
package/cli/tests/test-toggle.js
CHANGED
|
@@ -19,7 +19,7 @@ const metadata = {
|
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Helper function to find all toggle-capable devices
|
|
22
|
-
* @param {Object} manager -
|
|
22
|
+
* @param {Object} manager - ManagerMeross instance
|
|
23
23
|
* @returns {Promise<Array>} Array of toggle devices
|
|
24
24
|
*/
|
|
25
25
|
async function findAllToggleDevices(manager) {
|
|
@@ -40,7 +40,7 @@ async function findAllToggleDevices(manager) {
|
|
|
40
40
|
/**
|
|
41
41
|
* Runs all tests for toggle/switch devices
|
|
42
42
|
* @param {Object} context - Test context object
|
|
43
|
-
* @param {Object} context.manager -
|
|
43
|
+
* @param {Object} context.manager - ManagerMeross instance (already connected)
|
|
44
44
|
* @param {Array<Object>} context.devices - Pre-filtered devices (from CLI selection or auto-discovery)
|
|
45
45
|
* @param {Object} context.options - Test options (timeout, verbose, etc.)
|
|
46
46
|
* @returns {Promise<Array>} Array of test result objects
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "meross-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Command-line interface for controlling Meross smart home devices",
|
|
5
5
|
"author": "Abe Haverkamp",
|
|
6
6
|
"homepage": "https://github.com/Doekse/merossiot#readme",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"chalk": "^4.1.2",
|
|
25
25
|
"commander": "^12.1.0",
|
|
26
26
|
"inquirer": "^8.2.6",
|
|
27
|
-
"meross-iot": "^0.1
|
|
27
|
+
"meross-iot": "^0.2.1",
|
|
28
28
|
"ora": "^5.4.1"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
@@ -50,4 +50,3 @@
|
|
|
50
50
|
"lint:fix": "eslint . --fix"
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
-
|