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.
Files changed (72) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/LICENSE +21 -0
  3. package/README.md +110 -0
  4. package/cli/commands/control/execute.js +23 -0
  5. package/cli/commands/control/index.js +12 -0
  6. package/cli/commands/control/menu.js +193 -0
  7. package/cli/commands/control/params/generic.js +229 -0
  8. package/cli/commands/control/params/index.js +56 -0
  9. package/cli/commands/control/params/light.js +188 -0
  10. package/cli/commands/control/params/thermostat.js +166 -0
  11. package/cli/commands/control/params/timer.js +242 -0
  12. package/cli/commands/control/params/trigger.js +206 -0
  13. package/cli/commands/dump.js +35 -0
  14. package/cli/commands/index.js +34 -0
  15. package/cli/commands/info.js +221 -0
  16. package/cli/commands/list.js +112 -0
  17. package/cli/commands/mqtt.js +187 -0
  18. package/cli/commands/sniffer/device-sniffer.js +217 -0
  19. package/cli/commands/sniffer/fake-app.js +233 -0
  20. package/cli/commands/sniffer/index.js +7 -0
  21. package/cli/commands/sniffer/message-queue.js +65 -0
  22. package/cli/commands/sniffer/sniffer-menu.js +676 -0
  23. package/cli/commands/stats.js +90 -0
  24. package/cli/commands/status/device-status.js +1403 -0
  25. package/cli/commands/status/hub-status.js +72 -0
  26. package/cli/commands/status/index.js +50 -0
  27. package/cli/commands/status/subdevices/hub-smoke-detector.js +82 -0
  28. package/cli/commands/status/subdevices/hub-temp-hum-sensor.js +43 -0
  29. package/cli/commands/status/subdevices/hub-thermostat-valve.js +83 -0
  30. package/cli/commands/status/subdevices/hub-water-leak-sensor.js +27 -0
  31. package/cli/commands/status/subdevices/index.js +23 -0
  32. package/cli/commands/test/index.js +185 -0
  33. package/cli/config/users.js +108 -0
  34. package/cli/control-registry.js +875 -0
  35. package/cli/helpers/client.js +89 -0
  36. package/cli/helpers/meross.js +106 -0
  37. package/cli/menu/index.js +10 -0
  38. package/cli/menu/main.js +648 -0
  39. package/cli/menu/settings.js +789 -0
  40. package/cli/meross-cli.js +547 -0
  41. package/cli/tests/README.md +365 -0
  42. package/cli/tests/test-alarm.js +144 -0
  43. package/cli/tests/test-child-lock.js +248 -0
  44. package/cli/tests/test-config.js +133 -0
  45. package/cli/tests/test-control.js +189 -0
  46. package/cli/tests/test-diffuser.js +505 -0
  47. package/cli/tests/test-dnd.js +246 -0
  48. package/cli/tests/test-electricity.js +209 -0
  49. package/cli/tests/test-encryption.js +281 -0
  50. package/cli/tests/test-garage.js +259 -0
  51. package/cli/tests/test-helper.js +313 -0
  52. package/cli/tests/test-hub-mts100.js +355 -0
  53. package/cli/tests/test-hub-sensors.js +489 -0
  54. package/cli/tests/test-light.js +253 -0
  55. package/cli/tests/test-presence.js +497 -0
  56. package/cli/tests/test-registry.js +419 -0
  57. package/cli/tests/test-roller-shutter.js +628 -0
  58. package/cli/tests/test-runner.js +415 -0
  59. package/cli/tests/test-runtime.js +234 -0
  60. package/cli/tests/test-screen.js +133 -0
  61. package/cli/tests/test-sensor-history.js +146 -0
  62. package/cli/tests/test-smoke-config.js +138 -0
  63. package/cli/tests/test-spray.js +131 -0
  64. package/cli/tests/test-temp-unit.js +133 -0
  65. package/cli/tests/test-template.js +238 -0
  66. package/cli/tests/test-thermostat.js +919 -0
  67. package/cli/tests/test-timer.js +372 -0
  68. package/cli/tests/test-toggle.js +342 -0
  69. package/cli/tests/test-trigger.js +279 -0
  70. package/cli/utils/display.js +86 -0
  71. package/cli/utils/terminal.js +137 -0
  72. package/package.json +53 -0
@@ -0,0 +1,86 @@
1
+ 'use strict';
2
+
3
+ const packageJson = require('../../package.json');
4
+
5
+ function getRepoUrl() {
6
+ if (packageJson.repository && packageJson.repository.url) {
7
+ return packageJson.repository.url.replace(/^git\+/, '').replace(/\.git$/, '');
8
+ }
9
+ return null;
10
+ }
11
+
12
+ const LOGO_ASCII = `
13
+
14
+
15
+ *********** *********** ************ ****** ************ ********* *********
16
+ ************** ************ **************** ******** **************** ************* *************
17
+ ***** ***** * ***** ****** ******* ****** ****** ****** ****** ****** ****** ******
18
+ **** ***** ***** ***** ******** ***** ***** ***** **** ** **** ****
19
+ **** ***** ***** ***** ******** **** **** ***** ********* *********
20
+ **** ***** ***** ***** ******** ***** **** ***** ************ ************
21
+ **** ***** ***** ************ ***** ***** **** ***** ********* **********
22
+ **** ***** ***** ******** ***** ***** ***** ***** ***** * ****
23
+ **** ***** ***** ******** ******* ***** ******** ******* ***** ***** ***** *****
24
+ **** ***** ***** ************** ***** ************** ************* *************
25
+ **** ***** ***** ********** **** ********** *********** ***********
26
+
27
+
28
+ `;
29
+
30
+ function printLogo(showVersion = true, context = 'help') {
31
+ console.log(LOGO_ASCII);
32
+ const repoUrl = getRepoUrl();
33
+
34
+ if (showVersion) {
35
+ console.log(`Welcome to the Meross Cloud CLI Tool v${packageJson.version}`);
36
+ if (repoUrl) {
37
+ console.log(`${repoUrl}`);
38
+ }
39
+ console.log('');
40
+ }
41
+
42
+ if (context === 'help') {
43
+ console.log(' Control and manage your Meross smart home devices from the command line.');
44
+ if (repoUrl) {
45
+ console.log(` Documentation: ${repoUrl}`);
46
+ }
47
+ console.log(' Use \'meross-cli help\' to see available commands and options.\n');
48
+ } else if (context === 'version') {
49
+ console.log('');
50
+ }
51
+ }
52
+
53
+ function printVersion() {
54
+ console.log(`meross-cli v${packageJson.version}`);
55
+ const repoUrl = getRepoUrl();
56
+ if (repoUrl) {
57
+ console.log(`Repository: ${repoUrl}`);
58
+ }
59
+ if (packageJson.license) {
60
+ console.log(`License: ${packageJson.license}`);
61
+ }
62
+ }
63
+
64
+ function formatDevice(device) {
65
+ const status = device.deviceConnected ? 'connected' : 'disconnected';
66
+ const onlineStatus = device.isOnline ? 'online' : 'offline';
67
+
68
+ return {
69
+ uuid: device.uuid || 'unknown',
70
+ name: device.name || 'Unknown',
71
+ type: device.deviceType || 'unknown',
72
+ status,
73
+ online: onlineStatus,
74
+ firmware: device.firmwareVersion || 'unknown',
75
+ hardware: device.hardwareVersion || 'unknown'
76
+ };
77
+ }
78
+
79
+ module.exports = {
80
+ LOGO_ASCII,
81
+ getRepoUrl,
82
+ printLogo,
83
+ printVersion,
84
+ formatDevice
85
+ };
86
+
@@ -0,0 +1,137 @@
1
+ 'use strict';
2
+
3
+ const chalk = require('chalk');
4
+ const inquirer = require('inquirer');
5
+ const readline = require('readline');
6
+ const packageJson = require('../../package.json');
7
+ const { LOGO_ASCII, getRepoUrl } = require('./display');
8
+
9
+ const LOGO_HEIGHT = 21;
10
+ const SIMPLE_HEADER_HEIGHT = 5;
11
+ const CONTENT_START_LINE = LOGO_HEIGHT + 1;
12
+ const SIMPLE_CONTENT_START_LINE = SIMPLE_HEADER_HEIGHT + 1;
13
+
14
+ function clearScreen() {
15
+ process.stdout.write('\x1b[2J');
16
+ process.stdout.write('\x1b[H');
17
+ }
18
+
19
+ function moveCursorToTop() {
20
+ process.stdout.write('\x1b[H');
21
+ }
22
+
23
+ function moveCursorToLine(line) {
24
+ process.stdout.write(`\x1b[${line};1H`);
25
+ }
26
+
27
+ function renderLogoAtTop(context = 'menu', currentUser = null, deviceCount = null) {
28
+ moveCursorToTop();
29
+
30
+ process.stdout.write(LOGO_ASCII);
31
+ process.stdout.write(`Meross Cloud CLI Tool v${packageJson.version}\n`);
32
+ const repoUrl = getRepoUrl();
33
+ if (repoUrl) {
34
+ process.stdout.write(`${repoUrl}\n`);
35
+ }
36
+ process.stdout.write('\n');
37
+
38
+ if (context === 'menu') {
39
+ if (currentUser) {
40
+ process.stdout.write(' Welcome to the Meross IoT CLI tool\n');
41
+ process.stdout.write(` Logged in as: ${chalk.cyan(currentUser)}\n`);
42
+ const count = deviceCount !== null ? deviceCount : 0;
43
+ const deviceText = count === 1 ? 'device' : 'devices';
44
+ process.stdout.write(` Connected to ${chalk.green(count)} ${deviceText}\n`);
45
+ } else {
46
+ process.stdout.write('Welcome to the Meross IoT CLI tool. Please log in with your Meross account to continue.\n');
47
+ }
48
+ }
49
+
50
+ moveCursorToLine(CONTENT_START_LINE);
51
+ }
52
+
53
+ function renderSimpleHeader(currentUser = null, deviceCount = null) {
54
+ moveCursorToTop();
55
+
56
+ const width = 80;
57
+ const versionText = `Meross Cloud CLI Tool v${packageJson.version}`;
58
+ const versionPadding = Math.floor((width - versionText.length) / 2);
59
+
60
+ process.stdout.write(`╔${'═'.repeat(width - 2)}╗\n`);
61
+ process.stdout.write(`║${' '.repeat(versionPadding - 1)}${versionText}${' '.repeat(width - versionPadding - versionText.length - 1)}║\n`);
62
+ process.stdout.write(`╠${'═'.repeat(width - 2)}╣\n`);
63
+
64
+ if (currentUser) {
65
+ const count = deviceCount !== null ? deviceCount : 0;
66
+ const deviceText = count === 1 ? 'device' : 'devices';
67
+ const userText = `Logged in as: ${currentUser}`;
68
+ const deviceTextPlain = `Connected: ${count} ${deviceText}`;
69
+ const userLine = `Logged in as: ${chalk.cyan(currentUser)}`;
70
+ const deviceLine = `Connected: ${chalk.green(count)} ${deviceText}`;
71
+
72
+ const totalPlainLength = userText.length + deviceTextPlain.length;
73
+ const spacing = Math.max(1, width - totalPlainLength - 6);
74
+
75
+ process.stdout.write(`║ ${userLine}${' '.repeat(spacing)}${deviceLine} ║\n`);
76
+ } else {
77
+ const notLoggedInText = 'Not logged in';
78
+ const padding = width - notLoggedInText.length - 4;
79
+ process.stdout.write(`║ ${chalk.yellow(notLoggedInText)}${' '.repeat(padding)}║\n`);
80
+ }
81
+
82
+ process.stdout.write(`╚${'═'.repeat(width - 2)}╝\n`);
83
+
84
+ moveCursorToLine(SIMPLE_CONTENT_START_LINE);
85
+ }
86
+
87
+ function clearMenuArea(startLine = 5) {
88
+ for (let i = startLine; i < process.stdout.rows || i < 30; i++) {
89
+ process.stdout.write(`\x1b[${i};1H\x1b[K`);
90
+ }
91
+ process.stdout.write(`\x1b[${startLine};1H`);
92
+ }
93
+
94
+ function createRL() {
95
+ return readline.createInterface({
96
+ input: process.stdin,
97
+ output: process.stdout
98
+ });
99
+ }
100
+
101
+ async function question(rl, query) {
102
+ // For backward compatibility, use inquirer for better UX
103
+ const result = await inquirer.prompt([{
104
+ type: 'input',
105
+ name: 'value',
106
+ message: query.replace(/:\s*$/, '')
107
+ }]);
108
+ return result.value;
109
+ }
110
+
111
+ async function promptForPassword(rl, prompt = 'Password: ') {
112
+ // Use inquirer for password input with better UX
113
+ const result = await inquirer.prompt([{
114
+ type: 'password',
115
+ name: 'password',
116
+ message: prompt.replace(/:\s*$/, ''),
117
+ mask: '*'
118
+ }]);
119
+ return result.password;
120
+ }
121
+
122
+ module.exports = {
123
+ LOGO_HEIGHT,
124
+ SIMPLE_HEADER_HEIGHT,
125
+ CONTENT_START_LINE,
126
+ SIMPLE_CONTENT_START_LINE,
127
+ clearScreen,
128
+ moveCursorToTop,
129
+ moveCursorToLine,
130
+ renderLogoAtTop,
131
+ renderSimpleHeader,
132
+ clearMenuArea,
133
+ createRL,
134
+ question,
135
+ promptForPassword
136
+ };
137
+
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "meross-cli",
3
+ "version": "0.1.0",
4
+ "description": "Command-line interface for controlling Meross smart home devices",
5
+ "author": "Abe Haverkamp",
6
+ "homepage": "https://github.com/Doekse/merossiot#readme",
7
+ "license": "MIT",
8
+ "keywords": [
9
+ "meross",
10
+ "iot",
11
+ "smart-home",
12
+ "cli",
13
+ "command-line"
14
+ ],
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/Doekse/merossiot"
18
+ },
19
+ "engines": {
20
+ "node": ">=18"
21
+ },
22
+ "dependencies": {
23
+ "archiver": "^7.0.1",
24
+ "chalk": "^4.1.2",
25
+ "commander": "^12.1.0",
26
+ "inquirer": "^8.2.6",
27
+ "meross-iot": "^0.1.0",
28
+ "ora": "^5.4.1"
29
+ },
30
+ "devDependencies": {
31
+ "eslint": "^9.39.1"
32
+ },
33
+ "bugs": {
34
+ "url": "https://github.com/Doekse/merossiot/issues"
35
+ },
36
+ "bin": {
37
+ "meross-cli": "./cli/meross-cli.js"
38
+ },
39
+ "files": [
40
+ "cli/",
41
+ "README.md",
42
+ "LICENSE",
43
+ "CHANGELOG.md"
44
+ ],
45
+ "scripts": {
46
+ "start": "node cli/meross-cli.js",
47
+ "cli": "node cli/meross-cli.js",
48
+ "publish:npm": "npm publish --access public",
49
+ "lint": "eslint .",
50
+ "lint:fix": "eslint . --fix"
51
+ }
52
+ }
53
+