homebridge-melcloud-control 4.4.1-beta.11 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "MELCloud Control",
3
3
  "name": "homebridge-melcloud-control",
4
- "version": "4.4.1-beta.11",
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
- const arch = archOut.trim();
63
+ let arch = archOut.trim() || 'unknown';
64
64
 
65
- const isARM =
66
- arch.startsWith('arm') ||
67
- arch.startsWith('aarch64') ||
68
- arch.startsWith('aarch');
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 = fs.existsSync('/etc/config/uLinux.conf') || fs.existsSync('/etc/config/qpkg.conf');
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
- // macOS Puppeteer fallback is OK
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 entwareChromiumCandidates = [
113
- '/opt/bin/chromium',
114
- '/opt/bin/chromium-browser'
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
- '/opt/bin/opkg install chromium nspr nss libx11 libxcomposite libxdamage libxrandr atk libcups libdrm libgbm alsa-lib'
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
- // Retry after install
144
- for (const path of entwareChromiumCandidates) {
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 Linux ===================== */
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
- 'sudo apt-get install -y chromium chromium-browser chromium-codecs-ffmpeg || true'
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
- 'which chromium || which chromium-browser || which google-chrome || true'
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
- // Linux x64 Puppeteer fallback OK
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
- return null;
236
- } catch (error) {
237
- if (this.logError) {
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
  }
@@ -1,4 +1,3 @@
1
- import fs from 'fs';
2
1
  import axios from 'axios';
3
2
  import WebSocket from 'ws';
4
3
  import { exec } from 'child_process';
@@ -225,44 +224,21 @@ class MelCloudHome extends EventEmitter {
225
224
  const accountInfo = { State: false, Info: '', Account: {}, UseFahrenheit: false };
226
225
 
227
226
  // Get Chromium path from resolver
228
- let chromiumPath = await this.functions.ensureChromiumInstalled();
229
-
230
- // Detect architecture again (cheap & explicit)
231
- const { stdout: archOut } = await execPromise('uname -m');
232
- const arch = archOut.trim();
233
- const isARM =
234
- arch.startsWith('arm') ||
235
- arch.startsWith('aarch64') ||
236
- arch.startsWith('aarch');
237
-
238
- // Detect QNAP
239
- const isQnap =
240
- fs.existsSync('/etc/config/uLinux.conf') ||
241
- fs.existsSync('/etc/config/qpkg.conf');
242
-
243
- // Conditional Puppeteer fallback
244
- if (!chromiumPath) {
245
- if (!isARM && !isQnap) {
246
- try {
247
- const puppeteerPath = puppeteer.executablePath();
248
- if (!puppeteerPath) {
249
- accountInfo.Info = 'Puppeteer returned empty Chromium path';
250
- return accountInfo;
251
- }
227
+ const chromiumInfo = await this.functions.ensureChromiumInstalled();
228
+ let chromiumPath = chromiumInfo.path;
252
229
 
253
- chromiumPath = puppeteerPath;
254
- if (this.logDebug) this.emit('debug', `Using Puppeteer bundled Chromium at ${chromiumPath}`);
255
- } catch (error) {
256
- accountInfo.Info = `Failed to get Puppeteer Chromium path: ${error.message}`;
257
- return accountInfo;
258
- }
259
- } else {
260
- accountInfo.Info = 'Chromium not available for this platform. Install system Chromium.';
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}`;
261
238
  return accountInfo;
262
239
  }
263
240
  }
264
241
 
265
-
266
242
  // Verify Chromium executable
267
243
  try {
268
244
  const { stdout } = await execPromise(`"${chromiumPath}" --version`);