homebridge-melcloud-control 2.5.0-beta.8 → 2.5.0-beta.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config.schema.json +1028 -1013
- package/homebridge-ui/public/index.html +125 -31
- package/homebridge-ui/server.js +11 -47
- package/index.js +123 -113
- package/package.json +1 -1
- package/src/deviceata.js +10 -10
- package/src/deviceatw.js +14 -14
- package/src/deviceerv.js +8 -8
- package/src/melcloud.js +73 -66
|
@@ -6,18 +6,45 @@
|
|
|
6
6
|
<div id="melCloudAccount" style="display: none;" class="card card-body">
|
|
7
7
|
<form id="configForm">
|
|
8
8
|
<div class="text-center">
|
|
9
|
-
<label id="accountName" style="font-size: 23px">Account
|
|
9
|
+
<label id="accountName" style="font-size: 23px">Account</label><br>
|
|
10
10
|
<label id="info" style="text-align: center; font-size: 17px;">MELCloud</label><br><br>
|
|
11
11
|
</div>
|
|
12
12
|
<div class="form-group">
|
|
13
13
|
<label for="name">Name</label>
|
|
14
14
|
<input id="name" type="text" class="form-control"><br>
|
|
15
|
-
<label for="user">
|
|
15
|
+
<label for="user">User Name</label>
|
|
16
16
|
<input id="user" type="text" class="form-control"><br>
|
|
17
|
-
<label for="passwd">
|
|
18
|
-
<input id="passwd" type="
|
|
17
|
+
<label for="passwd">Password</label>
|
|
18
|
+
<input id="passwd" type="password" class="form-control"><br>
|
|
19
19
|
<label for="language">Language</label>
|
|
20
|
-
<
|
|
20
|
+
<select id="language" name="language" class="form-control"><br>
|
|
21
|
+
<option value="0">English</option>
|
|
22
|
+
<option value="1">Български</option>
|
|
23
|
+
<option value="2">Čeština</option>
|
|
24
|
+
<option value="3">Dansk</option>
|
|
25
|
+
<option value="4">Deutsch</option>
|
|
26
|
+
<option value="5">Eesti</option>
|
|
27
|
+
<option value="6">Español</option>
|
|
28
|
+
<option value="7">Français</option>
|
|
29
|
+
<option value="8">Հայերեն</option>
|
|
30
|
+
<option value="9">Latviešu</option>
|
|
31
|
+
<option value="10">Lietuvių</option>
|
|
32
|
+
<option value="11">Magyar</option>
|
|
33
|
+
<option value="12">Nederlands</option>
|
|
34
|
+
<option value="13">Norwegian</option>
|
|
35
|
+
<option value="14">Polski</option>
|
|
36
|
+
<option value="15">Português</option>
|
|
37
|
+
<option value="16">Русский</option>
|
|
38
|
+
<option value="17">Suomi</option>
|
|
39
|
+
<option value="18">Svenska</option>
|
|
40
|
+
<option value="19">Svenska</option>
|
|
41
|
+
<option value="20">Українська</option>
|
|
42
|
+
<option value="21">Türkçe</option>
|
|
43
|
+
<option value="22">Ελληνικά</option>
|
|
44
|
+
<option value="23">Hrvatski</option>
|
|
45
|
+
<option value="24">Română</option>
|
|
46
|
+
<option value="25">Slovenščina</option>
|
|
47
|
+
</select>
|
|
21
48
|
</div>
|
|
22
49
|
<div class="text-center">
|
|
23
50
|
<button id="logIn" type="button" class="btn btn-primary">Connect to MELCloud</button>
|
|
@@ -56,6 +83,8 @@
|
|
|
56
83
|
const setRemoveAtribute = j === i ? document.getElementById(`button${j}`).setAttribute("class", "btn btn-secondary") : document.getElementById(`button${j}`).setAttribute("class", "btn btn-primary");
|
|
57
84
|
}
|
|
58
85
|
|
|
86
|
+
//const devicesCount = pluginConfig[0].accounts[i].devicesAta.length ?? 0;
|
|
87
|
+
//document.getElementById('info').innerHTML = `MELCloud configured ${devicesCount} ${devicesCount} ${devicesCount !== 1 ? 'devices' : 'device'}.`;
|
|
59
88
|
document.getElementById('accountName').innerHTML = pluginConfig[0].accounts[i].name || '';
|
|
60
89
|
document.getElementById('name').value = pluginConfig[0].accounts[i].name || '';
|
|
61
90
|
document.getElementById('user').value = pluginConfig[0].accounts[i].user || '';
|
|
@@ -63,7 +92,8 @@
|
|
|
63
92
|
document.getElementById('language').value = pluginConfig[0].accounts[i].language || '';
|
|
64
93
|
|
|
65
94
|
const accountConfigured = pluginConfig[0].accounts[i].name && pluginConfig[0].accounts[i].user && pluginConfig[0].accounts[i].passwd && pluginConfig[0].accounts[i].language;
|
|
66
|
-
const
|
|
95
|
+
const setButtonState = accountConfigured ? document.getElementById('logIn').removeAttribute('disabled') : document.getElementById('logIn').setAttribute('disabled');
|
|
96
|
+
document.getElementById('configButton').setAttribute('disabled');
|
|
67
97
|
await homebridge.updatePluginConfig(pluginConfig);
|
|
68
98
|
this.deviceIndex = i;
|
|
69
99
|
});
|
|
@@ -82,7 +112,7 @@
|
|
|
82
112
|
pluginConfig[0].accounts[this.deviceIndex].language = document.querySelector('#language').value;
|
|
83
113
|
|
|
84
114
|
const accountConfigured = pluginConfig[0].accounts[i].name && pluginConfig[0].accounts[i].user && pluginConfig[0].accounts[i].passwd && pluginConfig[0].accounts[i].language;
|
|
85
|
-
const
|
|
115
|
+
const setButtonState = accountConfigured ? document.getElementById('logIn').removeAttribute('disabled') : document.getElementById('logIn').setAttribute('disabled');
|
|
86
116
|
|
|
87
117
|
await homebridge.updatePluginConfig(pluginConfig);
|
|
88
118
|
await homebridge.savePluginConfig(pluginConfig);
|
|
@@ -106,55 +136,119 @@
|
|
|
106
136
|
const user = pluginConfig[0].accounts[this.deviceIndex].user;
|
|
107
137
|
const passwd = pluginConfig[0].accounts[this.deviceIndex].passwd;
|
|
108
138
|
const language = pluginConfig[0].accounts[this.deviceIndex].language;
|
|
109
|
-
const enableDebugMode = pluginConfig[0].accounts[this.deviceIndex].enableDebugMode;
|
|
110
|
-
const refreshInterval = pluginConfig[0].accounts[this.deviceIndex].refreshInterval;
|
|
111
139
|
|
|
112
140
|
const payload = {
|
|
113
141
|
accountName: accountName,
|
|
114
142
|
user: user,
|
|
115
143
|
passwd: passwd,
|
|
116
|
-
language: language
|
|
117
|
-
enableDebugMode: enableDebugMode,
|
|
118
|
-
refreshInterval: refreshInterval
|
|
144
|
+
language: language
|
|
119
145
|
};
|
|
120
146
|
const response = await homebridge.request('/connect', payload);
|
|
121
|
-
const info = response.info;
|
|
147
|
+
const info = response.info ?? '';
|
|
122
148
|
const status = response.status;
|
|
123
149
|
const devices = response.data ?? [];
|
|
150
|
+
const newDevices = [];
|
|
124
151
|
|
|
125
152
|
switch (status) {
|
|
126
153
|
case 0:
|
|
127
154
|
//get device info fom devices
|
|
128
|
-
|
|
155
|
+
devices.forEach((deviceInfo, index) => {
|
|
156
|
+
const deviceType = deviceInfo.Type;
|
|
129
157
|
const deviceId = deviceInfo.DeviceID;
|
|
130
158
|
const deviceName = deviceInfo.DeviceName;
|
|
131
|
-
};
|
|
132
159
|
|
|
133
|
-
|
|
160
|
+
//config account keys
|
|
161
|
+
const accountKeys = Object.keys(pluginConfig[0].accounts[this.deviceIndex]);
|
|
162
|
+
|
|
163
|
+
//devices ata
|
|
164
|
+
if (deviceType === 0) {
|
|
165
|
+
const deviceAta = {
|
|
166
|
+
name: deviceName,
|
|
167
|
+
id: deviceId,
|
|
168
|
+
type: deviceType,
|
|
169
|
+
displayMode: 0,
|
|
170
|
+
heatDryFanMode: 0,
|
|
171
|
+
coolDryFanMode: 0,
|
|
172
|
+
autoDryFanMode: 0,
|
|
173
|
+
presets: false,
|
|
174
|
+
temperatureSensor: false,
|
|
175
|
+
temperatureSensorOutdoor: false,
|
|
176
|
+
buttonsSensors: []
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const ataDevicesExist = pluginConfig[0].accounts[this.deviceIndex].ataDevices ?? false;
|
|
180
|
+
const ataDevices = ataDevicesExist ? pluginConfig[0].accounts[this.deviceIndex].ataDevices : pluginConfig[0].accounts[this.deviceIndex].ataDevices = [];
|
|
181
|
+
const ataDeviceIdExist = ataDevices.some(device => device.id === deviceId);
|
|
182
|
+
const pushTypeAta = ataDeviceIdExist ? false : ataDevices.push(deviceAta);
|
|
183
|
+
const pushNewDevice = ataDeviceIdExist ? false : newDevices.push(deviceId);
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
//devices atw
|
|
187
|
+
if (deviceType === 1) {
|
|
188
|
+
const deviceAtw = {
|
|
189
|
+
name: deviceName,
|
|
190
|
+
id: deviceId,
|
|
191
|
+
type: deviceType,
|
|
192
|
+
displayMode: 0,
|
|
193
|
+
temperatureSensor: false,
|
|
194
|
+
temperatureSensorFlow: false,
|
|
195
|
+
temperatureSensorReturn: false,
|
|
196
|
+
temperatureSensorFlowZone1: false,
|
|
197
|
+
temperatureSensorReturnZone1: false,
|
|
198
|
+
temperatureSensorFlowWaterTank: false,
|
|
199
|
+
temperatureSensorReturnWaterTank: false,
|
|
200
|
+
temperatureSensorFlowZone2: false,
|
|
201
|
+
temperatureSensorReturnZone2: false,
|
|
202
|
+
presets: false,
|
|
203
|
+
temperatureSensor: false,
|
|
204
|
+
temperatureSensorOutdoor: false,
|
|
205
|
+
buttonsSensors: []
|
|
206
|
+
};
|
|
207
|
+
const atwDevicesExist = pluginConfig[0].accounts[this.deviceIndex].atwDevices ?? false;
|
|
208
|
+
const atwDevices = atwDevicesExist ? pluginConfig[0].accounts[this.deviceIndex].atwDevices : pluginConfig[0].accounts[this.deviceIndex].atwDevices = [];
|
|
209
|
+
const atwDeviceIdExist = atwDevices.some(device => device.id === deviceId);
|
|
210
|
+
const pushTypeatw = atwDeviceIdExist ? false : atwDevices.push(deviceAtw);
|
|
211
|
+
const pushNewDevice = atwDeviceIdExist ? false : newDevices.push(deviceId);
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
//devices erv
|
|
215
|
+
if (deviceType === 3) {
|
|
216
|
+
const deviceErv = {
|
|
217
|
+
name: deviceName,
|
|
218
|
+
id: deviceId,
|
|
219
|
+
type: deviceType,
|
|
220
|
+
displayMode: 0,
|
|
221
|
+
temperatureSensor: false,
|
|
222
|
+
temperatureSensorOutdoor: false,
|
|
223
|
+
temperatureSensorSupply: false,
|
|
224
|
+
presets: false,
|
|
225
|
+
temperatureSensor: false,
|
|
226
|
+
temperatureSensorOutdoor: false,
|
|
227
|
+
buttonsSensors: []
|
|
228
|
+
};
|
|
229
|
+
const ervDevicesExist = pluginConfig[0].accounts[this.deviceIndex].ervDevices ?? false;
|
|
230
|
+
const ervDevices = ervDevicesExist ? pluginConfig[0].accounts[this.deviceIndex].ervDevices : pluginConfig[0].accounts[this.deviceIndex].ervDevices = [];
|
|
231
|
+
const ervDeviceIdExist = ervDevices.some(device => device.id === deviceId);
|
|
232
|
+
const pushTypeerv = ervDeviceIdExist ? false : ervDevices.push(deviceErv);
|
|
233
|
+
const pushNewDevice = ervDeviceIdExist ? false : newDevices.push(deviceId);
|
|
234
|
+
};
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
const devicesCount = newDevices.length;
|
|
238
|
+
document.getElementById('info').innerHTML = `Check devices complete, found ${devicesCount} ${devicesCount !== 1 ? 'new devices' : 'new device'}. ${devicesCount === 0 ? '' : 'Now You can start to configure it.'}`;
|
|
134
239
|
document.getElementById('info').style.color = 'green';
|
|
240
|
+
|
|
135
241
|
await homebridge.updatePluginConfig(pluginConfig);
|
|
136
242
|
await homebridge.savePluginConfig(pluginConfig);
|
|
137
243
|
break;
|
|
138
244
|
case 1:
|
|
139
245
|
document.getElementById('info').innerHTML = info;
|
|
140
|
-
document.getElementById('info').style.color = '
|
|
141
|
-
break;
|
|
142
|
-
case 2:
|
|
143
|
-
document.getElementById('info').innerHTML = info;
|
|
144
|
-
document.getElementById('info').style.color = 'white';
|
|
145
|
-
break;
|
|
146
|
-
case 3:
|
|
147
|
-
document.getElementById('info').innerHTML = info;
|
|
148
|
-
document.getElementById('info').style.color = 'gray';
|
|
246
|
+
document.getElementById('info').style.color = 'red';
|
|
149
247
|
break;
|
|
150
|
-
|
|
151
|
-
document.getElementById('info').innerHTML =
|
|
248
|
+
default:
|
|
249
|
+
document.getElementById('info').innerHTML = `Received unknown status: ${status}, please try again.`;
|
|
152
250
|
document.getElementById('info').style.color = 'yellow';
|
|
153
251
|
break;
|
|
154
|
-
case 5:
|
|
155
|
-
document.getElementById('info').innerHTML = info;
|
|
156
|
-
document.getElementById('info').style.color = 'red';
|
|
157
|
-
break;
|
|
158
252
|
};
|
|
159
253
|
|
|
160
254
|
homebridge.hideSpinner();
|
package/homebridge-ui/server.js
CHANGED
|
@@ -19,62 +19,26 @@ class PluginUiServer extends HomebridgePluginUiServer {
|
|
|
19
19
|
const user = payload.user;
|
|
20
20
|
const passwd = payload.passwd;
|
|
21
21
|
const language = payload.language;
|
|
22
|
-
const enableDebugMode = payload.enableDebugMode;
|
|
23
|
-
const refreshInterval = payload.refreshInterval;
|
|
24
22
|
const accountInfoFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Account`;
|
|
25
23
|
const deviceInfoFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Device_`;
|
|
26
24
|
const buildingsFile = `${this.homebridgeStoragePath}/melcloud/${accountName}_Buildings`;
|
|
27
|
-
let data = {};
|
|
28
25
|
|
|
29
26
|
try {
|
|
30
|
-
|
|
31
|
-
melCloud
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
data = {
|
|
40
|
-
info: message,
|
|
41
|
-
status: 1
|
|
42
|
-
};
|
|
43
|
-
})
|
|
44
|
-
.on('message', (message) => {
|
|
45
|
-
data = {
|
|
46
|
-
info: message,
|
|
47
|
-
status: 2
|
|
48
|
-
};
|
|
49
|
-
})
|
|
50
|
-
.on('debug', (debug) => {
|
|
51
|
-
data = {
|
|
52
|
-
info: debug,
|
|
53
|
-
status: 3
|
|
54
|
-
};
|
|
55
|
-
})
|
|
56
|
-
.on('warn', (warn) => {
|
|
57
|
-
data = {
|
|
58
|
-
info: warn,
|
|
59
|
-
status: 4
|
|
60
|
-
};
|
|
61
|
-
})
|
|
62
|
-
.on('error', async (error) => {
|
|
63
|
-
data = {
|
|
64
|
-
info: error,
|
|
65
|
-
status: 5
|
|
66
|
-
};
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
return data;
|
|
27
|
+
let data = {};
|
|
28
|
+
const melCloud = new MelCloud(user, passwd, language, accountInfoFile, deviceInfoFile, buildingsFile, false, 0, true);
|
|
29
|
+
const contextKey = await melCloud.connect();
|
|
30
|
+
const devices = await melCloud.chackDevicesList(contextKey);
|
|
31
|
+
return data = {
|
|
32
|
+
info: '',
|
|
33
|
+
status: 0,
|
|
34
|
+
data: devices
|
|
35
|
+
};
|
|
70
36
|
} catch (error) {
|
|
71
|
-
data = {
|
|
37
|
+
return data = {
|
|
72
38
|
info: error,
|
|
73
|
-
status:
|
|
39
|
+
status: 1
|
|
74
40
|
};
|
|
75
|
-
return data;
|
|
76
41
|
};
|
|
77
|
-
|
|
78
42
|
};
|
|
79
43
|
};
|
|
80
44
|
|
package/index.js
CHANGED
|
@@ -38,11 +38,6 @@ class MelCloudPlatform {
|
|
|
38
38
|
}
|
|
39
39
|
accountsName.push(accountName);
|
|
40
40
|
|
|
41
|
-
//hide devices
|
|
42
|
-
const ataHideDeviceById = account.ataHideDeviceById || [];
|
|
43
|
-
const atwHideDeviceById = account.atwHideDeviceById || [];
|
|
44
|
-
const ervHideDeviceById = account.ervHideDeviceById || [];
|
|
45
|
-
|
|
46
41
|
//debug config
|
|
47
42
|
const enableDebugMode = account.enableDebugMode || false;
|
|
48
43
|
const debug = enableDebugMode ? log.info(`Account: ${accountName}, did finish launching.`) : false;
|
|
@@ -62,7 +57,7 @@ class MelCloudPlatform {
|
|
|
62
57
|
const prefDir = path.join(api.user.storagePath(), 'melcloud');
|
|
63
58
|
const accountInfoFile = `${prefDir}/${accountName}_Account`;
|
|
64
59
|
const buildingsFile = `${prefDir}/${accountName}_Buildings`;
|
|
65
|
-
const
|
|
60
|
+
const deviceFile = `${prefDir}/${accountName}_Device_`;
|
|
66
61
|
|
|
67
62
|
//create directory if it doesn't exist
|
|
68
63
|
try {
|
|
@@ -78,116 +73,131 @@ class MelCloudPlatform {
|
|
|
78
73
|
const deviceRefreshInterval = account.deviceRefreshInterval * 1000 || 5000;
|
|
79
74
|
|
|
80
75
|
//melcloud account
|
|
81
|
-
const melCloud = new MelCloud(user, passwd, language, accountInfoFile, buildingsFile,
|
|
82
|
-
melCloud.on('checkDevicesListComplete', (accountInfo, contextKey
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
76
|
+
const melCloud = new MelCloud(user, passwd, language, accountInfoFile, buildingsFile, deviceFile, enableDebugMode, refreshInterval, false);
|
|
77
|
+
melCloud.on('checkDevicesListComplete', (accountInfo, contextKey) => {
|
|
78
|
+
|
|
79
|
+
//Air Conditioner
|
|
80
|
+
for (const device of account.ataDevices) {
|
|
81
|
+
const id = device.id ?? false;
|
|
82
|
+
|
|
83
|
+
//check id exist
|
|
84
|
+
if (!id) {
|
|
85
|
+
continue;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const deviceId = id.toString();
|
|
89
|
+
const deviceType = device.type;
|
|
90
|
+
const deviceName = device.name;
|
|
91
|
+
const deviceTypeText = CONSTANTS.DeviceType[deviceType];
|
|
92
|
+
const deviceInfoFile = `${prefDir}/${accountName}_Device_${deviceId}`;
|
|
93
|
+
const airConditioner = new DeviceAta(api, account, device, melCloud, accountInfo, contextKey, accountName, deviceId, deviceName, deviceTypeText, accountInfoFile, deviceInfoFile, deviceRefreshInterval)
|
|
94
|
+
airConditioner.on('publishAccessory', (accessory) => {
|
|
95
|
+
|
|
96
|
+
//publish device
|
|
97
|
+
api.publishExternalAccessories(CONSTANTS.PluginName, [accessory]);
|
|
98
|
+
log.success(`${accountName}, ${deviceTypeText} ${deviceName}, published as external accessory.`);
|
|
99
|
+
})
|
|
100
|
+
.on('devInfo', (devInfo) => {
|
|
101
|
+
log.info(devInfo);
|
|
103
102
|
})
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
})
|
|
107
|
-
.on('success', (message) => {
|
|
108
|
-
log.success(`${deviceTypeText}, ${deviceName}, ${message}`);
|
|
109
|
-
})
|
|
110
|
-
.on('message', (message) => {
|
|
111
|
-
log.info(`${deviceTypeText}, ${deviceName}, ${message}`);
|
|
112
|
-
})
|
|
113
|
-
.on('debug', (debug) => {
|
|
114
|
-
log.info(`${deviceTypeText}, ${deviceName}, debug: ${debug}`);
|
|
115
|
-
})
|
|
116
|
-
.on('warn', (warn) => {
|
|
117
|
-
log.warn(`${deviceTypeText}, ${deviceName}, ${warn}`);
|
|
118
|
-
})
|
|
119
|
-
.on('error', (error) => {
|
|
120
|
-
log.error(`${deviceTypeText}, ${deviceName}, ${error}`);
|
|
121
|
-
});
|
|
122
|
-
break;
|
|
123
|
-
case 1: //Heat Pump
|
|
124
|
-
const atwHideDevice = atwHideDeviceById.some(device => device.id === deviceId) ?? false;
|
|
125
|
-
if (atwHideDevice) {
|
|
126
|
-
return;
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
const heatPump = new DeviceAtw(api, account, melCloud, accountInfo, accountName, contextKey, deviceId, deviceName, deviceTypeText, accountInfoFile, deviceInfoFile, deviceRefreshInterval)
|
|
130
|
-
heatPump.on('publishAccessory', (accessory) => {
|
|
131
|
-
|
|
132
|
-
//publish device
|
|
133
|
-
api.publishExternalAccessories(CONSTANTS.PluginName, [accessory]);
|
|
134
|
-
log.success(`${accountName}, ${deviceTypeText} ${deviceName}, published as external accessory.`);
|
|
103
|
+
.on('success', (message) => {
|
|
104
|
+
log.success(`${deviceTypeText}, ${deviceName}, ${message}`);
|
|
135
105
|
})
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
})
|
|
139
|
-
.on('success', (message) => {
|
|
140
|
-
log.success(`${deviceTypeText}, ${deviceName}, ${message}`);
|
|
141
|
-
})
|
|
142
|
-
.on('message', (message) => {
|
|
143
|
-
log.info(`${deviceTypeText}, ${deviceName}, ${message}`);
|
|
144
|
-
})
|
|
145
|
-
.on('debug', (debug) => {
|
|
146
|
-
log.info(`${deviceTypeText}, ${deviceName}, debug: ${debug}`);
|
|
147
|
-
})
|
|
148
|
-
.on('warn', (warn) => {
|
|
149
|
-
log.warn(`${deviceTypeText}, ${deviceName}, ${warn}`);
|
|
150
|
-
})
|
|
151
|
-
.on('error', (error) => {
|
|
152
|
-
log.error(`${deviceTypeText}, ${deviceName}, ${error}`);
|
|
153
|
-
});
|
|
154
|
-
break;
|
|
155
|
-
case 3: //Energy Recovery Ventilation
|
|
156
|
-
const ervHideDevice = ervHideDeviceById.some(device => device.id === deviceId) ?? false;
|
|
157
|
-
if (ervHideDevice) {
|
|
158
|
-
return;
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
const energyRecoveryVentilation = new DeviceErv(api, account, melCloud, accountInfo, accountName, contextKey, deviceId, deviceName, deviceTypeText, accountInfoFile, deviceInfoFile, deviceRefreshInterval)
|
|
162
|
-
energyRecoveryVentilation.on('publishAccessory', (accessory) => {
|
|
163
|
-
|
|
164
|
-
//publish device
|
|
165
|
-
api.publishExternalAccessories(CONSTANTS.PluginName, [accessory]);
|
|
166
|
-
log.success(`${accountName}, ${deviceTypeText} ${deviceName}, published as external accessory.`);
|
|
106
|
+
.on('message', (message) => {
|
|
107
|
+
log.info(`${deviceTypeText}, ${deviceName}, ${message}`);
|
|
167
108
|
})
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
109
|
+
.on('debug', (debug) => {
|
|
110
|
+
log.info(`${deviceTypeText}, ${deviceName}, debug: ${debug}`);
|
|
111
|
+
})
|
|
112
|
+
.on('warn', (warn) => {
|
|
113
|
+
log.warn(`${deviceTypeText}, ${deviceName}, ${warn}`);
|
|
114
|
+
})
|
|
115
|
+
.on('error', (error) => {
|
|
116
|
+
log.error(`${deviceTypeText}, ${deviceName}, ${error}`);
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
//Heat Pump
|
|
121
|
+
for (const device of account.atwDevices) {
|
|
122
|
+
const id = device.id ?? false;
|
|
123
|
+
|
|
124
|
+
//check id exist
|
|
125
|
+
if (!id) {
|
|
126
|
+
continue;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const deviceId = id.toString();
|
|
130
|
+
const deviceType = device.type;
|
|
131
|
+
const deviceName = device.name;
|
|
132
|
+
const deviceTypeText = CONSTANTS.DeviceType[deviceType];
|
|
133
|
+
const deviceInfoFile = `${prefDir}/${accountName}_Device_${deviceId}`;
|
|
134
|
+
const heatPump = new DeviceAtw(api, account, melCloud, device, accountInfo, contextKey, accountName, deviceId, deviceName, deviceTypeText, accountInfoFile, deviceInfoFile, deviceRefreshInterval)
|
|
135
|
+
heatPump.on('publishAccessory', (accessory) => {
|
|
136
|
+
|
|
137
|
+
//publish device
|
|
138
|
+
api.publishExternalAccessories(CONSTANTS.PluginName, [accessory]);
|
|
139
|
+
log.success(`${accountName}, ${deviceTypeText} ${deviceName}, published as external accessory.`);
|
|
140
|
+
})
|
|
141
|
+
.on('devInfo', (devInfo) => {
|
|
142
|
+
log.info(devInfo);
|
|
143
|
+
})
|
|
144
|
+
.on('success', (message) => {
|
|
145
|
+
log.success(`${deviceTypeText}, ${deviceName}, ${message}`);
|
|
146
|
+
})
|
|
147
|
+
.on('message', (message) => {
|
|
148
|
+
log.info(`${deviceTypeText}, ${deviceName}, ${message}`);
|
|
149
|
+
})
|
|
150
|
+
.on('debug', (debug) => {
|
|
151
|
+
log.info(`${deviceTypeText}, ${deviceName}, debug: ${debug}`);
|
|
152
|
+
})
|
|
153
|
+
.on('warn', (warn) => {
|
|
154
|
+
log.warn(`${deviceTypeText}, ${deviceName}, ${warn}`);
|
|
155
|
+
})
|
|
156
|
+
.on('error', (error) => {
|
|
157
|
+
log.error(`${deviceTypeText}, ${deviceName}, ${error}`);
|
|
158
|
+
});
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
//Energy Recovery Ventilation
|
|
162
|
+
for (const device of account.ervDevices) {
|
|
163
|
+
const id = device.id ?? false;
|
|
164
|
+
|
|
165
|
+
//check id exist
|
|
166
|
+
if (!id) {
|
|
167
|
+
continue;
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const deviceId = id.toString();
|
|
171
|
+
const deviceType = device.type;
|
|
172
|
+
const deviceName = device.name;
|
|
173
|
+
const deviceTypeText = CONSTANTS.DeviceType[deviceType];
|
|
174
|
+
const deviceInfoFile = `${prefDir}/${accountName}_Device_${deviceId}`;
|
|
175
|
+
const energyRecoveryVentilation = new DeviceErv(api, account, device, melCloud, accountInfo, contextKey, accountName, deviceId, deviceName, deviceTypeText, accountInfoFile, deviceInfoFile, deviceRefreshInterval)
|
|
176
|
+
energyRecoveryVentilation.on('publishAccessory', (accessory) => {
|
|
177
|
+
|
|
178
|
+
//publish device
|
|
179
|
+
api.publishExternalAccessories(CONSTANTS.PluginName, [accessory]);
|
|
180
|
+
log.success(`${accountName}, ${deviceTypeText} ${deviceName}, published as external accessory.`);
|
|
181
|
+
})
|
|
182
|
+
.on('devInfo', (devInfo) => {
|
|
183
|
+
log.info(devInfo);
|
|
184
|
+
})
|
|
185
|
+
.on('success', (message) => {
|
|
186
|
+
log.success(`${deviceTypeText}, ${deviceName}, ${message}`);
|
|
187
|
+
})
|
|
188
|
+
.on('message', (message) => {
|
|
189
|
+
log.info(`${deviceTypeText}, ${deviceName}, ${message}`);
|
|
190
|
+
})
|
|
191
|
+
.on('debug', (debug) => {
|
|
192
|
+
log.info(`${deviceTypeText}, ${deviceName}, debug: ${debug}`);
|
|
193
|
+
})
|
|
194
|
+
.on('warn', (warn) => {
|
|
195
|
+
log.warn(`${deviceTypeText}, ${deviceName}, ${warn}`);
|
|
196
|
+
})
|
|
197
|
+
.on('error', (error) => {
|
|
198
|
+
log.error(`${deviceTypeText}, ${deviceName}, ${error}`);
|
|
199
|
+
});
|
|
200
|
+
};
|
|
191
201
|
})
|
|
192
202
|
.on('success', (message) => {
|
|
193
203
|
log.success(`Account ${accountName}, ${message}`);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"displayName": "MELCloud Control",
|
|
3
3
|
"name": "homebridge-melcloud-control",
|
|
4
|
-
"version": "2.5.0-beta.
|
|
4
|
+
"version": "2.5.0-beta.80",
|
|
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 @@ const CONSTANTS = require('./constants.json');
|
|
|
7
7
|
let Accessory, Characteristic, Service, Categories, AccessoryUUID;
|
|
8
8
|
|
|
9
9
|
class DeviceAta extends EventEmitter {
|
|
10
|
-
constructor(api, account, melCloud, accountInfo,
|
|
10
|
+
constructor(api, account, device, melCloud, accountInfo, contextKey, accountName, deviceId, deviceName, deviceTypeText, accountInfoFile, deviceInfoFile, refreshInterval) {
|
|
11
11
|
super();
|
|
12
12
|
|
|
13
13
|
Accessory = api.platformAccessory;
|
|
@@ -17,14 +17,14 @@ class DeviceAta extends EventEmitter {
|
|
|
17
17
|
AccessoryUUID = api.hap.uuid;
|
|
18
18
|
|
|
19
19
|
//account config
|
|
20
|
-
this.displayMode =
|
|
21
|
-
this.temperatureSensor =
|
|
22
|
-
this.temperatureSensorOutdoor =
|
|
23
|
-
this.presetsEnabled =
|
|
24
|
-
this.heatDryFanMode =
|
|
25
|
-
this.coolDryFanMode =
|
|
26
|
-
this.autoDryFanMode =
|
|
27
|
-
this.buttons =
|
|
20
|
+
this.displayMode = device.displayMode || 0;
|
|
21
|
+
this.temperatureSensor = device.temperatureSensor || false;
|
|
22
|
+
this.temperatureSensorOutdoor = device.temperatureSensorOutdoor || false;
|
|
23
|
+
this.presetsEnabled = device.presets || false;
|
|
24
|
+
this.heatDryFanMode = device.heatDryFanMode || 1; //NONE, HEAT, DRY, FAN
|
|
25
|
+
this.coolDryFanMode = device.coolDryFanMode || 1; //NONE, COOL, DRY, FAN
|
|
26
|
+
this.autoDryFanMode = device.autoDryFanMode || 1; //NONE, AUTO, DRY, FAN
|
|
27
|
+
this.buttons = device.buttons || [];
|
|
28
28
|
this.disableLogInfo = account.disableLogInfo || false;
|
|
29
29
|
this.disableLogDeviceInfo = account.disableLogDeviceInfo || false;
|
|
30
30
|
this.enableDebugMode = account.enableDebugMode || false;
|
|
@@ -69,7 +69,7 @@ class DeviceAta extends EventEmitter {
|
|
|
69
69
|
accountInfoFile: accountInfoFile,
|
|
70
70
|
deviceInfoFile: deviceInfoFile,
|
|
71
71
|
debugLog: account.enableDebugMode,
|
|
72
|
-
refreshInterval:
|
|
72
|
+
refreshInterval: refreshInterval
|
|
73
73
|
});
|
|
74
74
|
|
|
75
75
|
this.melCloudAta.on('externalIntegrations', (deviceData, deviceState) => {
|
package/src/deviceatw.js
CHANGED
|
@@ -7,7 +7,7 @@ const CONSTANTS = require('./constants.json');
|
|
|
7
7
|
let Accessory, Characteristic, Service, Categories, AccessoryUUID;
|
|
8
8
|
|
|
9
9
|
class DeviceAtw extends EventEmitter {
|
|
10
|
-
constructor(api, account, melCloud, accountInfo,
|
|
10
|
+
constructor(api, account, device, melCloud, accountInfo, contextKey, accountName, deviceId, deviceName, deviceTypeText, accountInfoFile, deviceInfoFile, refreshInterval) {
|
|
11
11
|
super();
|
|
12
12
|
|
|
13
13
|
Accessory = api.platformAccessory;
|
|
@@ -17,18 +17,18 @@ class DeviceAtw extends EventEmitter {
|
|
|
17
17
|
AccessoryUUID = api.hap.uuid;
|
|
18
18
|
|
|
19
19
|
//account config
|
|
20
|
-
this.displayMode =
|
|
21
|
-
this.temperatureSensor =
|
|
22
|
-
this.temperatureSensorFlow =
|
|
23
|
-
this.temperatureSensorReturn =
|
|
24
|
-
this.temperatureSensorFlowZone1 =
|
|
25
|
-
this.temperatureSensorReturnZone1 =
|
|
26
|
-
this.temperatureSensorFlowWaterTank =
|
|
27
|
-
this.temperatureSensorReturnWaterTank =
|
|
28
|
-
this.temperatureSensorFlowZone2 =
|
|
29
|
-
this.temperatureSensorReturnZone2 =
|
|
30
|
-
this.presetsEnabled =
|
|
31
|
-
this.buttons =
|
|
20
|
+
this.displayMode = device.displayMode || 0;
|
|
21
|
+
this.temperatureSensor = device.temperatureSensor || false;
|
|
22
|
+
this.temperatureSensorFlow = device.temperatureSensorFlow || false;
|
|
23
|
+
this.temperatureSensorReturn = device.temperatureSensorReturn || false;
|
|
24
|
+
this.temperatureSensorFlowZone1 = device.temperatureSensorFlowZone1 || false;
|
|
25
|
+
this.temperatureSensorReturnZone1 = device.temperatureSensorFlowWaterTank || false;
|
|
26
|
+
this.temperatureSensorFlowWaterTank = device.temperatureSensorFlowZone1 || false;
|
|
27
|
+
this.temperatureSensorReturnWaterTank = device.temperatureSensorReturnWaterTank || false;
|
|
28
|
+
this.temperatureSensorFlowZone2 = device.temperatureSensorFlowZone2 || false;
|
|
29
|
+
this.temperatureSensorReturnZone2 = device.temperatureSensorReturnZone2 || false;
|
|
30
|
+
this.presetsEnabled = device.presets || false;
|
|
31
|
+
this.buttons = device.buttons || [];
|
|
32
32
|
this.disableLogInfo = account.disableLogInfo || false;
|
|
33
33
|
this.disableLogDeviceInfo = account.disableLogDeviceInfo || false;
|
|
34
34
|
this.enableDebugMode = account.enableDebugMode || false;
|
|
@@ -73,7 +73,7 @@ class DeviceAtw extends EventEmitter {
|
|
|
73
73
|
accountInfoFile: accountInfoFile,
|
|
74
74
|
deviceInfoFile: deviceInfoFile,
|
|
75
75
|
debugLog: account.enableDebugMode,
|
|
76
|
-
refreshInterval:
|
|
76
|
+
refreshInterval: refreshInterval
|
|
77
77
|
});
|
|
78
78
|
|
|
79
79
|
this.melCloudAtw.on('externalIntegrations', (deviceData, deviceState) => {
|