homebridge-melcloud-control 4.3.5-beta.3 → 4.3.5-beta.31

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/index.js CHANGED
@@ -74,7 +74,6 @@ class MelCloudPlatform {
74
74
  //define directory and file paths
75
75
  const accountFile = `${prefDir}/${accountName}_Account`;
76
76
  const buildingsFile = `${prefDir}/${accountName}_Buildings`;
77
- const devicesFile = `${prefDir}/${accountName}_Devices`;
78
77
 
79
78
  //set account refresh interval
80
79
  const refreshInterval = (account.refreshInterval ?? 120) * 1000
@@ -85,22 +84,22 @@ class MelCloudPlatform {
85
84
  .on('start', async () => {
86
85
  try {
87
86
  //melcloud account
88
- let configureAccount;
87
+ let melcloud;
89
88
  let timmers = []
90
89
  switch (account.type) {
91
90
  case 'melcloud':
92
91
  timmers = [{ name: 'checkDevicesList', sampling: refreshInterval }];
93
- configureAccount = new MelCloud(account, accountFile, buildingsFile, devicesFile, true);
92
+ melcloud = new MelCloud(account, accountFile, buildingsFile, true);
94
93
  break;
95
94
  case 'melcloudhome':
96
95
  timmers = [{ name: 'connect', sampling: 3300000 }, { name: 'checkDevicesList', sampling: 3000 }];
97
- configureAccount = new MelCloudHome(account, accountFile, buildingsFile, devicesFile, true);
96
+ melcloud = new MelCloudHome(account, accountFile, buildingsFile, true);
98
97
  break;
99
98
  default:
100
99
  if (logLevel.warn) log.warn(`Unknown account type: ${account.type}.`);
101
100
  return;
102
101
  }
103
- configureAccount.on('success', (msg) => log.success(`${accountName}, ${msg}`))
102
+ melcloud.on('success', (msg) => log.success(`${accountName}, ${msg}`))
104
103
  .on('info', (msg) => log.info(`${accountName}, ${msg}`))
105
104
  .on('debug', (msg) => log.info(`${accountName}, debug: ${msg}`))
106
105
  .on('warn', (msg) => log.warn(`${accountName}, ${msg}`))
@@ -109,7 +108,7 @@ class MelCloudPlatform {
109
108
  //connect
110
109
  let accountInfo;
111
110
  try {
112
- accountInfo = await configureAccount.connect();
111
+ accountInfo = await melcloud.connect();
113
112
  if (!accountInfo.State) {
114
113
  if (logLevel.warn) log.warn(`${accountName}, ${accountInfo.Info}`);
115
114
  return;
@@ -118,21 +117,21 @@ class MelCloudPlatform {
118
117
  if (logLevel.error) log.error(`${accountName}, Connect error: ${error.message ?? error}`);
119
118
  return;
120
119
  }
121
- if (logLevel.success) log.success(accountInfo.Info);
120
+ if (logLevel.success) log.success(`${accountName}, ${accountInfo.Info}`);
122
121
 
123
122
  //check devices list
124
- let devicesList;
123
+ let melcloudDevicesList;
125
124
  try {
126
- devicesList = await configureAccount.checkDevicesList();
127
- if (!devicesList.State) {
128
- if (logLevel.warn) log.warn(`${accountName}, ${devicesList.Info}`);
125
+ melcloudDevicesList = await melcloud.checkDevicesList();
126
+ if (!melcloudDevicesList.State) {
127
+ if (logLevel.warn) log.warn(`${accountName}, ${melcloudDevicesList.Info}`);
129
128
  return;
130
129
  }
131
130
  } catch (error) {
132
131
  if (logLevel.error) log.error(`${accountName}, Check devices list error: ${error.message ?? error}`);
133
132
  return;
134
133
  }
135
- if (logLevel.debug) log.info(devicesList.Info);
134
+ if (logLevel.debug) log.info(melcloudDevicesList.Info);
136
135
 
137
136
  //configured devices
138
137
  const ataDevices = (account.ataDevices || []).filter(device => device.id != null && String(device.id) !== '0');
@@ -144,14 +143,13 @@ class MelCloudPlatform {
144
143
  for (const [index, device] of devices.entries()) {
145
144
  //chack device from config exist on melcloud
146
145
  const displayType = device.displayType > 0;
147
- const deviceExistInMelCloud = devicesList.Devices.some(dev => dev.DeviceID === device.id);
146
+ const deviceExistInMelCloud = melcloudDevicesList.Devices.some(dev => dev.DeviceID === device.id);
148
147
  if (!deviceExistInMelCloud || !displayType) continue;
149
148
 
150
149
  device.id = String(device.id);
151
150
  const deviceName = device.name;
152
151
  const deviceType = device.type;
153
152
  const deviceTypeString = device.typeString;
154
- const deviceRefreshInterval = (device.refreshInterval ?? 5) * 1000;
155
153
  const defaultTempsFile = `${prefDir}/${accountName}_${device.id}_Temps`;
156
154
 
157
155
  // set rest ful port
@@ -179,15 +177,15 @@ class MelCloudPlatform {
179
177
  let configuredDevice;
180
178
  switch (deviceType) {
181
179
  case 0: //ATA
182
- configuredDevice = new DeviceAta(api, account, device, devicesFile, defaultTempsFile, accountInfo, accountFile, devicesList.WebSocket);
180
+ configuredDevice = new DeviceAta(api, account, device, defaultTempsFile, accountInfo, accountFile, melcloud, melcloudDevicesList);
183
181
  break;
184
182
  case 1: //ATW
185
- configuredDevice = new DeviceAtw(api, account, device, devicesFile, defaultTempsFile, accountInfo, accountFile, devicesList.WebSocket);
183
+ configuredDevice = new DeviceAtw(api, account, device, defaultTempsFile, accountInfo, accountFile, melcloud, melcloudDevicesList);
186
184
  break;
187
185
  case 2:
188
186
  break;
189
187
  case 3: //ERV
190
- configuredDevice = new DeviceErv(api, account, device, devicesFile, defaultTempsFile, accountInfo, accountFile, devicesList.WebSocket);
188
+ configuredDevice = new DeviceErv(api, account, device, defaultTempsFile, accountInfo, accountFile, melcloud, melcloudDevicesList);
191
189
  break;
192
190
  default:
193
191
  if (logLevel.warn) log.warn(`${accountName}, ${deviceTypeString}, ${deviceName}, unknown device: ${deviceType}.`);
@@ -205,17 +203,14 @@ class MelCloudPlatform {
205
203
  if (accessory) {
206
204
  api.publishExternalAccessories(PluginName, [accessory]);
207
205
  if (logLevel.success) log.success(`${accountName}, ${deviceTypeString}, ${deviceName}, Published as external accessory.`);
208
-
209
- //start impulse generators for device
210
- await configuredDevice.startStopImpulseGenerator(true, [{ name: 'checkState', sampling: deviceRefreshInterval }]);
211
206
  }
212
207
  }
213
208
 
214
- //start account impulse generator
215
- await configureAccount.impulseGenerator.state(true, timmers, false);
216
-
217
209
  //stop start impulse generator
218
210
  await impulseGenerator.state(false);
211
+
212
+ //start account impulse generator
213
+ await melcloud.impulseGenerator.state(true, timmers, false);
219
214
  } catch (error) {
220
215
  if (logLevel.error) log.error(`${accountName}, Start impulse generator error, ${error.message ?? error}, trying again.`);
221
216
  }
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.5-beta.3",
4
+ "version": "4.3.5-beta.31",
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/deviceata.js CHANGED
@@ -7,7 +7,7 @@ import { TemperatureDisplayUnits, AirConditioner } from './constants.js';
7
7
  let Accessory, Characteristic, Service, Categories, AccessoryUUID;
8
8
 
9
9
  class DeviceAta extends EventEmitter {
10
- constructor(api, account, device, devicesFile, defaultTempsFile, accountInfo, accountFile, webSocket) {
10
+ constructor(api, account, device, defaultTempsFile, accountInfo, accountFile, melcloud, melcloudDevicesList) {
11
11
  super();
12
12
 
13
13
  Accessory = api.platformAccessory;
@@ -17,7 +17,8 @@ class DeviceAta extends EventEmitter {
17
17
  AccessoryUUID = api.hap.uuid;
18
18
 
19
19
  //account config
20
- this.webSocket = webSocket;
20
+ this.melcloud = melcloud;
21
+ this.melcloudDevicesList = melcloudDevicesList;
21
22
  this.account = account;
22
23
  this.accountType = account.type;
23
24
  this.accountName = account.name;
@@ -49,7 +50,6 @@ class DeviceAta extends EventEmitter {
49
50
  this.buttons = (device.buttonsSensors || []).filter(button => (button.displayType ?? 0) > 0);
50
51
 
51
52
  //files
52
- this.devicesFile = devicesFile;
53
53
  this.defaultTempsFile = defaultTempsFile;
54
54
  this.accountInfo = accountInfo;
55
55
  this.accountFile = accountFile;
@@ -108,16 +108,6 @@ class DeviceAta extends EventEmitter {
108
108
  this.accessory = {};
109
109
  };
110
110
 
111
- async startStopImpulseGenerator(state, timers = []) {
112
- try {
113
- //start impulse generator
114
- await this.melCloudAta.impulseGenerator.state(state, timers)
115
- return true;
116
- } catch (error) {
117
- throw new Error(`Impulse generator start error: ${error}`);
118
- }
119
- }
120
-
121
111
  async externalIntegrations() {
122
112
  //RESTFul server
123
113
  const restFulEnabled = this.restFul.enable || false;
@@ -1331,7 +1321,7 @@ class DeviceAta extends EventEmitter {
1331
1321
  async start() {
1332
1322
  try {
1333
1323
  //melcloud device
1334
- this.melCloudAta = new MelCloudAta(this.account, this.device, this.devicesFile, this.defaultTempsFile, this.accountFile, this.webSocket)
1324
+ this.melCloudAta = new MelCloudAta(this.account, this.device, this.defaultTempsFile, this.accountFile, this.melcloud)
1335
1325
  .on('deviceInfo', (modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion) => {
1336
1326
  if (this.logDeviceInfo && this.displayDeviceInfo) {
1337
1327
  this.emit('devInfo', `---- ${this.deviceTypeString}: ${this.deviceName} ----`);
@@ -1888,9 +1878,10 @@ class DeviceAta extends EventEmitter {
1888
1878
  if (this.restFul.enable || this.mqtt.enable) await this.externalIntegrations();
1889
1879
 
1890
1880
  //check state
1891
- await this.melCloudAta.checkState();
1881
+ await this.melCloudAta.checkState(this.melcloudDevicesList);
1892
1882
 
1893
1883
  //prepare accessory
1884
+ await new Promise(r => setTimeout(r, 5000));
1894
1885
  const accessory = await this.prepareAccessory();
1895
1886
  return accessory;
1896
1887
  } catch (error) {
package/src/deviceatw.js CHANGED
@@ -7,7 +7,7 @@ import { TemperatureDisplayUnits, HeatPump } from './constants.js';
7
7
  let Accessory, Characteristic, Service, Categories, AccessoryUUID;
8
8
 
9
9
  class DeviceAtw extends EventEmitter {
10
- constructor(api, account, device, devicesFile, defaultTempsFile, accountInfo, accountFile) {
10
+ constructor(api, account, device, defaultTempsFile, accountInfo, accountFile, melcloud, melcloudDevicesList) {
11
11
  super();
12
12
 
13
13
  Accessory = api.platformAccessory;
@@ -17,6 +17,8 @@ class DeviceAtw extends EventEmitter {
17
17
  AccessoryUUID = api.hap.uuid;
18
18
 
19
19
  //account config
20
+ this.melcloud = melcloud;
21
+ this.melcloudDevicesList = melcloudDevicesList;
20
22
  this.account = account;
21
23
  this.accountType = account.type;
22
24
  this.accountName = account.name;
@@ -52,7 +54,6 @@ class DeviceAtw extends EventEmitter {
52
54
  this.buttons = (device.buttonsSensors || []).filter(button => (button.displayType ?? 0) > 0);
53
55
 
54
56
  //files
55
- this.devicesFile = devicesFile;
56
57
  this.defaultTempsFile = defaultTempsFile;
57
58
  this.accountInfo = accountInfo;
58
59
  this.accountFile = accountFile;
@@ -111,17 +112,6 @@ class DeviceAtw extends EventEmitter {
111
112
  this.accessory = {};
112
113
  };
113
114
 
114
- async startStopImpulseGenerator(state, timers = []) {
115
- try {
116
- //start impulse generator
117
- await this.melCloudAtw.impulseGenerator.state(state, timers)
118
- return true;
119
- } catch (error) {
120
- throw new Error(`Impulse generator start error: ${error}`);
121
- }
122
- }
123
-
124
-
125
115
  async externalIntegrations() {
126
116
  //RESTFul server
127
117
  const restFulEnabled = this.restFul.enable || false;
@@ -1577,7 +1567,7 @@ class DeviceAtw extends EventEmitter {
1577
1567
  async start() {
1578
1568
  try {
1579
1569
  //melcloud device
1580
- this.melCloudAtw = new MelCloudAtw(this.account, this.device, this.devicesFile, this.defaultTempsFile, this.accountFile)
1570
+ this.melCloudAtw = new MelCloudAtw(this.account, this.device, this.defaultTempsFile, this.accountFile, this.melcloud)
1581
1571
  .on('deviceInfo', (modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion, supportsHotWaterTank, supportsZone2) => {
1582
1572
  if (this.logDeviceInfo && this.displayDeviceInfo) {
1583
1573
  this.emit('devInfo', `---- ${this.deviceTypeString}: ${this.deviceName} ----`);
@@ -2317,9 +2307,10 @@ class DeviceAtw extends EventEmitter {
2317
2307
  if (this.restFul.enable || this.mqtt.enable) await this.externalIntegrations();
2318
2308
 
2319
2309
  //check state
2320
- await this.melCloudAtw.checkState();
2310
+ await this.melCloudAta.checkState(this.melcloudDevicesList);
2321
2311
 
2322
2312
  //prepare accessory
2313
+ await new Promise(r => setTimeout(r, 1000));
2323
2314
  const accessory = await this.prepareAccessory();
2324
2315
  return accessory;
2325
2316
  } catch (error) {
package/src/deviceerv.js CHANGED
@@ -7,7 +7,7 @@ import { TemperatureDisplayUnits, Ventilation } from './constants.js';
7
7
  let Accessory, Characteristic, Service, Categories, AccessoryUUID;
8
8
 
9
9
  class DeviceErv extends EventEmitter {
10
- constructor(api, account, device, devicesFile, defaultTempsFile, accountInfo, accountFile) {
10
+ constructor(api, account, device, defaultTempsFile, accountInfo, accountFile, melcloud, melcloudDevicesList) {
11
11
  super();
12
12
 
13
13
  Accessory = api.platformAccessory;
@@ -17,6 +17,8 @@ class DeviceErv extends EventEmitter {
17
17
  AccessoryUUID = api.hap.uuid;
18
18
 
19
19
  //account config
20
+ this.melcloud = melcloud;
21
+ this.melcloudDevicesList = melcloudDevicesList;
20
22
  this.account = account;
21
23
  this.accountType = account.type;
22
24
  this.accountName = account.name;
@@ -44,7 +46,6 @@ class DeviceErv extends EventEmitter {
44
46
  this.buttons = (device.buttonsSensors || []).filter(button => (button.displayType ?? 0) > 0);
45
47
 
46
48
  //files
47
- this.devicesFile = devicesFile;
48
49
  this.defaultTempsFile = defaultTempsFile;
49
50
  this.accountInfo = accountInfo;
50
51
  this.accountFile = accountFile;
@@ -103,16 +104,6 @@ class DeviceErv extends EventEmitter {
103
104
  this.accessory = {};
104
105
  };
105
106
 
106
- async startStopImpulseGenerator(state, timers = []) {
107
- try {
108
- //start impulse generator
109
- await this.melCloudErv.impulseGenerator.state(state, timers)
110
- return true;
111
- } catch (error) {
112
- throw new Error(`Impulse generator start error: ${error}`);
113
- }
114
- }
115
-
116
107
  async externalIntegrations() {
117
108
  //RESTFul server
118
109
  const restFulEnabled = this.restFul.enable || false;
@@ -1130,7 +1121,7 @@ class DeviceErv extends EventEmitter {
1130
1121
  async start() {
1131
1122
  try {
1132
1123
  //melcloud device
1133
- this.melCloudErv = new MelCloudErv(this.account, this.device, this.devicesFile, this.defaultTempsFile, this.accountFile)
1124
+ this.melCloudErv = new MelCloudErv(this.account, this.device, this.defaultTempsFile, this.accountFile, this.melcloud)
1134
1125
  .on('deviceInfo', (modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion) => {
1135
1126
  if (this.logDeviceInfo && this.displayDeviceInfo) {
1136
1127
  this.emit('devInfo', `---- ${this.deviceTypeString}: ${this.deviceName} ----`);
@@ -1590,9 +1581,10 @@ class DeviceErv extends EventEmitter {
1590
1581
  if (this.restFul.enable || this.mqtt.enable) await this.externalIntegrations();
1591
1582
 
1592
1583
  //check state
1593
- await this.melCloudErv.checkState();
1584
+ await this.melCloudAta.checkState(this.melcloudDevicesList);
1594
1585
 
1595
1586
  //prepare accessory
1587
+ await new Promise(r => setTimeout(r, 1000));
1596
1588
  const accessory = await this.prepareAccessory();
1597
1589
  return accessory;
1598
1590
  } catch (error) {
package/src/melcloud.js CHANGED
@@ -5,7 +5,7 @@ import Functions from './functions.js';
5
5
  import { ApiUrls } from './constants.js';
6
6
 
7
7
  class MelCloud extends EventEmitter {
8
- constructor(account, accountFile, buildingsFile, devicesFile, pluginStart = false) {
8
+ constructor(account, accountFile, buildingsFile, pluginStart = false) {
9
9
  super();
10
10
  this.accountType = account.type;
11
11
  this.user = account.user;
@@ -14,9 +14,9 @@ class MelCloud extends EventEmitter {
14
14
  this.logWarn = account.log?.warn;
15
15
  this.logError = account.log?.error;
16
16
  this.logDebug = account.log?.debug;
17
+
17
18
  this.accountFile = accountFile;
18
19
  this.buildingsFile = buildingsFile;
19
- this.devicesFile = devicesFile;
20
20
  this.headers = {};
21
21
 
22
22
  this.functions = new Functions(this.logWarn, this.logError, this.logDebug)
@@ -110,9 +110,7 @@ class MelCloud extends EventEmitter {
110
110
  devicesList.Info = `Found ${devicesCount} devices`;
111
111
  devicesList.Devices = devices;
112
112
  devicesList.Headers = this.headers;
113
-
114
- await this.functions.saveData(this.devicesFile, devicesList);
115
- if (this.logDebug) this.emit('debug', `${devicesCount} devices saved`);
113
+ this.emit('devicesList', devicesList);
116
114
 
117
115
  return devicesList;
118
116
  } catch (error) {
@@ -173,7 +171,7 @@ class MelCloud extends EventEmitter {
173
171
  });
174
172
 
175
173
  accountInfo.State = true;
176
- accountInfo.Info = 'Connect to MELCloud Success';
174
+ accountInfo.Info = 'Connect Success';
177
175
  accountInfo.UseFahrenheit = loginData.UseFahrenheit;
178
176
  accountInfo.Account = account;
179
177
  await this.functions.saveData(this.accountFile, accountInfo);
@@ -1,12 +1,10 @@
1
- import WebSocket from 'ws';
2
1
  import axios from 'axios';
3
2
  import EventEmitter from 'events';
4
- import ImpulseGenerator from './impulsegenerator.js';
5
3
  import Functions from './functions.js';
6
4
  import { ApiUrls, ApiUrlsHome, AirConditioner } from './constants.js';
7
5
 
8
6
  class MelCloudAta extends EventEmitter {
9
- constructor(account, device, devicesFile, defaultTempsFile, accountFile, webSocket) {
7
+ constructor(account, device, defaultTempsFile, accountFile, melcloud) {
10
8
  super();
11
9
  this.accountType = account.type;
12
10
  this.logSuccess = account.log?.success;
@@ -16,10 +14,9 @@ class MelCloudAta extends EventEmitter {
16
14
  this.restFulEnabled = account.restFul?.enable;
17
15
  this.mqttEnabled = account.mqtt?.enable;
18
16
  this.deviceId = device.id;
19
- this.devicesFile = devicesFile;
20
17
  this.defaultTempsFile = defaultTempsFile;
21
18
  this.accountFile = accountFile;
22
- this.webSocket = webSocket;
19
+
23
20
  this.functions = new Functions(this.logWarn, this.logError, this.logDebug)
24
21
  .on('warn', warn => this.emit('warn', warn))
25
22
  .on('error', error => this.emit('error', error))
@@ -27,48 +24,74 @@ class MelCloudAta extends EventEmitter {
27
24
 
28
25
  //set default values
29
26
  this.deviceData = {};
30
- this.headers = {};
31
- this.socket = null;
32
- this.connecting = false;
33
- this.socketConnected = false;
34
- this.heartbeat = null;
35
-
36
- //lock flag
37
- this.locks = false;
38
- this.impulseGenerator = new ImpulseGenerator()
39
- .on('checkState', () => this.handleWithLock(async () => {
40
- await this.checkState();
41
- }))
42
- .on('state', (state) => {
43
- this.emit(state ? 'success' : 'warn', `Impulse generator ${state ? 'started' : 'stopped'}`);
44
- });
45
- }
46
-
47
- async handleWithLock(fn) {
48
- if (this.locks) return;
27
+ this.headers = {}
49
28
 
50
- this.locks = true;
51
- try {
52
- await fn();
53
- } catch (error) {
54
- this.emit('error', `Inpulse generator error: ${error}`);
55
- } finally {
56
- this.locks = false;
57
- }
58
- }
59
-
60
- cleanupSocket() {
61
- if (this.heartbeat) {
62
- clearInterval(this.heartbeat);
63
- this.heartbeat = null;
64
- }
29
+ let deviceData = null;
30
+ melcloud.on('devicesList', async (devicesData) => {
31
+ this.headers = devicesData.Headers;
32
+ deviceData = devicesData.Devices.find(device => device.DeviceID === this.deviceId);
33
+ if (!deviceData) return;
34
+ deviceData.Scenes = devicesData.Scenes ?? [];
65
35
 
66
- if (this.socket) {
67
- try { this.socket.close(); } catch { }
68
- this.socket = null;
69
- }
36
+ //update state
37
+ await this.updateState(deviceData);
38
+ }).on('webSocket', async (parsedMessage) => {
39
+ try {
40
+ const messageData = parsedMessage?.[0]?.Data;
41
+ if (!messageData || !deviceData) return;
42
+
43
+ let updateState = false;
44
+ const unitId = messageData?.id;
45
+ switch (unitId) {
46
+ case this.deviceId:
47
+ const messageType = parsedMessage[0].messageType;
48
+ const settings = this.functions.parseArrayNameValue(messageData.settings);
49
+ switch (messageType) {
50
+ case 'unitStateChanged':
51
+
52
+ //update values
53
+ for (const [key, value] of Object.entries(settings)) {
54
+ if (!this.functions.isValidValue(value)) continue;
55
+
56
+ //update holiday mode
57
+ if (key === 'HolidayMode') {
58
+ deviceData.HolidayMode.Enabled = value;
59
+ continue;
60
+ }
61
+
62
+ //update device settings
63
+ if (key in deviceData.Device) {
64
+ deviceData.Device[key] = value;
65
+ }
66
+ }
67
+ updateState = true;
68
+ break;
69
+ case 'unitHolidayModeTriggered':
70
+ deviceData.Device.Power = settings.Power;
71
+ deviceData.HolidayMode.Enabled = settings.HolidayMode;
72
+ deviceData.HolidayMode.Active = messageData.active;
73
+ updateState = true;
74
+ break;
75
+ case 'unitWifiSignalChanged':
76
+ deviceData.Rssi = messageData.rssi;
77
+ updateState = true;
78
+ break;
79
+ default:
80
+ if (this.logDebug) this.emit('debug', `Unit ${unitId}, received unknown message type: ${stringifyMessage}`);
81
+ return;
82
+ }
83
+ break;
84
+ default:
85
+ if (this.logDebug) this.emit('debug', `Incoming unknown unit id: ${stringifyMessage}`);
86
+ return;
87
+ }
70
88
 
71
- this.socketConnected = false;
89
+ //update state
90
+ if (updateState) await this.updateState(deviceData);
91
+ } catch (error) {
92
+ if (this.logError) this.emit('error', `Web socket process message error: ${error}`);
93
+ }
94
+ });
72
95
  }
73
96
 
74
97
  async updateState(deviceData) {
@@ -144,94 +167,18 @@ class MelCloudAta extends EventEmitter {
144
167
  };
145
168
  };
146
169
 
147
- async checkState() {
170
+ async checkState(devicesData) {
148
171
  try {
149
- //read device info from file
150
- const devicesData = await this.functions.readData(this.devicesFile, true);
151
- if (!devicesData) return;
152
-
153
172
  this.headers = devicesData.Headers;
154
173
  const deviceData = devicesData.Devices.find(device => device.DeviceID === this.deviceId);
155
- if (!deviceData) return;
156
174
  deviceData.Scenes = devicesData.Scenes ?? [];
157
-
158
- //web cocket connection
159
- if (this.accountType === 'melcloudhome' && !this.connecting) {
160
- this.connecting = true;
161
-
162
- try {
163
- this.webSocket.on('message', async (message) => {
164
- const parsedMessage = JSON.parse(message);
165
- const stringifyMessage = JSON.stringify(parsedMessage, null, 2);
166
- if (parsedMessage.message === 'Forbidden') return;
167
-
168
- const messageData = parsedMessage?.[0]?.Data;
169
- if (!messageData) return;
170
-
171
- let updateState = false;
172
- const unitId = messageData?.id;
173
- switch (unitId) {
174
- case this.deviceId:
175
- if (!this.logDebug) this.emit('debug', `Incoming message: ${stringifyMessage}`);
176
- const messageType = parsedMessage[0].messageType;
177
- const settings = this.functions.parseArrayNameValue(messageData.settings);
178
- switch (messageType) {
179
- case 'unitStateChanged':
180
-
181
- //update values
182
- for (const [key, value] of Object.entries(settings)) {
183
- if (!this.functions.isValidValue(value)) continue;
184
-
185
- //update holiday mode
186
- if (key === 'HolidayMode') {
187
- deviceData.HolidayMode.Enabled = value;
188
- continue;
189
- }
190
-
191
- //update device settings
192
- if (key in deviceData.Device) {
193
- deviceData.Device[key] = value;
194
- }
195
- }
196
- updateState = true;
197
- break;
198
- case 'unitHolidayModeTriggered':
199
- deviceData.Device.Power = settings.Power;
200
- deviceData.HolidayMode.Enabled = settings.HolidayMode;
201
- deviceData.HolidayMode.Active = messageData.active;
202
- updateState = true;
203
- break;
204
- case 'unitWifiSignalChanged':
205
- deviceData.Rssi = messageData.rssi;
206
- updateState = true;
207
- break;
208
- default:
209
- if (!this.logDebug) this.emit('debug', `Unit ${unitId}, received unknown message type: ${stringifyMessage}`);
210
- return;
211
- }
212
- break;
213
- default:
214
- if (!this.logDebug) this.emit('debug', `Incoming unknown unit id: ${stringifyMessage}`);
215
- return;
216
- }
217
-
218
- //update state
219
- if (updateState) await this.updateState(deviceData);
220
- });
221
- } catch (error) {
222
- if (this.logError) this.emit('error', `Socket connection failed: ${error}`);
223
- this.cleanupSocket();
224
- }
225
- }
226
-
227
- //update state
228
175
  await this.updateState(deviceData);
229
176
 
230
177
  return true;
231
178
  } catch (error) {
232
- throw new Error(`Check state error: ${error.message}`);
179
+ throw new Error(`Chaeck state error: ${error.message}`);
233
180
  };
234
- };
181
+ }
235
182
 
236
183
  async send(accountType, displayType, deviceData, flag, flagData) {
237
184
  try {
@@ -284,7 +231,8 @@ class MelCloudAta extends EventEmitter {
284
231
  headers: headers,
285
232
  data: payload
286
233
  });
287
- this.updateData(deviceData, updateState);
234
+
235
+ this.emit('deviceState', deviceData);
288
236
  return true;
289
237
  case "melcloudhome":
290
238
  switch (flag) {
@@ -375,7 +323,6 @@ class MelCloudAta extends EventEmitter {
375
323
  data: payload
376
324
  });
377
325
 
378
- this.updateData(deviceData, updateState);
379
326
  return true;
380
327
  default:
381
328
  return;
@@ -385,14 +332,5 @@ class MelCloudAta extends EventEmitter {
385
332
  throw new Error(`Send data error: ${error.message}`);
386
333
  }
387
334
  }
388
-
389
- updateData(deviceData, updateState = true) {
390
- this.locks = true;
391
- if (updateState) this.emit('deviceState', deviceData);
392
-
393
- setTimeout(() => {
394
- this.locks = false
395
- }, 5000);
396
- }
397
335
  };
398
336
  export default MelCloudAta;
@@ -1,12 +1,10 @@
1
- import WebSocket from 'ws';
2
1
  import axios from 'axios';
3
2
  import EventEmitter from 'events';
4
- import ImpulseGenerator from './impulsegenerator.js';
5
3
  import Functions from './functions.js';
6
4
  import { ApiUrls, ApiUrlsHome, HeatPump } from './constants.js';
7
5
 
8
6
  class MelCloudAtw extends EventEmitter {
9
- constructor(account, device, devicesFile, defaultTempsFile, accountFile) {
7
+ constructor(account, device, defaultTempsFile, accountFile, melcloud) {
10
8
  super();
11
9
  this.accountType = account.type;
12
10
  this.logSuccess = account.log?.success;
@@ -16,9 +14,9 @@ class MelCloudAtw extends EventEmitter {
16
14
  this.restFulEnabled = account.restFul?.enable;
17
15
  this.mqttEnabled = account.mqtt?.enable;
18
16
  this.deviceId = device.id;
19
- this.devicesFile = devicesFile;
20
17
  this.defaultTempsFile = defaultTempsFile;
21
18
  this.accountFile = accountFile;
19
+
22
20
  this.functions = new Functions(this.logWarn, this.logError, this.logDebug)
23
21
  .on('warn', warn => this.emit('warn', warn))
24
22
  .on('error', error => this.emit('error', error))
@@ -27,47 +25,69 @@ class MelCloudAtw extends EventEmitter {
27
25
  //set default values
28
26
  this.deviceData = {};
29
27
  this.headers = {};
30
- this.socket = null;
31
- this.connecting = false;
32
- this.socketConnected = false;
33
- this.heartbeat = null;
34
-
35
- //lock flag
36
- this.locks = false;
37
- this.impulseGenerator = new ImpulseGenerator()
38
- .on('checkState', () => this.handleWithLock(async () => {
39
- await this.checkState();
40
- }))
41
- .on('state', (state) => {
42
- this.emit(state ? 'success' : 'warn', `Impulse generator ${state ? 'started' : 'stopped'}`);
43
- });
44
- }
45
28
 
46
- async handleWithLock(fn) {
47
- if (this.locks) return;
48
-
49
- this.locks = true;
50
- try {
51
- await fn();
52
- } catch (error) {
53
- this.emit('error', `Inpulse generator error: ${error}`);
54
- } finally {
55
- this.locks = false;
56
- }
57
- }
29
+ let deviceData = null;
30
+ melcloud.on('devicesList', async (devicesData) => {
31
+ this.headers = devicesData.Headers;
32
+ deviceData = devicesData.Devices.find(device => device.DeviceID === this.deviceId);
33
+ if (!deviceData) return;
34
+ deviceData.Scenes = devicesData.Scenes ?? [];
58
35
 
59
- cleanupSocket() {
60
- if (this.heartbeat) {
61
- clearInterval(this.heartbeat);
62
- this.heartbeat = null;
63
- }
36
+ //update state
37
+ await this.updateState(deviceData);
38
+ }).on('message', async (message) => {
39
+ try {
40
+ const parsedMessage = JSON.parse(message);
41
+ const stringifyMessage = JSON.stringify(parsedMessage, null, 2);
42
+ if (this.logDebug) this.emit('debug', `Incoming message: ${stringifyMessage}`);
43
+ if (parsedMessage.message === 'Forbidden') return;
44
+
45
+ const messageData = parsedMessage?.[0]?.Data;
46
+ if (!messageData || !deviceData) return;
47
+
48
+ let updateState = false;
49
+ const unitId = messageData?.id;
50
+ switch (unitId) {
51
+ case this.deviceId:
52
+ const messageType = parsedMessage[0].messageType;
53
+ switch (messageType) {
54
+ case 'unitStateChanged':
55
+ const settings = Object.fromEntries(
56
+ messageData.settings.map(({ name, value }) => {
57
+ let parsedValue = this.functions.convertValue(value);
58
+ return [name, parsedValue];
59
+ })
60
+ );
61
+ Object.assign(deviceData.Device, settings);
62
+ updateState = true;
63
+ break;
64
+ case 'unitHolidayModeTriggered':
65
+ deviceData.Device.Power = settings.Power;
66
+ deviceData.HolidayMode.Enabled = settings.HolidayMode;
67
+ deviceData.HolidayMode.Active = messageData.active;
68
+ updateState = true;
69
+ break;
70
+ case 'unitWifiSignalChanged':
71
+ deviceData.Rssi = messageData.rssi;
72
+ updateState = true;
73
+ break;
74
+ default:
75
+ if (this.logDebug) this.emit('debug', `Unit ${unitId}, received unknown message type: ${stringifyMessage}`);
76
+ return;
77
+ }
78
+ break;
79
+ default:
80
+ if (this.logDebug) this.emit('debug', `Incoming unknown unit id: ${stringifyMessage}`);
81
+ return;
82
+ }
64
83
 
65
- if (this.socket) {
66
- try { this.socket.close(); } catch { }
67
- this.socket = null;
68
- }
84
+ //update state
85
+ if (updateState) await this.updateState(deviceData);
86
+ } catch (error) {
87
+ if (this.logError) this.emit('error', `Web socket process message error: ${error}`);
88
+ }
89
+ });
69
90
 
70
- this.socketConnected = false;
71
91
  }
72
92
 
73
93
  async updateState(deviceData) {
@@ -137,105 +157,18 @@ class MelCloudAtw extends EventEmitter {
137
157
  };
138
158
  };
139
159
 
140
- async checkState() {
160
+ async checkState(devicesData) {
141
161
  try {
142
- //read device info from file
143
- const devicesData = await this.functions.readData(this.devicesFile, true);
144
- if (!devicesData) return;
145
-
146
162
  this.headers = devicesData.Headers;
147
163
  const deviceData = devicesData.Devices.find(device => device.DeviceID === this.deviceId);
148
- if (!deviceData) return;
149
164
  deviceData.Scenes = devicesData.Scenes ?? [];
150
-
151
- //web cocket connection
152
- if (this.accountType === 'melcloudhome' && !this.connecting && !this.socketConnected) {
153
- this.connecting = true;
154
-
155
- const url = `${ApiUrlsHome.WebSocketURL}${devicesData.WebSocketOptions.Hash}`;
156
- try {
157
- const socket = new WebSocket(url, { headers: devicesData.WebSocketOptions.Headers })
158
- .on('error', (error) => {
159
- if (this.logError) this.emit('error', `Socket error: ${error}`);
160
- socket.close();
161
- })
162
- .on('close', () => {
163
- if (this.logDebug) this.emit('debug', `Socket closed`);
164
- this.cleanupSocket();
165
- })
166
- .on('open', () => {
167
- this.socket = socket;
168
- this.socketConnected = true;
169
- this.connecting = false;
170
- if (this.logSuccess) this.emit('success', `Socket Connect Success`);
171
-
172
- // heartbeat
173
- this.heartbeat = setInterval(() => {
174
- if (socket.readyState === socket.OPEN) {
175
- if (this.logDebug) this.emit('debug', `Socket send heartbeat`);
176
- socket.ping();
177
- }
178
- }, 30000);
179
- })
180
- .on('pong', () => {
181
- if (this.logDebug) this.emit('debug', `Socket received heartbeat`);
182
- })
183
- .on('message', async (message) => {
184
- const parsedMessage = JSON.parse(message);
185
- const stringifyMessage = JSON.stringify(parsedMessage, null, 2);
186
- if (this.logDebug) this.emit('debug', `Incoming message: ${stringifyMessage}`);
187
- if (parsedMessage.message === 'Forbidden') return;
188
-
189
- const messageData = parsedMessage?.[0]?.Data;
190
- if (!messageData) return;
191
-
192
- let updateState = false;
193
- const unitId = messageData?.id;
194
- switch (unitId) {
195
- case this.deviceId:
196
- const messageType = parsedMessage[0].messageType;
197
- switch (messageType) {
198
- case 'unitStateChanged':
199
- const settings = Object.fromEntries(
200
- messageData.settings.map(({ name, value }) => {
201
- let parsedValue = this.functions.convertValue(value);
202
- return [name, parsedValue];
203
- })
204
- );
205
- Object.assign(deviceData.Device, settings);
206
- updateState = true;
207
- break;
208
- case 'unitWifiSignalChanged':
209
- deviceData.Rssi = messageData.rssi;
210
- updateState = true;
211
- break;
212
- default:
213
- if (this.logDebug) this.emit('debug', `Unit ${unitId}, received unknown message type: ${stringifyMessage}`);
214
- return;
215
- }
216
- break;
217
- default:
218
- if (this.logDebug) this.emit('debug', `Incoming unknown unit id: ${stringifyMessage}`);
219
- return;
220
- }
221
-
222
- //update state
223
- if (updateState) await this.updateState(deviceData);
224
- });
225
- } catch (error) {
226
- if (this.logError) this.emit('error', `Socket connection failed: ${error}`);
227
- this.cleanupSocket();
228
- }
229
- }
230
-
231
- //update state
232
165
  await this.updateState(deviceData);
233
166
 
234
167
  return true;
235
168
  } catch (error) {
236
- throw new Error(`Check state error: ${error.message}`);
169
+ throw new Error(`Chaeck state error: ${error.message}`);
237
170
  };
238
- };
171
+ }
239
172
 
240
173
  async send(accountType, displayType, deviceData, flag, flagData) {
241
174
  try {
@@ -303,7 +236,8 @@ class MelCloudAtw extends EventEmitter {
303
236
  headers: headers,
304
237
  data: payload
305
238
  });
306
- this.updateData(deviceData);
239
+
240
+ this.emit('deviceState', deviceData);
307
241
  return true;
308
242
  case "melcloudhome":
309
243
  switch (flag) {
@@ -363,7 +297,6 @@ class MelCloudAtw extends EventEmitter {
363
297
  data: payload
364
298
  });
365
299
 
366
- this.updateData(deviceData, updateState);
367
300
  return true;
368
301
  default:
369
302
  return;
@@ -373,14 +306,5 @@ class MelCloudAtw extends EventEmitter {
373
306
  throw new Error(`Send data error: ${error.message}`);
374
307
  }
375
308
  }
376
-
377
- updateData(deviceData, updateState = true) {
378
- this.locks = true;
379
- if (updateState) this.emit('deviceState', deviceData);
380
-
381
- setTimeout(() => {
382
- this.locks = false
383
- }, 5000);
384
- }
385
309
  };
386
310
  export default MelCloudAtw;
@@ -1,12 +1,10 @@
1
- import WebSocket from 'ws';
2
1
  import axios from 'axios';
3
2
  import EventEmitter from 'events';
4
- import ImpulseGenerator from './impulsegenerator.js';
5
3
  import Functions from './functions.js';
6
4
  import { ApiUrls, ApiUrlsHome, Ventilation } from './constants.js';
7
5
 
8
6
  class MelCloudErv extends EventEmitter {
9
- constructor(account, device, devicesFile, defaultTempsFile, accountFile) {
7
+ constructor(account, device, defaultTempsFile, accountFile, melcloud) {
10
8
  super();
11
9
  this.accountType = account.type;
12
10
  this.logSuccess = account.log?.success;
@@ -16,9 +14,9 @@ class MelCloudErv extends EventEmitter {
16
14
  this.restFulEnabled = account.restFul?.enable;
17
15
  this.mqttEnabled = account.mqtt?.enable;
18
16
  this.deviceId = device.id;
19
- this.devicesFile = devicesFile;
20
17
  this.defaultTempsFile = defaultTempsFile;
21
18
  this.accountFile = accountFile;
19
+
22
20
  this.functions = new Functions(this.logWarn, this.logError, this.logDebug)
23
21
  .on('warn', warn => this.emit('warn', warn))
24
22
  .on('error', error => this.emit('error', error))
@@ -28,42 +26,77 @@ class MelCloudErv extends EventEmitter {
28
26
  this.deviceData = {};
29
27
  this.headers = {};
30
28
 
31
- //lock flags
32
- this.locks = false;
33
- this.impulseGenerator = new ImpulseGenerator()
34
- .on('checkState', () => this.handleWithLock(async () => {
35
- await this.checkState();
36
- }))
37
- .on('state', (state) => {
38
- this.emit(state ? 'success' : 'warn', `Impulse generator ${state ? 'started' : 'stopped'}`);
39
- });
40
- }
29
+ let deviceData = null;
30
+ melcloud.on('devicesList', async (devicesData) => {
31
+ this.headers = devicesData.Headers;
32
+ deviceData = devicesData.Devices.find(device => device.DeviceID === this.deviceId);
33
+ if (!deviceData) return;
34
+ deviceData.Scenes = devicesData.Scenes ?? [];
41
35
 
42
- async handleWithLock(fn) {
43
- if (this.locks) return;
36
+ //update state
37
+ await this.updateState(deviceData);
38
+ }).on('webSocket', async (parsedMessage) => {
39
+ try {
40
+ const messageData = parsedMessage?.[0]?.Data;
41
+ if (!messageData || !deviceData) return;
44
42
 
45
- this.locks = true;
46
- try {
47
- await fn();
48
- } catch (error) {
49
- this.emit('error', `Inpulse generator error: ${error}`);
50
- } finally {
51
- this.locks = false;
52
- }
43
+ let updateState = false;
44
+ const unitId = messageData?.id;
45
+ switch (unitId) {
46
+ case this.deviceId:
47
+ const messageType = parsedMessage[0].messageType;
48
+ const settings = this.functions.parseArrayNameValue(messageData.settings);
49
+ switch (messageType) {
50
+ case 'unitStateChanged':
51
+
52
+ //update values
53
+ for (const [key, value] of Object.entries(settings)) {
54
+ if (!this.functions.isValidValue(value)) continue;
55
+
56
+ //update holiday mode
57
+ if (key === 'HolidayMode') {
58
+ deviceData.HolidayMode.Enabled = value;
59
+ continue;
60
+ }
61
+
62
+ //update device settings
63
+ if (key in deviceData.Device) {
64
+ deviceData.Device[key] = value;
65
+ }
66
+ }
67
+ updateState = true;
68
+ break;
69
+ case 'unitHolidayModeTriggered':
70
+ deviceData.Device.Power = settings.Power;
71
+ deviceData.HolidayMode.Enabled = settings.HolidayMode;
72
+ deviceData.HolidayMode.Active = messageData.active;
73
+ updateState = true;
74
+ break;
75
+ case 'unitWifiSignalChanged':
76
+ deviceData.Rssi = messageData.rssi;
77
+ updateState = true;
78
+ break;
79
+ default:
80
+ if (this.logDebug) this.emit('debug', `Unit ${unitId}, received unknown message type: ${stringifyMessage}`);
81
+ return;
82
+ }
83
+ break;
84
+ default:
85
+ if (this.logDebug) this.emit('debug', `Incoming unknown unit id: ${stringifyMessage}`);
86
+ return;
87
+ }
88
+
89
+ //update state
90
+ if (updateState) await this.updateState(deviceData);
91
+ } catch (error) {
92
+ if (this.logError) this.emit('error', `Web socket process message error: ${error}`);
93
+ }
94
+ });
53
95
  }
54
96
 
55
- async checkState() {
97
+ async updateState(deviceData) {
56
98
  try {
57
- //read device info from file
58
- const devicesData = await this.functions.readData(this.devicesFile, true);
59
- if (!devicesData) return;
60
-
61
- this.headers = devicesData.Headers;
62
- const deviceData = devicesData.Devices.find(device => device.DeviceID === this.deviceId);
63
- if (!deviceData) return;
64
99
  if (this.accountType === 'melcloudhome') {
65
- deviceData.Scenes = devicesData.Scenes ?? [];
66
-
67
100
  //read default temps
68
101
  const temps = await this.functions.readData(this.defaultTempsFile, true);
69
102
  deviceData.Device.DefaultHeatingSetTemperature = temps?.defaultHeatingSetTemperature ?? 20;
@@ -127,6 +160,19 @@ class MelCloudErv extends EventEmitter {
127
160
  };
128
161
  };
129
162
 
163
+ async checkState(devicesData) {
164
+ try {
165
+ this.headers = devicesData.Headers;
166
+ const deviceData = devicesData.Devices.find(device => device.DeviceID === this.deviceId);
167
+ deviceData.Scenes = devicesData.Scenes ?? [];
168
+ await this.updateState(deviceData);
169
+
170
+ return true;
171
+ } catch (error) {
172
+ throw new Error(`Chaeck state error: ${error.message}`);
173
+ };
174
+ }
175
+
130
176
  async send(accountType, displayType, deviceData, flag, flagData) {
131
177
  try {
132
178
  let method = null
@@ -194,7 +240,8 @@ class MelCloudErv extends EventEmitter {
194
240
  headers: headers,
195
241
  data: payload
196
242
  });
197
- this.updateData(deviceData);
243
+
244
+ this.emit('deviceState', deviceData);
198
245
  return true;
199
246
  case "melcloudhome":
200
247
  switch (flag) {
@@ -257,7 +304,7 @@ class MelCloudErv extends EventEmitter {
257
304
  headers: headers,
258
305
  data: payload
259
306
  });
260
- this.updateData(deviceData, updateState);
307
+
261
308
  return true;
262
309
  default:
263
310
  return;
@@ -267,14 +314,5 @@ class MelCloudErv extends EventEmitter {
267
314
  throw new Error(`Send data error: ${error.message}`);
268
315
  }
269
316
  }
270
-
271
- updateData(deviceData, updateState = true) {
272
- this.locks = true;
273
- if (updateState) this.emit('deviceState', deviceData);
274
-
275
- setTimeout(() => {
276
- this.locks = false
277
- }, 5000);
278
- }
279
317
  };
280
318
  export default MelCloudErv;
@@ -11,7 +11,7 @@ import { ApiUrlsHome, LanguageLocaleMap } from './constants.js';
11
11
  const execPromise = promisify(exec);
12
12
 
13
13
  class MelCloudHome extends EventEmitter {
14
- constructor(account, accountFile, buildingsFile, devicesFile, pluginStart = false) {
14
+ constructor(account, accountFile, buildingsFile, pluginStart = false) {
15
15
  super();
16
16
  this.accountType = account.type;
17
17
  this.user = account.user;
@@ -23,7 +23,7 @@ class MelCloudHome extends EventEmitter {
23
23
  this.logDebug = account.log?.debug;
24
24
  this.accountFile = accountFile;
25
25
  this.buildingsFile = buildingsFile;
26
- this.devicesFile = devicesFile;
26
+
27
27
  this.headers = {};
28
28
  this.webSocketOptions = {};
29
29
  this.socket = null;
@@ -242,13 +242,21 @@ class MelCloudHome extends EventEmitter {
242
242
  // heartbeat
243
243
  this.heartbeat = setInterval(() => {
244
244
  if (this.socket.readyState === this.socket.OPEN) {
245
- if (!this.logDebug) this.emit('debug', `Socket send heartbeat`);
245
+ if (this.logDebug) this.emit('debug', `Socket send heartbeat`);
246
246
  this.socket.ping();
247
247
  }
248
248
  }, 30000);
249
249
  })
250
250
  .on('pong', () => {
251
- if (!this.logDebug) this.emit('debug', `Socket received heartbeat`);
251
+ if (this.logDebug) this.emit('debug', `Socket received heartbeat`);
252
+ })
253
+ .on('message', (message) => {
254
+ const parsedMessage = JSON.parse(message);
255
+ const stringifyMessage = JSON.stringify(parsedMessage, null, 2);
256
+ if (!this.logDebug) this.emit('debug', `Incoming message: ${stringifyMessage}`);
257
+ if (parsedMessage.message === 'Forbidden') return;
258
+
259
+ this.emit('webSocket', parsedMessage);
252
260
  });
253
261
  } catch (error) {
254
262
  if (this.logError) this.emit('error', `Socket connection failed: ${error}`);
@@ -261,10 +269,7 @@ class MelCloudHome extends EventEmitter {
261
269
  devicesList.Devices = devices;
262
270
  devicesList.Scenes = scenes;
263
271
  devicesList.Headers = this.headers;
264
- devicesList.WebSocket = this.socket;
265
-
266
- await this.functions.saveData(this.devicesFile, devicesList);
267
- if (this.logDebug) this.emit('debug', `${devicesCount} devices saved`);
272
+ this.emit('devicesList', devicesList);;
268
273
 
269
274
  return devicesList;
270
275
  } catch (error) {
@@ -436,7 +441,7 @@ class MelCloudHome extends EventEmitter {
436
441
  };
437
442
 
438
443
  accountInfo.State = true;
439
- accountInfo.Info = 'Connect to MELCloud Home Success';
444
+ accountInfo.Info = 'Connect Success';
440
445
  await this.functions.saveData(this.accountFile, accountInfo);
441
446
 
442
447
  return accountInfo;