homebridge-melcloud-control 4.2.3-beta.2 → 4.2.3-beta.21
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/homebridge-ui/server.js +2 -1
- package/index.js +4 -3
- package/package.json +1 -1
- package/src/constants.js +30 -0
- package/src/deviceata.js +5 -7
- package/src/deviceatw.js +17 -12
- package/src/deviceerv.js +4 -6
- package/src/melcloud.js +32 -364
- package/src/melcloudata.js +7 -20
- package/src/melcloudatw.js +52 -72
- package/src/melclouderv.js +39 -61
- package/src/melcloudhome.js +359 -0
package/src/melcloudatw.js
CHANGED
|
@@ -52,16 +52,11 @@ class MelCloudAtw extends EventEmitter {
|
|
|
52
52
|
try {
|
|
53
53
|
//read device info from file
|
|
54
54
|
const devicesData = await this.functions.readData(this.devicesFile, true);
|
|
55
|
-
if (!Array.isArray(devicesData)) {
|
|
56
|
-
if (this.logWarn) this.emit('warn', `Device data not found`);
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
55
|
const deviceData = devicesData.find(device => device.DeviceID === this.deviceId);
|
|
60
56
|
|
|
61
57
|
if (this.accountType === 'melcloudhome') {
|
|
62
|
-
deviceData.SerialNumber = deviceData.DeviceID || '4.0.0';
|
|
63
|
-
deviceData.Device.FirmwareAppVersion = deviceData.ConnectedInterfaceIdentifier || '4.0.0';
|
|
64
58
|
}
|
|
59
|
+
|
|
65
60
|
const safeConfig = {
|
|
66
61
|
...deviceData,
|
|
67
62
|
Headers: 'removed',
|
|
@@ -69,15 +64,15 @@ class MelCloudAtw extends EventEmitter {
|
|
|
69
64
|
if (this.logDebug) this.emit('debug', `Device Data: ${JSON.stringify(safeConfig, null, 2)}`);
|
|
70
65
|
|
|
71
66
|
//device
|
|
72
|
-
|
|
67
|
+
//device
|
|
68
|
+
const serialNumber = deviceData.SerialNumber || '4.0.0';
|
|
69
|
+
const firmwareAppVersion = deviceData.Device?.FirmwareAppVersion || '4.0.0';
|
|
73
70
|
const hasHotWaterTank = deviceData.Device?.HasHotWaterTank;
|
|
74
|
-
const firmwareAppVersion = deviceData.Device?.FirmwareAppVersion;
|
|
75
71
|
const hasZone2 = deviceData.Device?.HasZone2;
|
|
76
72
|
|
|
77
73
|
//units
|
|
78
74
|
const units = Array.isArray(deviceData.Device?.Units) ? deviceData.Device?.Units : [];
|
|
79
75
|
const unitsCount = units.length;
|
|
80
|
-
const manufacturer = 'Mitsubishi';
|
|
81
76
|
|
|
82
77
|
const { indoor, outdoor } = units.reduce((acc, unit) => {
|
|
83
78
|
const target = unit.IsIndoor ? 'indoor' : 'outdoor';
|
|
@@ -109,14 +104,11 @@ class MelCloudAtw extends EventEmitter {
|
|
|
109
104
|
|
|
110
105
|
//check state changes
|
|
111
106
|
const deviceDataHasNotChanged = JSON.stringify(devicesData) === JSON.stringify(this.devicesData);
|
|
112
|
-
if (deviceDataHasNotChanged)
|
|
113
|
-
if (this.logDebug) this.emit('debug', `Device state not changed`);
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
107
|
+
if (deviceDataHasNotChanged) return;
|
|
116
108
|
this.devicesData = devicesData;
|
|
117
109
|
|
|
118
110
|
//emit info
|
|
119
|
-
this.emit('deviceInfo',
|
|
111
|
+
this.emit('deviceInfo', indoor.model, outdoor.model, serialNumber, firmwareAppVersion, hasHotWaterTank, hasZone2);
|
|
120
112
|
|
|
121
113
|
//emit state
|
|
122
114
|
this.emit('deviceState', deviceData);
|
|
@@ -148,93 +140,81 @@ class MelCloudAtw extends EventEmitter {
|
|
|
148
140
|
let path = '';
|
|
149
141
|
switch (accountType) {
|
|
150
142
|
case "melcloud":
|
|
151
|
-
|
|
143
|
+
deviceData.Device.EffectiveFlags = effectiveFlags;
|
|
144
|
+
payload = {
|
|
145
|
+
DeviceID: deviceData.Device.DeviceID,
|
|
146
|
+
EffectiveFlags: deviceData.Device.EffectiveFlags,
|
|
147
|
+
Power: deviceData.Device.Power,
|
|
148
|
+
SetTemperatureZone1: deviceData.Device.SetTemperatureZone1,
|
|
149
|
+
SetTemperatureZone2: deviceData.Device.SetTemperatureZone2,
|
|
150
|
+
OperationMode: deviceData.Device.OperationMode,
|
|
151
|
+
OperationModeZone1: deviceData.Device.OperationModeZone1,
|
|
152
|
+
OperationModeZone2: deviceData.Device.OperationModeZone2,
|
|
153
|
+
SetHeatFlowTemperatureZone1: deviceData.Device.SetHeatFlowTemperatureZone1,
|
|
154
|
+
SetHeatFlowTemperatureZone2: deviceData.Device.SetHeatFlowTemperatureZone2,
|
|
155
|
+
SetCoolFlowTemperatureZone1: deviceData.Device.SetCoolFlowTemperatureZone1,
|
|
156
|
+
SetCoolFlowTemperatureZone2: deviceData.Device.SetCoolFlowTemperatureZone2,
|
|
157
|
+
SetTankWaterTemperature: deviceData.Device.SetTankWaterTemperature,
|
|
158
|
+
ForcedHotWaterMode: deviceData.Device.ForcedHotWaterMode,
|
|
159
|
+
EcoHotWater: deviceData.Device.EcoHotWater,
|
|
160
|
+
HolidayMode: deviceData.Device.HolidayMode,
|
|
161
|
+
ProhibitZone1: deviceData.Device.ProhibitHeatingZone1,
|
|
162
|
+
ProhibitZone2: deviceData.Device.ProhibitHeatingZone2,
|
|
163
|
+
ProhibitHotWater: deviceData.Device.ProhibitHotWater,
|
|
164
|
+
HasPendingCommand: true
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (this.logDebug) this.emit('debug', `Send Data: ${JSON.stringify(payload, null, 2)}`);
|
|
168
|
+
await axios(ApiUrls.SetAtw, {
|
|
152
169
|
method: 'POST',
|
|
153
170
|
baseURL: ApiUrls.BaseURL,
|
|
154
171
|
timeout: 10000,
|
|
155
172
|
headers: deviceData.Headers,
|
|
156
|
-
|
|
173
|
+
data: payload
|
|
157
174
|
});
|
|
158
|
-
|
|
159
|
-
deviceData.Device.EffectiveFlags = effectiveFlags;
|
|
160
|
-
payload = {
|
|
161
|
-
data: {
|
|
162
|
-
DeviceID: deviceData.Device.DeviceID,
|
|
163
|
-
EffectiveFlags: deviceData.Device.EffectiveFlags,
|
|
164
|
-
Power: deviceData.Device.Power,
|
|
165
|
-
SetTemperatureZone1: deviceData.Device.SetTemperatureZone1,
|
|
166
|
-
SetTemperatureZone2: deviceData.Device.SetTemperatureZone2,
|
|
167
|
-
OperationMode: deviceData.Device.OperationMode,
|
|
168
|
-
OperationModeZone1: deviceData.Device.OperationModeZone1,
|
|
169
|
-
OperationModeZone2: deviceData.Device.OperationModeZone2,
|
|
170
|
-
SetHeatFlowTemperatureZone1: deviceData.Device.SetHeatFlowTemperatureZone1,
|
|
171
|
-
SetHeatFlowTemperatureZone2: deviceData.Device.SetHeatFlowTemperatureZone2,
|
|
172
|
-
SetCoolFlowTemperatureZone1: deviceData.Device.SetCoolFlowTemperatureZone1,
|
|
173
|
-
SetCoolFlowTemperatureZone2: deviceData.Device.SetCoolFlowTemperatureZone2,
|
|
174
|
-
SetTankWaterTemperature: deviceData.Device.SetTankWaterTemperature,
|
|
175
|
-
ForcedHotWaterMode: deviceData.Device.ForcedHotWaterMode,
|
|
176
|
-
EcoHotWater: deviceData.Device.EcoHotWater,
|
|
177
|
-
HolidayMode: deviceData.Device.HolidayMode,
|
|
178
|
-
ProhibitZone1: deviceData.Device.ProhibitHeatingZone1,
|
|
179
|
-
ProhibitZone2: deviceData.Device.ProhibitHeatingZone2,
|
|
180
|
-
ProhibitHotWater: deviceData.Device.ProhibitHotWater,
|
|
181
|
-
HasPendingCommand: true
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
await axiosInstancePost(ApiUrls.SetAtw, payload);
|
|
186
175
|
this.updateData(deviceData);
|
|
187
176
|
return true;
|
|
188
177
|
case "melcloudhome":
|
|
189
178
|
switch (effectiveFlags) {
|
|
190
179
|
case 'holidaymode':
|
|
191
|
-
payload = {
|
|
192
|
-
data: { enabled: deviceData.HolidayMode.Enabled, startDate: deviceData.HolidayMode.StartDate, endDate: deviceData.HolidayMode.EndDate, units: { "ATW": [deviceData.DeviceID] } }
|
|
193
|
-
};
|
|
180
|
+
payload = { enabled: deviceData.HolidayMode.Enabled, startDate: deviceData.HolidayMode.StartDate, endDate: deviceData.HolidayMode.EndDate, units: { "ATW": [deviceData.DeviceID] } };
|
|
194
181
|
method = 'POST';
|
|
195
182
|
path = ApiUrlsHome.PostHolidayMode;
|
|
196
183
|
break;
|
|
197
184
|
case 'schedule':
|
|
198
|
-
payload = {
|
|
199
|
-
data: {
|
|
200
|
-
enabled: deviceData.ScheduleEnabled
|
|
201
|
-
}
|
|
202
|
-
};
|
|
185
|
+
payload = { enabled: deviceData.ScheduleEnabled };
|
|
203
186
|
method = 'PUT';
|
|
204
187
|
path = ApiUrlsHome.PutScheduleEnable.replace('deviceid', deviceData.DeviceID);
|
|
205
188
|
break;
|
|
206
189
|
default:
|
|
207
190
|
payload = {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
EcoHotWater: deviceData.Device.EcoHotWater,
|
|
222
|
-
}
|
|
191
|
+
Power: deviceData.Device.Power,
|
|
192
|
+
SetTemperatureZone1: deviceData.Device.SetTemperatureZone1,
|
|
193
|
+
SetTemperatureZone2: deviceData.Device.SetTemperatureZone2,
|
|
194
|
+
OperationMode: HeatPump.OperationModeMapEnumToString[deviceData.Device.OperationMode],
|
|
195
|
+
OperationModeZone1: HeatPump.OperationModeMapEnumToString[deviceData.Device.OperationModeZone1],
|
|
196
|
+
OperationModeZone2: HeatPump.OperationModeMapEnumToString[deviceData.Device.OperationModeZone2],
|
|
197
|
+
SetHeatFlowTemperatureZone1: deviceData.Device.SetHeatFlowTemperatureZone1,
|
|
198
|
+
SetHeatFlowTemperatureZone2: deviceData.Device.SetHeatFlowTemperatureZone2,
|
|
199
|
+
SetCoolFlowTemperatureZone1: deviceData.Device.SetCoolFlowTemperatureZone1,
|
|
200
|
+
SetCoolFlowTemperatureZone2: deviceData.Device.SetCoolFlowTemperatureZone2,
|
|
201
|
+
SetTankWaterTemperature: deviceData.Device.SetTankWaterTemperature,
|
|
202
|
+
ForcedHotWaterMode: deviceData.Device.ForcedHotWaterMode,
|
|
203
|
+
EcoHotWater: deviceData.Device.EcoHotWater,
|
|
223
204
|
};
|
|
224
205
|
method = 'PUT';
|
|
225
206
|
path = ApiUrlsHome.SetAtw.replace('deviceid', deviceData.DeviceID);
|
|
226
207
|
break
|
|
227
208
|
}
|
|
228
209
|
|
|
229
|
-
|
|
210
|
+
if (this.logDebug) this.emit('debug', `Send Data: ${JSON.stringify(payload, null, 2)}`);
|
|
211
|
+
await axios(path, {
|
|
230
212
|
method: method,
|
|
231
213
|
baseURL: ApiUrlsHome.BaseURL,
|
|
232
214
|
timeout: 10000,
|
|
233
|
-
headers: deviceData.Headers
|
|
215
|
+
headers: deviceData.Headers,
|
|
216
|
+
data: payload
|
|
234
217
|
});
|
|
235
|
-
|
|
236
|
-
if (this.logDebug) this.emit('debug', `Send Data: ${JSON.stringify(payload.data, null, 2)}`);
|
|
237
|
-
await axiosInstancePut(path, payload);
|
|
238
218
|
this.updateData(deviceData);
|
|
239
219
|
return true;
|
|
240
220
|
default:
|
package/src/melclouderv.js
CHANGED
|
@@ -52,35 +52,28 @@ class MelCloudErv extends EventEmitter {
|
|
|
52
52
|
try {
|
|
53
53
|
//read device info from file
|
|
54
54
|
const devicesData = await this.functions.readData(this.devicesFile, true);
|
|
55
|
-
if (!Array.isArray(devicesData)) {
|
|
56
|
-
if (this.logWarn) this.emit('warn', `Device data not found`);
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
55
|
const deviceData = devicesData.find(device => device.DeviceID === this.deviceId);
|
|
60
56
|
|
|
61
57
|
if (this.accountType === 'melcloudhome') {
|
|
62
|
-
deviceData.SerialNumber = deviceData.DeviceID || '4.0.0';
|
|
63
|
-
deviceData.Device.FirmwareAppVersion = deviceData.ConnectedInterfaceIdentifier || '4.0.0';
|
|
64
|
-
|
|
65
58
|
//read default temps
|
|
66
59
|
const temps = await this.functions.readData(this.defaultTempsFile, true);
|
|
67
60
|
deviceData.Device.DefaultHeatingSetTemperature = temps?.defaultHeatingSetTemperature ?? 20;
|
|
68
61
|
deviceData.Device.DefaultCoolingSetTemperature = temps?.defaultCoolingSetTemperature ?? 24;
|
|
69
62
|
}
|
|
63
|
+
|
|
70
64
|
const safeConfig = {
|
|
71
65
|
...deviceData,
|
|
72
66
|
Headers: 'removed',
|
|
73
67
|
};
|
|
74
68
|
if (this.logDebug) this.emit('debug', `Device Data: ${JSON.stringify(safeConfig, null, 2)}`);
|
|
75
69
|
|
|
76
|
-
//
|
|
77
|
-
const serialNumber = deviceData.SerialNumber;
|
|
78
|
-
const firmwareAppVersion = deviceData.Device?.FirmwareAppVersion;
|
|
70
|
+
//device
|
|
71
|
+
const serialNumber = deviceData.SerialNumber || '4.0.0';
|
|
72
|
+
const firmwareAppVersion = deviceData.Device?.FirmwareAppVersion || '4.0.0';
|
|
79
73
|
|
|
80
74
|
//units
|
|
81
75
|
const units = Array.isArray(deviceData.Device?.Units) ? deviceData.Device?.Units : [];
|
|
82
76
|
const unitsCount = units.length;
|
|
83
|
-
const manufacturer = 'Mitsubishi';
|
|
84
77
|
|
|
85
78
|
const { indoor, outdoor } = units.reduce((acc, unit) => {
|
|
86
79
|
const target = unit.IsIndoor ? 'indoor' : 'outdoor';
|
|
@@ -112,14 +105,11 @@ class MelCloudErv extends EventEmitter {
|
|
|
112
105
|
|
|
113
106
|
//check state changes
|
|
114
107
|
const deviceDataHasNotChanged = JSON.stringify(devicesData) === JSON.stringify(this.devicesData);
|
|
115
|
-
if (deviceDataHasNotChanged)
|
|
116
|
-
if (this.logDebug) this.emit('debug', `Device state not changed`);
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
108
|
+
if (deviceDataHasNotChanged) return;
|
|
119
109
|
this.devicesData = devicesData;
|
|
120
110
|
|
|
121
111
|
//emit info
|
|
122
|
-
this.emit('deviceInfo',
|
|
112
|
+
this.emit('deviceInfo', indoor.model, outdoor.model, serialNumber, firmwareAppVersion);
|
|
123
113
|
|
|
124
114
|
//emit state
|
|
125
115
|
this.emit('deviceState', deviceData);
|
|
@@ -137,14 +127,6 @@ class MelCloudErv extends EventEmitter {
|
|
|
137
127
|
let path = '';
|
|
138
128
|
switch (accountType) {
|
|
139
129
|
case "melcloud":
|
|
140
|
-
const axiosInstancePost = axios.create({
|
|
141
|
-
method: 'POST',
|
|
142
|
-
baseURL: ApiUrls.BaseURL,
|
|
143
|
-
timeout: 10000,
|
|
144
|
-
headers: deviceData.Headers,
|
|
145
|
-
withCredentials: true
|
|
146
|
-
});
|
|
147
|
-
|
|
148
130
|
//set target temp based on display mode and ventilation mode
|
|
149
131
|
switch (displayType) {
|
|
150
132
|
case 1: //Heather/Cooler
|
|
@@ -168,25 +150,30 @@ class MelCloudErv extends EventEmitter {
|
|
|
168
150
|
//device state
|
|
169
151
|
deviceData.Device.EffectiveFlags = effectiveFlags;
|
|
170
152
|
payload = {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
HasPendingCommand: true
|
|
186
|
-
}
|
|
153
|
+
DeviceID: deviceData.Device.DeviceID,
|
|
154
|
+
EffectiveFlags: deviceData.Device.EffectiveFlags,
|
|
155
|
+
Power: deviceData.Device.Power,
|
|
156
|
+
SetTemperature: deviceData.Device.SetTemperature,
|
|
157
|
+
SetFanSpeed: deviceData.Device.SetFanSpeed,
|
|
158
|
+
OperationMode: deviceData.Device.OperationMode,
|
|
159
|
+
VentilationMode: deviceData.Device.VentilationMode,
|
|
160
|
+
DefaultCoolingSetTemperature: deviceData.Device.DefaultCoolingSetTemperature,
|
|
161
|
+
DefaultHeatingSetTemperature: deviceData.Device.DefaultHeatingSetTemperature,
|
|
162
|
+
HideRoomTemperature: deviceData.Device.HideRoomTemperature,
|
|
163
|
+
HideSupplyTemperature: deviceData.Device.HideSupplyTemperature,
|
|
164
|
+
HideOutdoorTemperature: deviceData.Device.HideOutdoorTemperature,
|
|
165
|
+
NightPurgeMode: deviceData.Device.NightPurgeMode,
|
|
166
|
+
HasPendingCommand: true
|
|
187
167
|
}
|
|
188
168
|
|
|
189
|
-
|
|
169
|
+
if (this.logDebug) this.emit('debug', `Send Data: ${JSON.stringify(payload, null, 2)}`);
|
|
170
|
+
await axios(ApiUrls.SetErv, {
|
|
171
|
+
method: 'POST',
|
|
172
|
+
baseURL: ApiUrls.BaseURL,
|
|
173
|
+
timeout: 10000,
|
|
174
|
+
headers: deviceData.Headers,
|
|
175
|
+
data: payload
|
|
176
|
+
});
|
|
190
177
|
this.updateData(deviceData);
|
|
191
178
|
return true;
|
|
192
179
|
case "melcloudhome":
|
|
@@ -204,45 +191,36 @@ class MelCloudErv extends EventEmitter {
|
|
|
204
191
|
|
|
205
192
|
switch (effectiveFlags) {
|
|
206
193
|
case 'holidaymode':
|
|
207
|
-
payload = {
|
|
208
|
-
data: { enabled: deviceData.HolidayMode.Enabled, startDate: deviceData.HolidayMode.StartDate, endDate: deviceData.HolidayMode.EndDate, units: { "ERV": [deviceData.DeviceID] } }
|
|
209
|
-
};
|
|
194
|
+
payload = { enabled: deviceData.HolidayMode.Enabled, startDate: deviceData.HolidayMode.StartDate, endDate: deviceData.HolidayMode.EndDate, units: { "ERV": [deviceData.DeviceID] } };
|
|
210
195
|
method = 'POST';
|
|
211
196
|
path = ApiUrlsHome.PostHolidayMode;
|
|
212
197
|
break;
|
|
213
198
|
case 'schedule':
|
|
214
|
-
payload = {
|
|
215
|
-
data: {
|
|
216
|
-
enabled: deviceData.ScheduleEnabled
|
|
217
|
-
}
|
|
218
|
-
};
|
|
199
|
+
payload = { enabled: deviceData.ScheduleEnabled };
|
|
219
200
|
method = 'PUT';
|
|
220
201
|
path = ApiUrlsHome.PutScheduleEnable.replace('deviceid', deviceData.DeviceID);
|
|
221
202
|
break;
|
|
222
203
|
default:
|
|
223
204
|
payload = {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
VentilationMode: Ventilation.VentilationModeMapEnumToString[deviceData.Device.VentilationMode],
|
|
230
|
-
}
|
|
205
|
+
Power: deviceData.Device.Power,
|
|
206
|
+
SetTemperature: deviceData.Device.SetTemperature,
|
|
207
|
+
SetFanSpeed: String(deviceData.Device.SetFanSpeed),
|
|
208
|
+
OperationMode: Ventilation.OperationModeMapEnumToString[deviceData.Device.OperationMode],
|
|
209
|
+
VentilationMode: Ventilation.VentilationModeMapEnumToString[deviceData.Device.VentilationMode],
|
|
231
210
|
};
|
|
232
211
|
method = 'PUT';
|
|
233
212
|
path = ApiUrlsHome.SetErv.replace('deviceid', deviceData.DeviceID);
|
|
234
213
|
break
|
|
235
214
|
}
|
|
236
215
|
|
|
237
|
-
|
|
216
|
+
if (this.logDebug) this.emit('debug', `Send Data: ${JSON.stringify(payload, null, 2)}`);
|
|
217
|
+
await axios(path, {
|
|
238
218
|
method: method,
|
|
239
219
|
baseURL: ApiUrlsHome.BaseURL,
|
|
240
220
|
timeout: 10000,
|
|
241
|
-
headers: deviceData.Headers
|
|
221
|
+
headers: deviceData.Headers,
|
|
222
|
+
data: payload
|
|
242
223
|
});
|
|
243
|
-
|
|
244
|
-
if (this.logDebug) this.emit('debug', `Send Data: ${JSON.stringify(payload.data, null, 2)}`);
|
|
245
|
-
await axiosInstancePut(path, payload);
|
|
246
224
|
this.updateData(deviceData);
|
|
247
225
|
return true;
|
|
248
226
|
default:
|