homebridge-melcloud-control 4.1.2-beta.32 → 4.1.2-beta.34
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/config.schema.json +32 -37
- package/homebridge-ui/public/index.html +38 -35
- package/package.json +1 -1
- package/src/functions.js +26 -3
package/config.schema.json
CHANGED
|
@@ -2228,46 +2228,41 @@
|
|
|
2228
2228
|
"expanded": false,
|
|
2229
2229
|
"items": [
|
|
2230
2230
|
{
|
|
2231
|
-
"
|
|
2232
|
-
"type": "
|
|
2233
|
-
"
|
|
2234
|
-
"expandable": true,
|
|
2235
|
-
"expanded": false,
|
|
2236
|
-
"items": [
|
|
2237
|
-
"accounts[].ataDevices[].temperatureSensor",
|
|
2238
|
-
"accounts[].ataDevices[].temperatureOutdoorSensor"
|
|
2239
|
-
]
|
|
2240
|
-
},
|
|
2241
|
-
{
|
|
2242
|
-
"title": "System",
|
|
2243
|
-
"type": "section",
|
|
2244
|
-
"description": "Section for setup system sensors",
|
|
2245
|
-
"expandable": true,
|
|
2246
|
-
"expanded": false,
|
|
2247
|
-
"items": [
|
|
2248
|
-
"accounts[].ataDevices[].frostProtectionSensor",
|
|
2249
|
-
"accounts[].ataDevices[].overheatProtectionSensor",
|
|
2250
|
-
"accounts[].ataDevices[].holidayModeSensor",
|
|
2251
|
-
"accounts[].ataDevices[].scheduleSensor",
|
|
2252
|
-
"accounts[].ataDevices[].errorSensor"
|
|
2253
|
-
]
|
|
2254
|
-
},
|
|
2255
|
-
{
|
|
2256
|
-
"title": "Custom",
|
|
2257
|
-
"type": "section",
|
|
2258
|
-
"description": "Section for creating custom buttons/sensors",
|
|
2259
|
-
"expandable": true,
|
|
2260
|
-
"expanded": false,
|
|
2231
|
+
"key": "accounts[].ataDevices[]",
|
|
2232
|
+
"type": "tabarray",
|
|
2233
|
+
"title": "{{ value.name }}",
|
|
2261
2234
|
"items": [
|
|
2262
2235
|
{
|
|
2263
|
-
"
|
|
2264
|
-
"
|
|
2265
|
-
|
|
2236
|
+
"title": "Temperature",
|
|
2237
|
+
"items": [
|
|
2238
|
+
"accounts[].ataDevices[].temperatureSensor",
|
|
2239
|
+
"accounts[].ataDevices[].temperatureOutdoorSensor"
|
|
2240
|
+
]
|
|
2241
|
+
},
|
|
2242
|
+
{
|
|
2243
|
+
"title": "System",
|
|
2244
|
+
"items": [
|
|
2245
|
+
"accounts[].ataDevices[].frostProtectionSensor",
|
|
2246
|
+
"accounts[].ataDevices[].overheatProtectionSensor",
|
|
2247
|
+
"accounts[].ataDevices[].holidayModeSensor",
|
|
2248
|
+
"accounts[].ataDevices[].scheduleSensor",
|
|
2249
|
+
"accounts[].ataDevices[].errorSensor"
|
|
2250
|
+
]
|
|
2251
|
+
},
|
|
2252
|
+
{
|
|
2253
|
+
"title": "Custom",
|
|
2266
2254
|
"items": [
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2255
|
+
{
|
|
2256
|
+
"key": "accounts[].ataDevices[].buttonsSensors",
|
|
2257
|
+
"type": "tabarray",
|
|
2258
|
+
"title": "{{ value.name || 'button/sensor' }}",
|
|
2259
|
+
"items": [
|
|
2260
|
+
"accounts[].ataDevices[].buttonsSensors[].displayType",
|
|
2261
|
+
"accounts[].ataDevices[].buttonsSensors[].mode",
|
|
2262
|
+
"accounts[].ataDevices[].buttonsSensors[].name",
|
|
2263
|
+
"accounts[].ataDevices[].buttonsSensors[].namePrefix"
|
|
2264
|
+
]
|
|
2265
|
+
}
|
|
2271
2266
|
]
|
|
2272
2267
|
}
|
|
2273
2268
|
]
|
|
@@ -266,45 +266,48 @@
|
|
|
266
266
|
buttonsSensors: []
|
|
267
267
|
};
|
|
268
268
|
|
|
269
|
-
if (!devicesInConfig.some(dev => String(dev.id) ===
|
|
269
|
+
if (!devicesInConfig.some(dev => String(dev.id) === device.DeviceID)) {
|
|
270
270
|
devicesInConfig.push(deviceObj);
|
|
271
271
|
newArr.push(deviceObj);
|
|
272
272
|
}
|
|
273
273
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
deviceInConfig.presets
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
deviceInConfig.schedules
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
274
|
+
const deviceInConfig = devicesInConfig.find(dev => String(dev.id) === device.DeviceID);
|
|
275
|
+
if (deviceInConfig) {
|
|
276
|
+
if (account.type === 'melcloud') {
|
|
277
|
+
const presets = device.Presets || [];
|
|
278
|
+
presets.forEach((preset, index) => {
|
|
279
|
+
const presetObj = {
|
|
280
|
+
id: preset.ID,
|
|
281
|
+
displayType: 0,
|
|
282
|
+
name: preset.NumberDescription || `Preset ${index}`,
|
|
283
|
+
namePrefix: false
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
const presetsInConfig = deviceInConfig.presets || [];
|
|
287
|
+
if (!presetsInConfig.some(pres => String(pres.id) === preset.ID)) {
|
|
288
|
+
presetsInConfig.push(presetObj);
|
|
289
|
+
newPresets.push(presetObj);
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (account.type === 'melcloudhome') {
|
|
295
|
+
const schedules = device.Schedule || [];
|
|
296
|
+
schedules.forEach((schedule, index) => {
|
|
297
|
+
const scheduleObj = {
|
|
298
|
+
id: schedule.Id,
|
|
299
|
+
displayType: 0,
|
|
300
|
+
name: `Schedule ${index}`,
|
|
301
|
+
namePrefix: false
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
const schedulesInConfig = deviceInConfig.schedules || [];
|
|
305
|
+
if (!schedulesInConfig.some(sched => String(sched.id) === schedule.Id)) {
|
|
306
|
+
schedulesInConfig.push(scheduleObj);
|
|
307
|
+
newPresets.push(scheduleObj);
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
}
|
|
308
311
|
}
|
|
309
312
|
});
|
|
310
313
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"displayName": "MELCloud Control",
|
|
3
3
|
"name": "homebridge-melcloud-control",
|
|
4
|
-
"version": "4.1.2-beta.
|
|
4
|
+
"version": "4.1.2-beta.34",
|
|
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
|
@@ -113,7 +113,7 @@ class Functions extends EventEmitter {
|
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
// === Linux (x64, Docker, etc.) ===
|
|
116
|
+
// === Linux (x64, Docker, QNAP etc.) ===
|
|
117
117
|
if (osName === 'Linux') {
|
|
118
118
|
try {
|
|
119
119
|
// --- Try detect common Chromium binaries ---
|
|
@@ -127,6 +127,29 @@ class Functions extends EventEmitter {
|
|
|
127
127
|
|
|
128
128
|
if (this.logWarn) this.emit('warn', 'Chromium not found. Attempting installation...');
|
|
129
129
|
|
|
130
|
+
// --- Detect Entware (QNAP) ---
|
|
131
|
+
let entwareExists = false;
|
|
132
|
+
try {
|
|
133
|
+
await access('/opt/bin/opkg', fs.constants.X_OK);
|
|
134
|
+
entwareExists = true;
|
|
135
|
+
} catch { }
|
|
136
|
+
|
|
137
|
+
if (entwareExists) {
|
|
138
|
+
try {
|
|
139
|
+
if (this.logDebug) this.emit('debug', 'Detected Entware. Attempting installation via opkg...');
|
|
140
|
+
await execPromise('/opt/bin/opkg update');
|
|
141
|
+
await execPromise('/opt/bin/opkg install chromium');
|
|
142
|
+
const { stdout: checkOut } = await execPromise('which chromium || which chromium-browser || true');
|
|
143
|
+
chromiumPath = checkOut.trim() || '/opt/bin/chromium';
|
|
144
|
+
if (chromiumPath) {
|
|
145
|
+
if (this.logDebug) this.emit('debug', `Chromium installed successfully via Entware at ${chromiumPath}`);
|
|
146
|
+
return chromiumPath;
|
|
147
|
+
}
|
|
148
|
+
} catch (error) {
|
|
149
|
+
if (this.logDebug) this.emit('debug', `Entware installation failed: ${error.message}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
130
153
|
// --- Try install (Docker-optimized first) ---
|
|
131
154
|
const installCommands = [
|
|
132
155
|
'apt-get update -y && apt-get install -y chromium chromium-browser chromium-codecs-ffmpeg',
|
|
@@ -138,7 +161,6 @@ class Functions extends EventEmitter {
|
|
|
138
161
|
try {
|
|
139
162
|
if (this.logDebug) this.emit('debug', `Trying installation: ${cmd}`);
|
|
140
163
|
await execPromise(`sudo ${cmd}`);
|
|
141
|
-
// Check for binary after install
|
|
142
164
|
const { stdout: checkOut } = await execPromise('which chromium || which chromium-browser || true');
|
|
143
165
|
chromiumPath = checkOut.trim() || '/usr/bin/chromium';
|
|
144
166
|
if (chromiumPath) {
|
|
@@ -151,7 +173,6 @@ class Functions extends EventEmitter {
|
|
|
151
173
|
}
|
|
152
174
|
|
|
153
175
|
if (isDocker) {
|
|
154
|
-
// Docker fallback specific
|
|
155
176
|
try {
|
|
156
177
|
await execPromise('sudo apt-get update -y && sudo apt-get install -y chromium');
|
|
157
178
|
await access('/usr/bin/chromium', fs.constants.X_OK);
|
|
@@ -172,5 +193,7 @@ class Functions extends EventEmitter {
|
|
|
172
193
|
return null;
|
|
173
194
|
}
|
|
174
195
|
}
|
|
196
|
+
|
|
197
|
+
|
|
175
198
|
}
|
|
176
199
|
export default Functions
|