homebridge-melcloud-control 4.3.0-beta.32 → 4.3.0-beta.33
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/melcloudata.js +63 -91
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.0-beta.
|
|
4
|
+
"version": "4.3.0-beta.33",
|
|
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/melcloudata.js
CHANGED
|
@@ -27,6 +27,7 @@ class MelCloudAta extends EventEmitter {
|
|
|
27
27
|
this.deviceData = {};
|
|
28
28
|
this.headers = {};
|
|
29
29
|
this.socket = null;
|
|
30
|
+
this.connecting = false;
|
|
30
31
|
this.socketConnected = false;
|
|
31
32
|
|
|
32
33
|
//lock flag
|
|
@@ -74,76 +75,12 @@ class MelCloudAta extends EventEmitter {
|
|
|
74
75
|
if (this.logDebug) this.emit('debug', `Reconnect in ${delay}ms`);
|
|
75
76
|
|
|
76
77
|
setTimeout(() => {
|
|
77
|
-
this.reconnectDelay *= 2;
|
|
78
|
+
this.reconnectDelay *= 2;
|
|
78
79
|
this.reconnectDelay = Math.max(1000, this.reconnectDelay);
|
|
79
80
|
this.connectSocket(deviceData);
|
|
80
81
|
}, delay);
|
|
81
82
|
};
|
|
82
83
|
|
|
83
|
-
async connectSocket(deviceData, wsHeaders) {
|
|
84
|
-
if (this.connecting || this.socketConnected) return;
|
|
85
|
-
|
|
86
|
-
this.connecting = true;
|
|
87
|
-
const url = `${ApiUrlsHome.WebSocketURL}${wsHeaders.hash}`;
|
|
88
|
-
try {
|
|
89
|
-
const socket = new WebSocket(url, { headers: wsHeaders.headers })
|
|
90
|
-
.on('error', (error) => {
|
|
91
|
-
if (this.logError) this.emit('error', `Socket error: ${error}`);
|
|
92
|
-
})
|
|
93
|
-
.on('close', () => {
|
|
94
|
-
if (this.logDebug) this.emit('debug', `Socket closed`);
|
|
95
|
-
this.reconnect();
|
|
96
|
-
})
|
|
97
|
-
.on('open', () => {
|
|
98
|
-
this.socket = socket;
|
|
99
|
-
this.socketConnected = true;
|
|
100
|
-
this.connecting = false;
|
|
101
|
-
this.reconnectDelay = 1000;
|
|
102
|
-
this.emit('success', `Socket Connect Success`);
|
|
103
|
-
|
|
104
|
-
// heartbeat
|
|
105
|
-
this.heartbeat = setInterval(() => {
|
|
106
|
-
if (socket.readyState === socket.OPEN) {
|
|
107
|
-
if (!this.logDebug) this.emit('warn', `Socket send heartbeat`);
|
|
108
|
-
socket.ping();
|
|
109
|
-
}
|
|
110
|
-
}, 30000);
|
|
111
|
-
})
|
|
112
|
-
.on('pong', () => {
|
|
113
|
-
if (!this.logDebug) this.emit('warn', `Socket received heartbeat`);
|
|
114
|
-
})
|
|
115
|
-
.on('message', (message) => {
|
|
116
|
-
const parsedMessage = JSON.parse(message);
|
|
117
|
-
if (!this.logDebug) this.emit('warn', `Incoming message: ${JSON.stringify(parsedMessage, null, 2)}`);
|
|
118
|
-
|
|
119
|
-
const messageData = parsedMessage?.[0]?.Data;
|
|
120
|
-
const unitId = messageData?.id;
|
|
121
|
-
|
|
122
|
-
switch (unitId) {
|
|
123
|
-
case this.deviceId:
|
|
124
|
-
const messageType = parsedMessage[0].messageType;
|
|
125
|
-
switch (messageType) {
|
|
126
|
-
case 'unitStateChanged':
|
|
127
|
-
const settings = Object.fromEntries(messageData.settings.map(s => [s.name, s.value]));
|
|
128
|
-
Object.assign(deviceData.Device, settings);
|
|
129
|
-
this.emit('deviceState', deviceData);
|
|
130
|
-
break;
|
|
131
|
-
case 'unitWiFiChanged':
|
|
132
|
-
const state = Object.fromEntries(messageData.settings.map(s => [s.name, s.value]));
|
|
133
|
-
Object.assign(deviceData.Device, state);
|
|
134
|
-
this.emit('deviceState', deviceData);
|
|
135
|
-
break;
|
|
136
|
-
}
|
|
137
|
-
break;
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
} catch (error) {
|
|
142
|
-
if (this.logError) this.emit('error', `Socket connection failed: ${error}`);
|
|
143
|
-
this.reconnect();
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
84
|
async checkState() {
|
|
148
85
|
try {
|
|
149
86
|
|
|
@@ -166,7 +103,67 @@ class MelCloudAta extends EventEmitter {
|
|
|
166
103
|
deviceData.Device.DefaultHeatingSetTemperature = temps?.defaultHeatingSetTemperature ?? 20;
|
|
167
104
|
deviceData.Device.DefaultCoolingSetTemperature = temps?.defaultCoolingSetTemperature ?? 24;
|
|
168
105
|
|
|
169
|
-
|
|
106
|
+
if (!this.connecting && !this.socketConnected) {
|
|
107
|
+
|
|
108
|
+
this.connecting = true;
|
|
109
|
+
const url = `${ApiUrlsHome.WebSocketURL}${devicesData.wsHeaders.hash}`;
|
|
110
|
+
try {
|
|
111
|
+
const socket = new WebSocket(url, { headers: devicesData.wsHeaders.headers })
|
|
112
|
+
.on('error', (error) => {
|
|
113
|
+
if (this.logError) this.emit('error', `Socket error: ${error}`);
|
|
114
|
+
})
|
|
115
|
+
.on('close', () => {
|
|
116
|
+
if (this.logDebug) this.emit('debug', `Socket closed`);
|
|
117
|
+
this.reconnect();
|
|
118
|
+
})
|
|
119
|
+
.on('open', () => {
|
|
120
|
+
this.socket = socket;
|
|
121
|
+
this.socketConnected = true;
|
|
122
|
+
this.connecting = false;
|
|
123
|
+
this.reconnectDelay = 1000;
|
|
124
|
+
this.emit('success', `Socket Connect Success`);
|
|
125
|
+
|
|
126
|
+
// heartbeat
|
|
127
|
+
this.heartbeat = setInterval(() => {
|
|
128
|
+
if (socket.readyState === socket.OPEN) {
|
|
129
|
+
if (!this.logDebug) this.emit('warn', `Socket send heartbeat`);
|
|
130
|
+
socket.ping();
|
|
131
|
+
}
|
|
132
|
+
}, 30000);
|
|
133
|
+
})
|
|
134
|
+
.on('pong', () => {
|
|
135
|
+
if (!this.logDebug) this.emit('warn', `Socket received heartbeat`);
|
|
136
|
+
})
|
|
137
|
+
.on('message', (message) => {
|
|
138
|
+
const parsedMessage = JSON.parse(message);
|
|
139
|
+
if (!this.logDebug) this.emit('warn', `Incoming message: ${JSON.stringify(parsedMessage, null, 2)}`);
|
|
140
|
+
|
|
141
|
+
const messageData = parsedMessage?.[0]?.Data;
|
|
142
|
+
const unitId = messageData?.id;
|
|
143
|
+
|
|
144
|
+
switch (unitId) {
|
|
145
|
+
case this.deviceId:
|
|
146
|
+
const messageType = parsedMessage[0].messageType;
|
|
147
|
+
switch (messageType) {
|
|
148
|
+
case 'unitStateChanged':
|
|
149
|
+
const settings = Object.fromEntries(messageData.settings.map(s => [s.name, s.value]));
|
|
150
|
+
Object.assign(deviceData.Device, settings);
|
|
151
|
+
this.emit('deviceState', deviceData);
|
|
152
|
+
break;
|
|
153
|
+
case 'unitWiFiChanged':
|
|
154
|
+
const state = Object.fromEntries(messageData.settings.map(s => [s.name, s.value]));
|
|
155
|
+
Object.assign(deviceData.Device, state);
|
|
156
|
+
this.emit('deviceState', deviceData);
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
} catch (error) {
|
|
163
|
+
if (this.logError) this.emit('error', `Socket connection failed: ${error}`);
|
|
164
|
+
this.reconnect();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
170
167
|
}
|
|
171
168
|
if (this.logDebug) this.emit('debug', `Device Data: ${JSON.stringify(deviceData, null, 2)}`);
|
|
172
169
|
|
|
@@ -324,11 +321,6 @@ class MelCloudAta extends EventEmitter {
|
|
|
324
321
|
this.headers.Referer = ApiUrlsHome.Referers.GetPutScenes;
|
|
325
322
|
break;
|
|
326
323
|
default:
|
|
327
|
-
if (!this.socket || this.socket.readyState !== this.socket.OPEN) {
|
|
328
|
-
if (this.logDebug) this.emit('debug', `Socket not open, cannot send`);
|
|
329
|
-
return false;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
324
|
if (displayType === 1 && deviceData.Device.OperationMode === 8) {
|
|
333
325
|
deviceData.Device.SetTemperature = (deviceData.Device.DefaultCoolingSetTemperature + deviceData.Device.DefaultHeatingSetTemperature) / 2;
|
|
334
326
|
|
|
@@ -354,26 +346,6 @@ class MelCloudAta extends EventEmitter {
|
|
|
354
346
|
method = 'PUT';
|
|
355
347
|
path = ApiUrlsHome.PutAta.replace('deviceid', deviceData.DeviceID);
|
|
356
348
|
this.headers.Referer = ApiUrlsHome.Referers.PutDeviceSettings;
|
|
357
|
-
|
|
358
|
-
const payload1 = {
|
|
359
|
-
Data: {
|
|
360
|
-
id: deviceData.DeviceID,
|
|
361
|
-
unitType: 'ata',
|
|
362
|
-
settings: [
|
|
363
|
-
{
|
|
364
|
-
name: 'Power',
|
|
365
|
-
value: deviceData.Device.Power
|
|
366
|
-
}
|
|
367
|
-
]
|
|
368
|
-
}
|
|
369
|
-
};
|
|
370
|
-
try {
|
|
371
|
-
this.socket.send(JSON.stringify(payload1));
|
|
372
|
-
return true;
|
|
373
|
-
} catch (err) {
|
|
374
|
-
if (this.logDebug) this.emit('debug', `Socket send error: ${err}`);
|
|
375
|
-
return false;
|
|
376
|
-
}
|
|
377
349
|
}
|
|
378
350
|
|
|
379
351
|
this.headers['Content-Type'] = 'application/json; charset=utf-8';
|