homebridge-melcloud-control 4.4.1-beta.10 → 4.4.1-beta.12
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 +42 -118
- package/src/melcloudhome.js +10 -33
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"displayName": "MELCloud Control",
|
|
3
3
|
"name": "homebridge-melcloud-control",
|
|
4
|
-
"version": "4.4.1-beta.
|
|
4
|
+
"version": "4.4.1-beta.12",
|
|
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
|
@@ -60,187 +60,111 @@ class Functions extends EventEmitter {
|
|
|
60
60
|
const osName = osOut.trim();
|
|
61
61
|
|
|
62
62
|
const { stdout: archOut } = await execPromise('uname -m');
|
|
63
|
-
|
|
63
|
+
let arch = archOut.trim() || 'unknown';
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
// Normalizacja architektury
|
|
66
|
+
if (arch.startsWith('arm') || arch.startsWith('aarch')) arch = 'arm';
|
|
67
|
+
else if (arch.includes('64')) arch = 'x64';
|
|
68
|
+
else arch = 'x86';
|
|
69
69
|
|
|
70
|
+
const isARM = arch === 'arm';
|
|
70
71
|
const isMac = osName === 'Darwin';
|
|
71
72
|
const isLinux = osName === 'Linux';
|
|
72
|
-
const isQnap =
|
|
73
|
+
const isQnap =
|
|
74
|
+
fs.existsSync('/etc/config/uLinux.conf') ||
|
|
75
|
+
fs.existsSync('/etc/config/qpkg.conf');
|
|
73
76
|
|
|
74
77
|
// Detect Docker
|
|
75
78
|
let isDocker = false;
|
|
76
|
-
try {
|
|
77
|
-
await access('/.dockerenv');
|
|
78
|
-
isDocker = true;
|
|
79
|
-
} catch { }
|
|
80
|
-
|
|
79
|
+
try { await access('/.dockerenv'); isDocker = true; } catch { }
|
|
81
80
|
try {
|
|
82
81
|
const { stdout } = await execPromise('cat /proc/1/cgroup || true');
|
|
83
|
-
if (stdout.includes('docker') || stdout.includes('containerd'))
|
|
84
|
-
isDocker = true;
|
|
85
|
-
}
|
|
82
|
+
if (stdout.includes('docker') || stdout.includes('containerd')) isDocker = true;
|
|
86
83
|
} catch { }
|
|
87
84
|
|
|
85
|
+
const result = { path: null, arch };
|
|
86
|
+
|
|
88
87
|
/* ===================== macOS ===================== */
|
|
89
88
|
if (isMac) {
|
|
90
89
|
const macCandidates = [
|
|
91
90
|
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
|
|
92
91
|
'/Applications/Chromium.app/Contents/MacOS/Chromium'
|
|
93
92
|
];
|
|
94
|
-
|
|
95
93
|
for (const path of macCandidates) {
|
|
96
|
-
try {
|
|
97
|
-
await access(path, fs.constants.X_OK);
|
|
98
|
-
return path;
|
|
99
|
-
} catch { }
|
|
94
|
+
try { await access(path, fs.constants.X_OK); result.path = path; return result; } catch { }
|
|
100
95
|
}
|
|
101
96
|
|
|
102
|
-
//
|
|
103
|
-
try {
|
|
104
|
-
return puppeteer.executablePath();
|
|
105
|
-
} catch {
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
97
|
+
// Fallback do Puppeteer
|
|
98
|
+
try { result.path = puppeteer.executablePath(); return result; } catch { }
|
|
108
99
|
}
|
|
109
100
|
|
|
110
101
|
/* ===================== QNAP ===================== */
|
|
111
102
|
if (isQnap) {
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
];
|
|
116
|
-
|
|
117
|
-
// Check existing Entware Chromium
|
|
118
|
-
for (const path of entwareChromiumCandidates) {
|
|
119
|
-
try {
|
|
120
|
-
await access(path, fs.constants.X_OK);
|
|
121
|
-
return path;
|
|
122
|
-
} catch { }
|
|
103
|
+
const qnapCandidates = ['/opt/bin/chromium', '/opt/bin/chromium-browser'];
|
|
104
|
+
for (const path of qnapCandidates) {
|
|
105
|
+
try { await access(path, fs.constants.X_OK); result.path = path; return result; } catch { }
|
|
123
106
|
}
|
|
124
107
|
|
|
125
|
-
// Try installing via Entware
|
|
126
108
|
try {
|
|
127
109
|
await access('/opt/bin/opkg', fs.constants.X_OK);
|
|
128
|
-
|
|
129
110
|
await execPromise('/opt/bin/opkg update');
|
|
130
|
-
await execPromise(
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
// Ensure Entware libs are visible
|
|
135
|
-
process.env.LD_LIBRARY_PATH =
|
|
136
|
-
`/opt/lib:${process.env.LD_LIBRARY_PATH || ''}`;
|
|
137
|
-
|
|
138
|
-
} catch {
|
|
139
|
-
// opkg missing or install failed
|
|
140
|
-
return null;
|
|
141
|
-
}
|
|
111
|
+
await execPromise('opkg install chromium nspr nss libx11 libxcomposite libxdamage libxrandr atk libcups libdrm libgbm alsa-lib');
|
|
112
|
+
process.env.LD_LIBRARY_PATH = `/opt/lib:${process.env.LD_LIBRARY_PATH || ''}`;
|
|
113
|
+
} catch { }
|
|
142
114
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
try {
|
|
146
|
-
await access(path, fs.constants.X_OK);
|
|
147
|
-
return path;
|
|
148
|
-
} catch { }
|
|
115
|
+
for (const path of qnapCandidates) {
|
|
116
|
+
try { await access(path, fs.constants.X_OK); result.path = path; return result; } catch { }
|
|
149
117
|
}
|
|
150
|
-
|
|
151
|
-
return null;
|
|
152
118
|
}
|
|
153
119
|
|
|
154
|
-
/* ===================== ARM
|
|
120
|
+
/* ===================== Linux ARM ===================== */
|
|
155
121
|
if (isLinux && isARM) {
|
|
156
|
-
const armCandidates = [
|
|
157
|
-
'/usr/bin/chromium-browser',
|
|
158
|
-
'/usr/bin/chromium',
|
|
159
|
-
'/snap/bin/chromium'
|
|
160
|
-
];
|
|
161
|
-
|
|
122
|
+
const armCandidates = ['/usr/bin/chromium-browser', '/usr/bin/chromium', '/snap/bin/chromium'];
|
|
162
123
|
for (const path of armCandidates) {
|
|
163
|
-
try {
|
|
164
|
-
await access(path, fs.constants.X_OK);
|
|
165
|
-
return path;
|
|
166
|
-
} catch { }
|
|
124
|
+
try { await access(path, fs.constants.X_OK); result.path = path; return result; } catch { }
|
|
167
125
|
}
|
|
168
126
|
|
|
169
|
-
// Try auto-install (only if not Docker)
|
|
170
127
|
if (!isDocker) {
|
|
171
128
|
try {
|
|
172
129
|
await execPromise('sudo apt-get update -y');
|
|
173
|
-
await execPromise(
|
|
174
|
-
|
|
175
|
-
);
|
|
130
|
+
await execPromise('sudo apt-get install -y chromium chromium-browser chromium-codecs-ffmpeg || true');
|
|
131
|
+
await execPromise('sudo apt-get install -y libnspr4 libnss3 libx11-6 libxcomposite1 libxdamage1 libxrandr2 libatk1.0-0 libcups2 libdrm2 libgbm1 libasound2 || true');
|
|
176
132
|
} catch { }
|
|
177
133
|
}
|
|
178
134
|
|
|
179
|
-
// Retry after install
|
|
180
135
|
for (const path of armCandidates) {
|
|
181
|
-
try {
|
|
182
|
-
await access(path, fs.constants.X_OK);
|
|
183
|
-
return path;
|
|
184
|
-
} catch { }
|
|
136
|
+
try { await access(path, fs.constants.X_OK); result.path = path; return result; } catch { }
|
|
185
137
|
}
|
|
186
|
-
|
|
187
|
-
// ARM → NO Puppeteer fallback
|
|
188
|
-
return null;
|
|
189
138
|
}
|
|
190
139
|
|
|
191
140
|
/* ===================== Linux x64 ===================== */
|
|
192
141
|
if (isLinux) {
|
|
193
|
-
const linuxCandidates = [
|
|
194
|
-
'/usr/bin/chromium',
|
|
195
|
-
'/usr/bin/chromium-browser',
|
|
196
|
-
'/usr/bin/google-chrome',
|
|
197
|
-
'/snap/bin/chromium',
|
|
198
|
-
'/usr/local/bin/chromium'
|
|
199
|
-
];
|
|
200
|
-
|
|
142
|
+
const linuxCandidates = ['/usr/bin/chromium', '/usr/bin/chromium-browser', '/usr/bin/google-chrome', '/snap/bin/chromium', '/usr/local/bin/chromium'];
|
|
201
143
|
try {
|
|
202
|
-
const { stdout } = await execPromise(
|
|
203
|
-
|
|
204
|
-
);
|
|
205
|
-
if (stdout.trim()) return stdout.trim();
|
|
144
|
+
const { stdout } = await execPromise('which chromium || which chromium-browser || which google-chrome || true');
|
|
145
|
+
if (stdout.trim()) { result.path = stdout.trim(); return result; }
|
|
206
146
|
} catch { }
|
|
207
147
|
|
|
208
148
|
for (const path of linuxCandidates) {
|
|
209
|
-
try {
|
|
210
|
-
await access(path, fs.constants.X_OK);
|
|
211
|
-
return path;
|
|
212
|
-
} catch { }
|
|
149
|
+
try { await access(path, fs.constants.X_OK); result.path = path; return result; } catch { }
|
|
213
150
|
}
|
|
214
151
|
|
|
215
|
-
// Docker x64 → try install
|
|
216
152
|
if (isDocker) {
|
|
217
|
-
try {
|
|
218
|
-
await execPromise(
|
|
219
|
-
'apt-get update -y && apt-get install -y chromium || true'
|
|
220
|
-
);
|
|
221
|
-
await access('/usr/bin/chromium', fs.constants.X_OK);
|
|
222
|
-
return '/usr/bin/chromium';
|
|
223
|
-
} catch { }
|
|
153
|
+
try { await execPromise('apt-get update -y && apt-get install -y chromium || true'); await access('/usr/bin/chromium', fs.constants.X_OK); result.path = '/usr/bin/chromium'; return result; } catch { }
|
|
224
154
|
}
|
|
225
155
|
|
|
226
|
-
//
|
|
227
|
-
try {
|
|
228
|
-
return puppeteer.executablePath();
|
|
229
|
-
} catch {
|
|
230
|
-
return null;
|
|
231
|
-
}
|
|
156
|
+
// Fallback Puppeteer tylko jeśli nie ARM/QNAP
|
|
157
|
+
try { result.path = puppeteer.executablePath(); return result; } catch { }
|
|
232
158
|
}
|
|
233
159
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
this.emit('error', `Chromium detection error: ${error.message}`);
|
|
239
|
-
}
|
|
240
|
-
return null;
|
|
160
|
+
return result;
|
|
161
|
+
} catch (err) {
|
|
162
|
+
if (this.logError) this.emit('error', `Chromium detection error: ${err.message}`);
|
|
163
|
+
return { path: null, arch: 'unknown' };
|
|
241
164
|
}
|
|
242
165
|
}
|
|
243
166
|
|
|
167
|
+
|
|
244
168
|
isValidValue(v) {
|
|
245
169
|
return v !== undefined && v !== null && !(typeof v === 'number' && Number.isNaN(v));
|
|
246
170
|
}
|
package/src/melcloudhome.js
CHANGED
|
@@ -224,44 +224,21 @@ class MelCloudHome extends EventEmitter {
|
|
|
224
224
|
const accountInfo = { State: false, Info: '', Account: {}, UseFahrenheit: false };
|
|
225
225
|
|
|
226
226
|
// Get Chromium path from resolver
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
// Detect architecture again (cheap & explicit)
|
|
230
|
-
const { stdout: archOut } = await execPromise('uname -m');
|
|
231
|
-
const arch = archOut.trim();
|
|
232
|
-
const isARM =
|
|
233
|
-
arch.startsWith('arm') ||
|
|
234
|
-
arch.startsWith('aarch64') ||
|
|
235
|
-
arch.startsWith('aarch');
|
|
236
|
-
|
|
237
|
-
// Detect QNAP
|
|
238
|
-
const isQnap =
|
|
239
|
-
fs.existsSync('/etc/config/uLinux.conf') ||
|
|
240
|
-
fs.existsSync('/etc/config/qpkg.conf');
|
|
241
|
-
|
|
242
|
-
// Conditional Puppeteer fallback
|
|
243
|
-
if (!chromiumPath) {
|
|
244
|
-
if (!isARM && !isQnap) {
|
|
245
|
-
try {
|
|
246
|
-
const puppeteerPath = puppeteer.executablePath();
|
|
247
|
-
if (!puppeteerPath) {
|
|
248
|
-
accountInfo.Info = 'Puppeteer returned empty Chromium path';
|
|
249
|
-
return accountInfo;
|
|
250
|
-
}
|
|
227
|
+
const chromiumInfo = await this.functions.ensureChromiumInstalled();
|
|
228
|
+
let chromiumPath = chromiumInfo.path;
|
|
251
229
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
230
|
+
// zawsze próbuj Puppeteer jeśli brak binarki
|
|
231
|
+
if (!chromiumPath) {
|
|
232
|
+
try {
|
|
233
|
+
chromiumPath = puppeteer.executablePath();
|
|
234
|
+
if (this.logDebug) this.emit('debug', `Using Puppeteer Chromium (${chromiumInfo.arch}) at ${chromiumPath}`);
|
|
235
|
+
} catch (error) {
|
|
236
|
+
accountInfo.Info =
|
|
237
|
+
`No Chromium available for architecture ${chromiumInfo.arch}`;
|
|
260
238
|
return accountInfo;
|
|
261
239
|
}
|
|
262
240
|
}
|
|
263
241
|
|
|
264
|
-
|
|
265
242
|
// Verify Chromium executable
|
|
266
243
|
try {
|
|
267
244
|
const { stdout } = await execPromise(`"${chromiumPath}" --version`);
|