homebridge-melcloud-control 4.0.0-beta.52 → 4.0.0-beta.521

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.
@@ -77,8 +77,8 @@
77
77
  </div>
78
78
 
79
79
  <div class="mb-2">
80
- <label for="displayType" class="form-label">Account Type</label>
81
- <select id="displayType" name="displayType" class="form-control">
80
+ <label for="accountType" class="form-label">Account Type</label>
81
+ <select id="accountType" name="accountType" class="form-control">
82
82
  <option value="disabled">None/Disabled</option>
83
83
  <option value="melcloud">MELCloud</option>
84
84
  <option value="melcloudhome">MELCloud Home</option>
@@ -86,17 +86,18 @@
86
86
  </div>
87
87
 
88
88
  <div class="text-center">
89
- <button id="logIn" type="button" class="btn btn-secondary">Log In</button>
89
+ <button id="logIn" type="button" class="btn btn-secondary">Connect to MELCloud</button>
90
90
  <button id="configButton" type="button" class="btn btn-secondary"><i class="fas fa-gear"></i></button>
91
91
  </div>
92
92
  </form>
93
- <div id="accountButton" class="text-center mt-2"></div>
93
+ <div id="accountButton" class="d-flex flex-wrap justify-content-center gap-1 mt-3"></div>
94
94
  </div>
95
95
  </div>
96
96
 
97
97
  <script>
98
98
  (async () => {
99
99
  const pluginConfig = await homebridge.getPluginConfig();
100
+
100
101
  if (!pluginConfig.length) {
101
102
  pluginConfig.push({});
102
103
  await homebridge.updatePluginConfig(pluginConfig);
@@ -104,54 +105,79 @@
104
105
  return;
105
106
  }
106
107
 
107
- this.deviceIndex = 0;
108
-
109
- const accountsCount = pluginConfig[0].accounts.length;
110
- for (let i = 0; i < accountsCount; i++) {
108
+ this.accountIndex = 0;
109
+ const accounts = pluginConfig[0].accounts || [];
110
+ const accountsCount = accounts.length;
111
+
112
+ const container = document.getElementById("accountButton");
113
+ container.style.display = 'flex';
114
+ container.style.flexWrap = 'wrap';
115
+ container.style.justifyContent = 'center';
116
+ container.style.gap = '0.25rem';
117
+ container.style.alignItems = 'center';
118
+
119
+ const formElements = {
120
+ name: document.getElementById('name'),
121
+ user: document.getElementById('user'),
122
+ passwd: document.getElementById('passwd'),
123
+ language: document.getElementById('language'),
124
+ accountType: document.getElementById('accountType'),
125
+ logIn: document.getElementById('logIn'),
126
+ accountName: document.getElementById('accountName')
127
+ };
128
+
129
+ // Tworzenie przycisków
130
+ accounts.forEach((account, i) => {
111
131
  const button = document.createElement("button");
112
132
  button.type = "button";
113
133
  button.id = `button${i}`;
114
134
  button.className = "btn btn-primary";
115
135
  button.style.textTransform = 'none';
116
- button.innerText = pluginConfig[0].accounts[i].name;
117
- document.getElementById("accountButton").appendChild(button);
136
+ button.innerText = account.name || `Account ${i + 1}`;
137
+ container.appendChild(button);
118
138
 
119
139
  button.addEventListener('click', async () => {
120
- for (let j = 0; j < accountsCount; j++) {
140
+ this.accountIndex = i;
141
+
142
+ // Zmieniamy klasę wszystkich przycisków
143
+ accounts.forEach((_, j) => {
121
144
  document.getElementById(`button${j}`).className = (j === i ? 'btn btn-primary' : 'btn btn-secondary');
122
- }
145
+ });
123
146
 
124
- const acc = pluginConfig[0].accounts[i];
125
- document.getElementById('accountName').innerText = acc.name || '';
126
- document.getElementById('name').value = acc.name || '';
127
- document.getElementById('user').value = acc.user || '';
128
- document.getElementById('passwd').value = acc.passwd || '';
129
- document.getElementById('language').value = acc.language || '0';
130
- document.getElementById('displayType').value = acc.displayType || 'disabled';
131
- document.getElementById('logIn').disabled = !(acc.name && acc.user && acc.passwd && acc.language && acc.displayType);
132
- this.deviceIndex = i;
147
+ // Ustawiamy formularz
148
+ formElements.accountName.innerText = account.name || '';
149
+ formElements.name.value = account.name || '';
150
+ formElements.user.value = account.user || '';
151
+ formElements.passwd.value = account.passwd || '';
152
+ formElements.language.value = account.language || '0';
153
+ formElements.accountType.value = account.type || 'disabled';
154
+ formElements.logIn.disabled = !(account.name && account.user && account.passwd && account.language && account.type);
133
155
  });
156
+ });
134
157
 
135
- if (i === accountsCount - 1) document.getElementById(`button0`).click();
136
- }
137
-
138
- document.getElementById('melCloudAccount').style.display = 'block';
158
+ // Klikamy pierwszy przycisk po zakończeniu pętli
159
+ if (accountsCount > 0) document.getElementById('button0').click();
139
160
 
161
+ // Jeden listener input dla całego formularza
140
162
  document.getElementById('configForm').addEventListener('input', async () => {
141
- const acc = pluginConfig[0].accounts[this.deviceIndex];
142
- acc.name = document.querySelector('#name').value;
143
- acc.user = document.querySelector('#user').value;
144
- acc.passwd = document.querySelector('#passwd').value;
145
- acc.language = document.querySelector('#language').value;
146
- acc.displayType = document.querySelector('#displayType').value;
163
+ const account = accounts[this.accountIndex];
164
+ if (!account) return;
147
165
 
148
- document.getElementById('logIn').disabled = !(acc.name && acc.user && acc.passwd && acc.languaged && acc.displayType);
166
+ account.name = formElements.name.value;
167
+ account.user = formElements.user.value;
168
+ account.passwd = formElements.passwd.value;
169
+ account.language = formElements.language.value;
170
+ account.type = formElements.accountType.value;
171
+
172
+ formElements.logIn.disabled = !(account.name && account.user && account.passwd && account.language && account.type);
149
173
 
150
174
  await homebridge.updatePluginConfig(pluginConfig);
151
175
  await homebridge.savePluginConfig(pluginConfig);
152
176
  });
153
177
 
154
- // --- Config Button Toggle ---
178
+ document.getElementById('melCloudAccount').style.display = 'block';
179
+
180
+ // Config Button Toggle
155
181
  const configButton = document.getElementById('configButton');
156
182
  let configButtonState = false;
157
183
  configButton.addEventListener('click', () => {
@@ -173,13 +199,14 @@
173
199
  }
174
200
  });
175
201
 
176
- // --- Device Handling & Login Logic ---
202
+ // Device Handling & Login Logic
177
203
  function removeStaleDevices(configDevices, melcloudDevices) {
178
204
  const melcloudIds = melcloudDevices.map(d => d.DeviceID);
179
205
  const removedDevices = [];
206
+
180
207
  for (let i = configDevices.length - 1; i >= 0; i--) {
181
208
  const device = configDevices[i];
182
- if (device.id !== 0 && !melcloudIds.includes(device.id)) {
209
+ if (device.id !== "0" && !melcloudIds.includes(device.id)) {
183
210
  removedDevices.push(device);
184
211
  configDevices.splice(i, 1);
185
212
  }
@@ -196,61 +223,77 @@
196
223
  }
197
224
 
198
225
  document.getElementById('logIn').addEventListener('click', async () => {
199
- homebridge.showSpinner();
200
226
  document.getElementById(`logIn`).className = "btn btn-primary";
227
+
201
228
  updateInfo('info', 'Connecting...', 'yellow');
229
+ homebridge.showSpinner();
202
230
 
203
231
  try {
204
- const acc = pluginConfig[0].accounts[this.deviceIndex];
205
- const payload = { accountName: acc.name, user: acc.user, passwd: acc.passwd, language: acc.language, displayType: acc.displayType };
206
- const devicesInMelCloud = await homebridge.request('/connect', payload);
232
+ const account = pluginConfig[0].accounts[this.accountIndex];
233
+ const response = await homebridge.request('/connect', account);
234
+ if (!response.State) {
235
+ homebridge.hideSpinner();
236
+ updateInfo('info', response.Info);
237
+ return;
238
+ }
207
239
 
208
240
  // Initialize devices arrays
209
241
  const newDevices = { ata: [], ataPresets: [], atw: [], atwPresets: [], erv: [], ervPresets: [] };
210
242
  const devicesByType = { ata: [], atw: [], erv: [] };
211
243
 
212
- devicesInMelCloud.forEach(d => {
244
+ response.Devices.forEach(d => {
213
245
  if (d.Type === 0) devicesByType.ata.push(d);
214
246
  if (d.Type === 1) devicesByType.atw.push(d);
215
247
  if (d.Type === 3) devicesByType.erv.push(d);
216
248
  });
217
249
 
218
- acc.ataDevices ??= [];
219
- acc.atwDevices ??= [];
220
- acc.ervDevices ??= [];
250
+ account.ataDevices ??= [];
251
+ account.atwDevices ??= [];
252
+ account.ervDevices ??= [];
221
253
 
222
- const removedAta = removeStaleDevices(acc.ataDevices, devicesByType.ata);
223
- const removedAtw = removeStaleDevices(acc.atwDevices, devicesByType.atw);
224
- const removedErv = removeStaleDevices(acc.ervDevices, devicesByType.erv);
254
+ const removedAta = removeStaleDevices(account.ataDevices, devicesByType.ata);
255
+ const removedAtw = removeStaleDevices(account.atwDevices, devicesByType.atw);
256
+ const removedErv = removeStaleDevices(account.ervDevices, devicesByType.erv);
225
257
 
226
- // Function to handle device & presets
227
258
  const handleDevices = (devicesInCloud, devicesInConfig, typeString, newArr, newPresets) => {
228
259
  devicesInCloud.forEach(device => {
229
260
  const { DeviceID: id, Type: type, DeviceName: name, Presets: presets = [] } = device;
230
- const devObj = { id, type, typeString, name, displayMode: 1, presets: [], buttonsSensors: [] };
261
+ const devObj = structuredClone({
262
+ id,
263
+ type,
264
+ typeString,
265
+ name,
266
+ displayType: 0,
267
+ presets: [],
268
+ buttonsSensors: []
269
+ });
270
+
231
271
  if (!devicesInConfig.some(d => d.id === id)) {
232
272
  devicesInConfig.push(devObj);
233
- newArr.push(devObj);
273
+ newArr.push(structuredClone(devObj));
234
274
  }
235
- presets.forEach(p => {
236
- p.id = p.ID;
237
- p.name = p.NumberDescription;
238
- p.displayType = 0;
239
- p.namePrefix = false;
275
+
276
+ presets.forEach(preset => {
277
+ const p = structuredClone({
278
+ id: preset.ID,
279
+ name: preset.NumberDescription,
280
+ displayType: 0,
281
+ namePrefix: false
282
+ });
283
+
240
284
  const devConfig = devicesInConfig.find(d => d.id === id);
241
- if (devConfig && !devConfig.presets.some(x => x.id === p.ID)) {
285
+ if (devConfig && !devConfig.presets.some(x => x.id === p.id)) {
242
286
  devConfig.presets.push(p);
243
- newPresets.push(p);
287
+ newPresets.push(structuredClone(p));
244
288
  }
245
289
  });
246
290
  });
247
291
  };
248
292
 
249
- handleDevices(devicesByType.ata, acc.ataDevices, "Air Conditioner", newDevices.ata, newDevices.ataPresets);
250
- handleDevices(devicesByType.atw, acc.atwDevices, "Heat Pump", newDevices.atw, newDevices.atwPresets);
251
- handleDevices(devicesByType.erv, acc.ervDevices, "Energy Recovery ventiltion", newDevices.erv, newDevices.ervPresets);
293
+ handleDevices(devicesByType.ata, account.ataDevices, "Air Conditioner", newDevices.ata, newDevices.ataPresets);
294
+ handleDevices(devicesByType.atw, account.atwDevices, "Heat Pump", newDevices.atw, newDevices.atwPresets);
295
+ handleDevices(devicesByType.erv, account.ervDevices, "Energy Recovery Ventilation", newDevices.erv, newDevices.ervPresets);
252
296
 
253
- // Display summary
254
297
  const newDevicesCount = newDevices.ata.length + newDevices.atw.length + newDevices.erv.length;
255
298
  const newPresetsCount = newDevices.ataPresets.length + newDevices.atwPresets.length + newDevices.ervPresets.length;
256
299
  const removedDevicesCount = removedAta.length + removedAtw.length + removedErv.length;
@@ -258,9 +301,12 @@
258
301
  if (!newDevicesCount && !newPresetsCount && !removedDevicesCount) {
259
302
  updateInfo('info', 'No changes detected.', 'white');
260
303
  } else {
261
- if (newDevicesCount) updateInfo('info', `Found new devices: ATA: ${newDevices.ata.length}, ATW: ${newDevices.atw.length}, ERV: ${newDevices.erv.length}.`, 'green');
262
- if (newPresetsCount) updateInfo('info1', `Found new presets: ATA: ${newDevices.ataPresets.length}, ATW: ${newDevices.atwPresets.length}, ERV: ${newDevices.ervPresets.length}.`, 'green');
263
- if (removedDevicesCount) updateInfo('info2', `Removed devices: ATA: ${removedAta.length}, ATW: ${removedAtw.length}, ERV: ${removedErv.length}.`, 'orange');
304
+ if (newDevicesCount)
305
+ updateInfo('info', `Found new devices: ATA: ${newDevices.ata.length}, ATW: ${newDevices.atw.length}, ERV: ${newDevices.erv.length}.`, 'green');
306
+ if (newPresetsCount)
307
+ updateInfo('info1', `Found new presets: ATA: ${newDevices.ataPresets.length}, ATW: ${newDevices.atwPresets.length}, ERV: ${newDevices.ervPresets.length}.`, 'green');
308
+ if (removedDevicesCount)
309
+ updateInfo('info2', `Removed devices: ATA: ${removedAta.length}, ATW: ${removedAtw.length}, ERV: ${removedErv.length}.`, 'orange');
264
310
  }
265
311
 
266
312
  await homebridge.updatePluginConfig(pluginConfig);
@@ -269,7 +315,7 @@
269
315
 
270
316
  } catch (error) {
271
317
  updateInfo('info', 'Check Your credentials data and try again.', 'yellow');
272
- updateInfo('info1', `Error: ${error}`, 'red');
318
+ updateInfo('info1', `Error: ${JSON.stringify(error)}`, 'red');
273
319
  document.getElementById('logIn').className = "btn btn-secondary";
274
320
  } finally {
275
321
  homebridge.hideSpinner();
@@ -12,21 +12,19 @@ class PluginUiServer extends HomebridgePluginUiServer {
12
12
  this.ready();
13
13
  };
14
14
 
15
- async start(payload) {
16
- const accountName = payload.accountName;
17
- const user = payload.user;
18
- const passwd = payload.passwd;
19
- const language = payload.language;
20
- const displayType = payload.displayType;
15
+ async start(account) {
16
+ const accountName = account.name;
21
17
  const accountFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Account`;
22
18
  const buildingsFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Buildings`;
23
19
  const devicesFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Devices`;
24
- const melCloud = new MelCloud(displayType, user, passwd, language, accountFile, buildingsFile, devicesFile, false, true);
20
+ const melCloud = new MelCloud(account, accountFile, buildingsFile, devicesFile);
25
21
 
26
22
  try {
27
23
  const accountInfo = await melCloud.connect();
28
- const devices = await melCloud.checkDevicesList(accountInfo.ContextKey);
29
- return devices;
24
+ if (!accountInfo.State) return accountInfo;
25
+
26
+ const devicesList = await melCloud.checkDevicesList();
27
+ return devicesList;
30
28
  } catch (error) {
31
29
  throw new Error(`MELCloud error: ${error.message ?? error}.`);
32
30
  };
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { join } from 'path';
2
- import { mkdirSync } from 'fs';
2
+ import { mkdirSync, existsSync, writeFileSync } from 'fs';
3
3
  import MelCloud from './src/melcloud.js';
4
4
  import DeviceAta from './src/deviceata.js';
5
5
  import DeviceAtw from './src/deviceatw.js';
@@ -30,8 +30,8 @@ class MelCloudPlatform {
30
30
  api.on('didFinishLaunching', async () => {
31
31
  //loop through accounts
32
32
  for (const account of config.accounts) {
33
- const displayType = account.displayType || 'disabled';
34
- if (displayType === 'disabled') continue;
33
+ const accountType = account.type || 'disabled';
34
+ if (accountType === 'disabled') continue;
35
35
 
36
36
  const accountName = account.name;
37
37
  const user = account.user;
@@ -59,7 +59,6 @@ class MelCloudPlatform {
59
59
  debug: account.log?.debug
60
60
  };
61
61
 
62
-
63
62
  if (logLevel.debug) {
64
63
  log.info(`${accountName}, debug: did finish launching.`);
65
64
  const safeConfig = {
@@ -80,7 +79,6 @@ class MelCloudPlatform {
80
79
  const buildingsFile = `${prefDir}/${accountName}_Buildings`;
81
80
  const devicesFile = `${prefDir}/${accountName}_Devices`;
82
81
 
83
-
84
82
  //set account refresh interval
85
83
  const refreshInterval = (account.refreshInterval ?? 120) * 1000
86
84
 
@@ -90,7 +88,7 @@ class MelCloudPlatform {
90
88
  .on('start', async () => {
91
89
  try {
92
90
  //melcloud account
93
- const melCloud = new MelCloud(displayType, user, passwd, language, accountFile, buildingsFile, devicesFile, logLevel.warn, logLevel.debug, false)
91
+ const melCloud = new MelCloud(account, accountFile, buildingsFile, devicesFile, true)
94
92
  .on('success', (msg) => logLevel.success && log.success(`${accountName}, ${msg}`))
95
93
  .on('info', (msg) => logLevel.info && log.info(`${accountName}, ${msg}`))
96
94
  .on('debug', (msg) => logLevel.debug && log.info(`${accountName}, debug: ${msg}`))
@@ -106,56 +104,74 @@ class MelCloudPlatform {
106
104
  return;
107
105
  }
108
106
 
109
- const contextKey = accountInfo.ContextKey;
110
- const useFahrenheit = accountInfo.UseFahrenheit;
111
-
112
- if (!contextKey) {
107
+ if (!accountInfo.State) {
108
+ if (logLevel.warn) log.warn(`${accountName}, ${accountInfo.Info}`);
113
109
  return;
114
110
  }
111
+ if (logLevel.success) log.success(accountInfo.Info);
112
+ const useFahrenheit = accountInfo.UseFahrenheit;
115
113
 
116
114
  //check devices list
117
- let devicesInMelcloud;
115
+ let devicesList;
118
116
  try {
119
- devicesInMelcloud = await melCloud.checkDevicesList(contextKey);
117
+ devicesList = await melCloud.checkDevicesList();
120
118
  } catch (error) {
121
119
  if (logLevel.error) log.error(`${accountName}, Check devices list error: ${error.message ?? error}`);
122
120
  return;
123
121
  }
124
- if (!devicesInMelcloud || !Array.isArray(devicesInMelcloud)) return;
122
+ if (!devicesList.State) {
123
+ if (logLevel.warn) log.warn(`${accountName}, ${devicesList.Info}`);
124
+ return;
125
+ }
125
126
 
126
127
  //configured devices
127
- const ataDevices = account.ataDevices ?? [];
128
- const atwDevices = account.atwDevices ?? [];
129
- const ervDevices = account.ervDevices ?? [];
128
+ const ataDevices = (account.ataDevices || []).filter(device => (device.id ?? '0') !== '0');
129
+ const atwDevices = (account.atwDevices || []).filter(device => (device.id ?? '0') !== '0');
130
+ const ervDevices = (account.ervDevices || []).filter(device => (device.id ?? '0') !== '0');
130
131
  const devices = [...ataDevices, ...atwDevices, ...ervDevices];
131
132
  if (logLevel.debug) log.info(`Found configured devices ATA: ${ataDevices.length}, ATW: ${atwDevices.length}, ERV: ${ervDevices.length}.`);
132
133
 
133
134
  for (const device of devices) {
134
135
  //chack device from config exist on melcloud
135
- const deviceId = device.id;
136
- const displayMode = device.displayMode > 0;
137
- const deviceExistInMelCloud = devicesInMelcloud.some(dev => dev.DeviceID === deviceId);
138
- if (!deviceExistInMelCloud || !displayMode) {
139
- continue;
140
- }
136
+ const displayType = device.displayType > 0;
137
+ const deviceExistInMelCloud = devicesList.Devices.some(dev => dev.DeviceID === device.id);
138
+ if (!deviceExistInMelCloud || !displayType) continue;
141
139
 
142
140
  const deviceName = device.name;
143
141
  const deviceType = device.type;
144
142
  const deviceTypeText = device.typeString;
145
143
  const deviceRefreshInterval = (device.refreshInterval ?? 5) * 1000;
144
+ const defaultTempsFile = `${prefDir}/${accountName}_${device.id}_Temps`;
145
+
146
+ if (accountType === 'melcloudhome') {
147
+ try {
148
+ const temps = {
149
+ defaultCoolingSetTemperature: 24,
150
+ defaultHeatingSetTemperature: 20
151
+ };
152
+
153
+ if (!existsSync(defaultTempsFile)) {
154
+ writeFileSync(defaultTempsFile, JSON.stringify(temps, null, 2));
155
+ if (logLevel.debug) log.debug(`Default temperature file created: ${defaultTempsFile}`);
156
+ }
157
+ } catch (error) {
158
+ if (logLevel.error) log.error(`Device: ${host} ${deviceName}, File init error: ${error.message}`);
159
+ continue;
160
+ }
161
+ }
146
162
 
147
163
  let configuredDevice;
148
164
  switch (deviceType) {
149
165
  case 0: //ATA
150
- configuredDevice = new DeviceAta(api, account, device, contextKey, devicesFile, useFahrenheit, restFul, mqtt);
166
+ configuredDevice = new DeviceAta(api, account, device, devicesFile, defaultTempsFile, useFahrenheit, restFul, mqtt);
151
167
  break;
152
168
  case 1: //ATW
153
- configuredDevice = new DeviceAtw(api, account, device, contextKey, devicesFile, useFahrenheit, restFul, mqtt);
169
+ configuredDevice = new DeviceAtw(api, account, device, devicesFile, defaultTempsFile, useFahrenheit, restFul, mqtt);
154
170
  break;
155
171
  case 2:
156
172
  break;
157
173
  case 3: //ERV
158
- configuredDevice = new DeviceErv(api, account, device, contextKey, devicesFile, useFahrenheit, restFul, mqtt);
174
+ configuredDevice = new DeviceErv(api, account, device, devicesFile, defaultTempsFile, useFahrenheit, restFul, mqtt);
159
175
  break;
160
176
  default:
161
177
  if (logLevel.warn) log.warn(`${accountName}, ${deviceTypeText}, ${deviceName}, unknown device: ${deviceType}.`);
@@ -164,7 +180,7 @@ class MelCloudPlatform {
164
180
 
165
181
  configuredDevice.on('melCloud', async (key, value) => {
166
182
  try {
167
- accountInfo[key] = value;
183
+ accountInfo.LoginData[key] = value;
168
184
  await melCloud.send(accountInfo);
169
185
  } catch (error) {
170
186
  if (logLevel.error) log.error(`${accountName}, ${deviceTypeText}, ${deviceName}, ${error.message ?? error}.`);
@@ -182,8 +198,9 @@ class MelCloudPlatform {
182
198
  api.publishExternalAccessories(PluginName, [accessory]);
183
199
  if (logLevel.success) log.success(`${accountName}, ${deviceTypeText}, ${deviceName}, Published as external accessory.`);
184
200
 
185
- //start impulse generators
186
- await melCloud.impulseGenerator.state(true, [{ name: 'checkDevicesList', sampling: refreshInterval }]);
201
+ //start impulse generators\
202
+ const timmers = accountType === 'melcloudhome' ? [{ name: 'connect', sampling: 900000 }, { name: 'checkDevicesList', sampling: deviceRefreshInterval }] : [{ name: 'checkDevicesList', sampling: refreshInterval }];
203
+ await melCloud.impulseGenerator.state(true, timmers);
187
204
  await configuredDevice.startStopImpulseGenerator(true, [{ name: 'checkState', sampling: deviceRefreshInterval }]);
188
205
 
189
206
  //stop impulse generator
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "MELCloud Control",
3
3
  "name": "homebridge-melcloud-control",
4
- "version": "4.0.0-beta.52",
4
+ "version": "4.0.0-beta.521",
5
5
  "description": "Homebridge plugin to control Mitsubishi Air Conditioner, Heat Pump and Energy Recovery Ventilation.",
6
6
  "license": "MIT",
7
7
  "author": "grzegorz914",
@@ -32,14 +32,15 @@
32
32
  ],
33
33
  "engines": {
34
34
  "homebridge": "^1.9.0 || ^2.0.0 || ^2.0.0-beta.30 || ^2.0.0-alpha.60",
35
- "node": "^20 || ^22 || ^24"
35
+ "node": "^20 || ^22 || ^24 || ^25"
36
36
  },
37
37
  "dependencies": {
38
38
  "@homebridge/plugin-ui-utils": "^2.1.0",
39
39
  "async-mqtt": "^2.6.3",
40
- "axios": "^1.12.2",
40
+ "axios": "^1.13.1",
41
41
  "express": "^5.1.0",
42
- "puppeteer": "^24.26.0"
42
+ "puppeteer-core": "^24.27.0",
43
+ "util": "^0.12.5"
43
44
  },
44
45
  "keywords": [
45
46
  "homebridge",
package/src/constants.js CHANGED
@@ -18,8 +18,7 @@ export const ApiUrls = {
18
18
  };
19
19
 
20
20
  export const ApiUrlsHome = {
21
- LoginUrl:"https://live-melcloudhome.auth.eu-west-1.amazoncognito.com/login?client_id=3g4d5l5kivuqi7oia68gib7uso&redirect_uri=https%3A%2F%2Fauth.melcloudhome.com%2Fsignin-oidc-meu&response_type=code&scope=openid%20profile&response_mode=form_post",
22
- BaseURL: 'https://melcloudhome.com',
21
+ BaseURL: "https://melcloudhome.com",
23
22
  GetUserContext: "/api/user/context",
24
23
  SetAta: "/api/ataunit/deviceid",
25
24
  SetAtw: "/api/atwunit/deviceid",
@@ -36,25 +35,19 @@ export const DeviceType = [
36
35
  export const TemperatureDisplayUnits = ["°C", "°F"];
37
36
 
38
37
  export const AirConditioner = {
39
- System: ["AIR CONDITIONER OFF", "AIR CONDITIONER ON", "AIR CONDITIONER OFFLINE"],
40
- DriveMode: [
41
- "0", "HEAT", "DRY", "COOL", "4", "5", "6", "FAN", "AUTO",
42
- "ISEE HEAT", "ISEE DRY", "ISEE COOL"
43
- ],
44
- VerticalVane: ["AUTO", "1", "2", "3", "4", "5", "6", "SWING"],
45
- HorizontalVane: [
46
- "AUTO", "LL", "L", "C", "R", "RR", "6", "7",
47
- "SPLIT", "9", "10", "11", "SWING"
48
- ],
49
- AirDirection: ["AUTO", "SWING"],
50
- FanSpeed: [
51
- "AUTO", "1", "QUIET", "WEAK", "4",
52
- "STRONG", "VERY STRONG", "OFF"
53
- ],
54
- CurrentOperationModeHeatherCooler: [
55
- "INACTIVE", "IDLE", "HEATING", "COOLING"
56
- ],
57
- CurrentOperationModeThermostat: ["INACTIVE", "HEATING", "COOLING"],
38
+ SystemMapEnumToString: { 0: "Air Conditioner Off", 1: "Air Conditioner On", 2: "Air Conditioner Offline" },
39
+ AirDirectionMapEnumToString: { 0: "Auto", 1: "Swing" },
40
+ CurrentOperationModeHeatherCoolerMapEnumToString: { 0: "Inactive", 1: "Idle", 2: "Heating", 3: "Cooling" },
41
+ CurrentOperationModeThermostatMapEnumToString: { 0: "Inactive", 1: "Heating", 2: "Cooling" },
42
+ OperationModeMapStringToEnum: { "0": 0, "Heat": 1, "Dry": 2, "Cool": 3, "4": 4, "5": 5, "6": 6, "Fan": 7, "Automatic": 8, "Isee Heat": 9, "Isee Dry": 10, "Isee Cool": 11 },
43
+ OperationModeMapEnumToString: { 0: "0", 1: "Heat", 2: "Dry", 3: "Cool", 4: "4", 5: "5", 6: "6", 7: "Fan", 8: "Automatic", 9: "Isee Heat", 10: "Isee Dry", 11: "Isee Cool" },
44
+ FanSpeedMapStringToEnum: { "Auto": 0, "One": 1, "Two": 2, "Three": 3, "Four": 4, "Five": 5 },
45
+ FanSpeedMapEnumToString: { 0: "Auto", 1: "One", 2: "Two", 3: "Three", 4: "Four", 5: "Five" },
46
+ FanSpeedCurrentMapEnumToString: { 0: "Quiet", 1: "One", 2: "Two", 3: "Three", 4: "Four", 5: "Five" },
47
+ VaneVerticalDirectionMapStringToEnum: { "Auto": 0, "One": 1, "Two": 2, "Three": 3, "Four": 4, "Five": 5, "Six": 6, "Swing": 7 },
48
+ VaneVerticalDirectionMapEnumToString: { 0: "Auto", 1: "One", 2: "Two", 3: "Three", 4: "Four", 5: "Five", 6: "Six", 7: "Swing" },
49
+ VaneHorizontalDirectionMapStringToEnum: { "Auto": 0, "Left": 1, "LeftCentre": 2, "Centre": 3, "RightCentre": 4, "Right": 5, "Six": 6, "Seven": 7, "Split": 8, "Nine": 9, "Ten": 10, "Eleven": 11, "Swing": 12 },
50
+ VaneHorizontalDirectionMapEnumToString: { 0: "Auto", 1: "Left", 2: "LeftCentre", 3: "Centre", 4: "RightCentre", 5: "Right", 6: "Six", 7: "Seven", 8: "Split", 9: "Nine", 10: "Ten", 11: "Eleven", 12: "Swing" },
58
51
  EffectiveFlags: {
59
52
  Power: 1,
60
53
  OperationMode: 2,
@@ -74,7 +67,7 @@ export const AirConditioner = {
74
67
  Presets: 287,
75
68
  HolidayMode: 131072,
76
69
  All: 281483566710825
77
- }
70
+ },
78
71
  };
79
72
 
80
73
  export const HeatPump = {