homebridge-melcloud-control 4.3.14 → 4.3.15-beta.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/package.json +1 -1
- package/src/functions.js +86 -83
- package/src/melcloudhome.js +2 -2
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"displayName": "MELCloud Control",
|
|
3
3
|
"name": "homebridge-melcloud-control",
|
|
4
|
-
"version": "4.3.
|
|
4
|
+
"version": "4.3.15-beta.0",
|
|
5
5
|
"description": "Homebridge plugin to control Mitsubishi Air Conditioner, Heat Pump and Energy Recovery Ventilation.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "grzegorz914",
|
package/src/functions.js
CHANGED
|
@@ -55,132 +55,135 @@ class Functions extends EventEmitter {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
async ensureChromiumInstalled() {
|
|
58
|
-
let chromiumPath =
|
|
58
|
+
let chromiumPath = null;
|
|
59
59
|
|
|
60
60
|
try {
|
|
61
|
-
// Detect OS
|
|
62
|
-
const { stdout: osOut } = await execPromise(
|
|
61
|
+
// --- Detect OS ---
|
|
62
|
+
const { stdout: osOut } = await execPromise("uname -s");
|
|
63
63
|
const osName = osOut.trim();
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
// Detect Architecture
|
|
67
|
-
const { stdout: archOut } = await execPromise('uname -m');
|
|
64
|
+
const { stdout: archOut } = await execPromise("uname -m");
|
|
68
65
|
const arch = archOut.trim();
|
|
69
|
-
if (this.logDebug) this.emit('debug', `Detected architecture: ${arch}`);
|
|
70
66
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
await access('/.dockerenv', fs.constants.F_OK);
|
|
75
|
-
isDocker = true;
|
|
76
|
-
} catch { }
|
|
67
|
+
const isARM = arch.startsWith("arm") || arch.startsWith("aarch64") || arch.startsWith("aarch");
|
|
68
|
+
const isMac = osName === "Darwin";
|
|
69
|
+
const isLinux = osName === "Linux";
|
|
77
70
|
|
|
71
|
+
// --- Detect Docker ---
|
|
72
|
+
let isDocker = false;
|
|
73
|
+
try { await access("/.dockerenv"); isDocker = true; } catch { }
|
|
78
74
|
try {
|
|
79
|
-
const { stdout } = await execPromise(
|
|
80
|
-
if (stdout.includes(
|
|
75
|
+
const { stdout } = await execPromise("cat /proc/1/cgroup || true");
|
|
76
|
+
if (stdout.includes("docker") || stdout.includes("containerd")) isDocker = true;
|
|
81
77
|
} catch { }
|
|
82
|
-
if (isDocker && this.logDebug) this.emit('debug', 'Running inside Docker container');
|
|
83
78
|
|
|
84
|
-
// macOS
|
|
85
|
-
if (
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
return
|
|
79
|
+
// --- macOS ---
|
|
80
|
+
if (isMac) {
|
|
81
|
+
const macCandidates = [
|
|
82
|
+
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
83
|
+
"/Applications/Chromium.app/Contents/MacOS/Chromium"
|
|
84
|
+
];
|
|
85
|
+
for (const p of macCandidates) {
|
|
86
|
+
try { await access(p, fs.constants.X_OK); return p; } catch { }
|
|
92
87
|
}
|
|
88
|
+
return null;
|
|
93
89
|
}
|
|
94
90
|
|
|
95
|
-
// ARM
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
'/usr/bin/chromium'
|
|
91
|
+
// --- ARM / Raspberry Pi ---
|
|
92
|
+
if (isARM && isLinux) {
|
|
93
|
+
const armCandidates = [
|
|
94
|
+
"/usr/bin/chromium-browser",
|
|
95
|
+
"/usr/bin/chromium",
|
|
96
|
+
"/snap/bin/chromium"
|
|
102
97
|
];
|
|
103
98
|
|
|
104
|
-
//
|
|
105
|
-
for (const
|
|
106
|
-
try {
|
|
107
|
-
await access(path, fs.constants.X_OK);
|
|
108
|
-
chromiumPath = path;
|
|
109
|
-
return chromiumPath;
|
|
110
|
-
} catch { }
|
|
99
|
+
// Try existing
|
|
100
|
+
for (const p of armCandidates) {
|
|
101
|
+
try { await access(p, fs.constants.X_OK); return p; } catch { }
|
|
111
102
|
}
|
|
112
103
|
|
|
113
|
-
//
|
|
114
|
-
|
|
115
|
-
await execPromise(
|
|
116
|
-
|
|
117
|
-
try {
|
|
118
|
-
await execPromise('sudo apt-get install -y chromium');
|
|
119
|
-
} catch {
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
104
|
+
// If not in Docker, try apt installation
|
|
105
|
+
if (!isDocker) {
|
|
106
|
+
try { await execPromise("sudo apt-get update -y"); } catch { }
|
|
107
|
+
try { await execPromise("sudo apt-get install -y chromium-browser chromium-codecs-ffmpeg || true"); } catch { }
|
|
108
|
+
try { await execPromise("sudo apt-get install -y chromium || true"); } catch { }
|
|
122
109
|
}
|
|
123
110
|
|
|
124
|
-
//
|
|
125
|
-
for (const
|
|
126
|
-
try {
|
|
127
|
-
await access(path, fs.constants.X_OK);
|
|
128
|
-
chromiumPath = path;
|
|
129
|
-
return chromiumPath;
|
|
130
|
-
} catch { }
|
|
111
|
+
// Retry after installation
|
|
112
|
+
for (const p of armCandidates) {
|
|
113
|
+
try { await access(p, fs.constants.X_OK); return p; } catch { }
|
|
131
114
|
}
|
|
132
115
|
|
|
133
116
|
return null;
|
|
134
117
|
}
|
|
135
118
|
|
|
136
|
-
//
|
|
137
|
-
|
|
138
|
-
|
|
119
|
+
// --- QNAP / Entware ---
|
|
120
|
+
let entwareExists = false;
|
|
121
|
+
try { await access("/opt/bin/opkg", fs.constants.X_OK); entwareExists = true; } catch { }
|
|
122
|
+
|
|
123
|
+
if (entwareExists) {
|
|
139
124
|
try {
|
|
140
|
-
|
|
141
|
-
|
|
125
|
+
await execPromise("/opt/bin/opkg update");
|
|
126
|
+
await execPromise("/opt/bin/opkg install nspr nss libx11 libxcomposite libxdamage libxrandr atk libcups libdrm libgbm alsa-lib");
|
|
127
|
+
process.env.LD_LIBRARY_PATH = `/opt/lib:${process.env.LD_LIBRARY_PATH || ""}`;
|
|
142
128
|
} catch { }
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// --- Synology DSM 7 ---
|
|
132
|
+
const synoCandidates = [
|
|
133
|
+
"/var/packages/Chromium/target/usr/bin/chromium",
|
|
134
|
+
"/usr/local/chromium/bin/chromium"
|
|
135
|
+
];
|
|
136
|
+
for (const p of synoCandidates) {
|
|
137
|
+
try { await access(p, fs.constants.X_OK); return p; } catch { }
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// --- Linux x64 ---
|
|
141
|
+
if (isLinux) {
|
|
142
|
+
const linuxCandidates = [
|
|
143
|
+
"/usr/bin/chromium",
|
|
144
|
+
"/usr/bin/chromium-browser",
|
|
145
|
+
"/usr/bin/google-chrome",
|
|
146
|
+
"/snap/bin/chromium",
|
|
147
|
+
"/usr/local/bin/chromium"
|
|
148
|
+
];
|
|
143
149
|
|
|
144
|
-
// Entware (QNAP)
|
|
145
|
-
let entwareExists = false;
|
|
146
150
|
try {
|
|
147
|
-
await
|
|
148
|
-
|
|
151
|
+
const { stdout } = await execPromise("which chromium || which chromium-browser || which google-chrome || true");
|
|
152
|
+
const found = stdout.trim();
|
|
153
|
+
if (found) return found;
|
|
149
154
|
} catch { }
|
|
150
155
|
|
|
151
|
-
|
|
152
|
-
try {
|
|
153
|
-
await execPromise('/opt/bin/opkg update');
|
|
154
|
-
await execPromise('/opt/bin/opkg install nspr nss libx11 libxcomposite libxdamage libxrandr libatk libatk-bridge libcups libdrm libgbm libasound');
|
|
155
|
-
process.env.LD_LIBRARY_PATH = `/opt/lib:${process.env.LD_LIBRARY_PATH || ''}`;
|
|
156
|
-
} catch { }
|
|
156
|
+
for (const p of linuxCandidates) {
|
|
157
|
+
try { await access(p, fs.constants.X_OK); return p; } catch { }
|
|
157
158
|
}
|
|
158
159
|
|
|
159
|
-
//
|
|
160
|
+
// Docker: try installing chromium inside container (if allowed)
|
|
161
|
+
if (isDocker) {
|
|
162
|
+
try { await execPromise("apt-get update -y && apt-get install -y chromium || true"); } catch { }
|
|
163
|
+
try { await access("/usr/bin/chromium", fs.constants.X_OK); return "/usr/bin/chromium"; } catch { }
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Install missing libraries
|
|
160
167
|
const depCommands = [
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
168
|
+
"apt-get update -y && apt-get install -y libnspr4 libnss3 libx11-6 libxcomposite1 libxdamage1 libxrandr2 libatk1.0-0 libcups2 libdrm2 libgbm1 libasound2 || true",
|
|
169
|
+
"yum install -y nspr nss libX11 libXcomposite libXdamage libXrandr atk cups libdrm libgbm alsa-lib || true",
|
|
170
|
+
"apk add --no-cache nspr nss libx11 libxcomposite libxdamage libxrandr atk cups libdrm libgbm alsa-lib || true"
|
|
164
171
|
];
|
|
165
|
-
|
|
166
172
|
for (const cmd of depCommands) {
|
|
167
|
-
try {
|
|
168
|
-
await execPromise(`sudo ${cmd}`);
|
|
169
|
-
} catch { }
|
|
173
|
+
try { await execPromise(`sudo ${cmd}`); } catch { }
|
|
170
174
|
}
|
|
171
175
|
|
|
172
|
-
|
|
173
|
-
return systemChromium;
|
|
176
|
+
return null;
|
|
174
177
|
}
|
|
175
178
|
|
|
176
|
-
if (this.logDebug) this.emit('debug', `Unsupported OS: ${osName}`);
|
|
177
179
|
return null;
|
|
178
|
-
} catch (
|
|
179
|
-
if (this.logError) this.emit(
|
|
180
|
+
} catch (err) {
|
|
181
|
+
if (this.logError) this.emit("error", `Chromium detection error: ${err.message}`);
|
|
180
182
|
return null;
|
|
181
183
|
}
|
|
182
184
|
}
|
|
183
185
|
|
|
186
|
+
|
|
184
187
|
isValidValue(v) {
|
|
185
188
|
return v !== undefined && v !== null && !(typeof v === 'number' && Number.isNaN(v));
|
|
186
189
|
}
|
package/src/melcloudhome.js
CHANGED
|
@@ -228,7 +228,7 @@ class MelCloudHome extends EventEmitter {
|
|
|
228
228
|
// Get Chromium path
|
|
229
229
|
let chromiumPath = await this.functions.ensureChromiumInstalled();
|
|
230
230
|
|
|
231
|
-
// === Fallback to Puppeteer's
|
|
231
|
+
// === Fallback to Puppeteer's bundled Chromium ===
|
|
232
232
|
if (!chromiumPath) {
|
|
233
233
|
try {
|
|
234
234
|
const puppeteerPath = puppeteer.executablePath();
|
|
@@ -245,7 +245,7 @@ class MelCloudHome extends EventEmitter {
|
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
-
// Verify executable
|
|
248
|
+
// === Verify Chromium executable ===
|
|
249
249
|
try {
|
|
250
250
|
const { stdout } = await execPromise(`"${chromiumPath}" --version`);
|
|
251
251
|
if (this.logDebug) this.emit('debug', `Chromium detected: ${stdout.trim()}`);
|