homebridge-melcloud-control 4.2.5-beta.3 → 4.2.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/CHANGELOG.md +11 -0
- package/README.md +22 -21
- package/config.schema.json +11 -11
- package/index.js +6 -15
- package/package.json +1 -1
- package/src/constants.js +1 -0
- package/src/deviceata.js +20 -19
- package/src/deviceatw.js +21 -23
- package/src/deviceerv.js +21 -20
- package/src/melcloud.js +11 -28
- package/src/melcloudata.js +47 -41
- package/src/melcloudatw.js +47 -40
- package/src/melclouderv.js +59 -52
- package/src/melcloudhome.js +27 -52
package/src/deviceerv.js
CHANGED
|
@@ -6,7 +6,7 @@ import { TemperatureDisplayUnits, Ventilation } from './constants.js';
|
|
|
6
6
|
let Accessory, Characteristic, Service, Categories, AccessoryUUID;
|
|
7
7
|
|
|
8
8
|
class DeviceErv extends EventEmitter {
|
|
9
|
-
constructor(api, account, device, devicesFile, defaultTempsFile,
|
|
9
|
+
constructor(api, account, device, devicesFile, defaultTempsFile, accountInfo, accountFile) {
|
|
10
10
|
super();
|
|
11
11
|
|
|
12
12
|
Accessory = api.platformAccessory;
|
|
@@ -43,6 +43,8 @@ class DeviceErv extends EventEmitter {
|
|
|
43
43
|
this.deviceTypeText = device.typeString;
|
|
44
44
|
this.devicesFile = devicesFile;
|
|
45
45
|
this.defaultTempsFile = defaultTempsFile;
|
|
46
|
+
this.accountInfo = accountInfo;
|
|
47
|
+
this.accountFile = accountFile;
|
|
46
48
|
this.displayDeviceInfo = true;
|
|
47
49
|
|
|
48
50
|
//external integrations
|
|
@@ -93,7 +95,6 @@ class DeviceErv extends EventEmitter {
|
|
|
93
95
|
|
|
94
96
|
//accessory
|
|
95
97
|
this.accessory = {};
|
|
96
|
-
this.useFahrenheit = useFahrenheit ? 1 : 0;
|
|
97
98
|
};
|
|
98
99
|
|
|
99
100
|
async externalIntegrations() {
|
|
@@ -455,10 +456,10 @@ class DeviceErv extends EventEmitter {
|
|
|
455
456
|
if (this.account.type === 'melcloudhome') return;
|
|
456
457
|
|
|
457
458
|
try {
|
|
458
|
-
|
|
459
|
-
this.accessory.useFahrenheit = value;
|
|
459
|
+
this.accessory.useFahrenheit = value ? true : false;
|
|
460
460
|
if (this.logInfo) this.emit('info', `Set temperature display unit: ${TemperatureDisplayUnits[value]}`);
|
|
461
|
-
this.
|
|
461
|
+
this.accountInfo.UseFahrenheit = value ? true : false;
|
|
462
|
+
await this.melCloudErv.send(this.accountType, this.displayType, deviceData, 'account', this.accountInfo);
|
|
462
463
|
} catch (error) {
|
|
463
464
|
if (this.logWarn) this.emit('warn', `Set temperature display unit error: ${error}`);
|
|
464
465
|
};
|
|
@@ -548,10 +549,10 @@ class DeviceErv extends EventEmitter {
|
|
|
548
549
|
if (this.account.type === 'melcloudhome') return;
|
|
549
550
|
|
|
550
551
|
try {
|
|
551
|
-
|
|
552
|
-
this.accessory.useFahrenheit = value;
|
|
552
|
+
this.accessory.useFahrenheit = value ? true : false;
|
|
553
553
|
if (this.logInfo) this.emit('info', `Set temperature display unit: ${TemperatureDisplayUnits[value]}`);
|
|
554
|
-
this.
|
|
554
|
+
this.accountInfo.UseFahrenheit = value ? true : false;
|
|
555
|
+
await this.melCloudErv.send(this.accountType, this.displayType, deviceData, 'account', this.accountInfo);
|
|
555
556
|
} catch (error) {
|
|
556
557
|
if (this.logWarn) this.emit('warn', `Set temperature display unit error: ${error}`);
|
|
557
558
|
};
|
|
@@ -741,7 +742,7 @@ class DeviceErv extends EventEmitter {
|
|
|
741
742
|
.onSet(async (state) => {
|
|
742
743
|
try {
|
|
743
744
|
deviceData.HolidayMode.Enabled = state;
|
|
744
|
-
if (this.logInfo) this.emit('info', `Holiday mode: ${state ? '
|
|
745
|
+
if (this.logInfo) this.emit('info', `Holiday mode: ${state ? 'Enabled' : 'Disabled'}`);
|
|
745
746
|
await this.melCloudErv.send(this.accountType, this.displayType, deviceData, 'holidaymode');
|
|
746
747
|
} catch (error) {
|
|
747
748
|
if (this.logWarn) this.emit('warn', `Set holiday mode error: ${error}`);
|
|
@@ -823,7 +824,7 @@ class DeviceErv extends EventEmitter {
|
|
|
823
824
|
break;
|
|
824
825
|
};
|
|
825
826
|
|
|
826
|
-
if (this.logInfo) this.emit('info', `Preset ${name}: ${state ? 'Set
|
|
827
|
+
if (this.logInfo) this.emit('info', `Preset ${name}: ${state ? 'Set' : 'Unset'}`);
|
|
827
828
|
await this.melCloudErv.send(this.accountType, this.displayType, deviceData, AirConditioner.EffectiveFlags.Presets);
|
|
828
829
|
} catch (error) {
|
|
829
830
|
if (this.logWarn) this.emit('warn', `Set preset error: ${error}`);
|
|
@@ -880,7 +881,7 @@ class DeviceErv extends EventEmitter {
|
|
|
880
881
|
.onSet(async (state) => {
|
|
881
882
|
try {
|
|
882
883
|
deviceData.ScheduleEnabled = state;
|
|
883
|
-
if (this.logInfo) this.emit('info', `Schedules: ${state ? '
|
|
884
|
+
if (this.logInfo) this.emit('info', `Schedules: ${state ? 'Enabled' : 'Disabled'}`);
|
|
884
885
|
await this.melCloudErv.send(this.accountType, this.displayType, deviceData, 'schedule');
|
|
885
886
|
} catch (error) {
|
|
886
887
|
if (this.logWarn) this.emit('warn', `Set schedule serror: ${error}`);
|
|
@@ -949,7 +950,7 @@ class DeviceErv extends EventEmitter {
|
|
|
949
950
|
.onSet(async (state) => {
|
|
950
951
|
try {
|
|
951
952
|
sceneData.Enabled = state;
|
|
952
|
-
if (this.logInfo) this.emit('info', `Scene ${name}: ${state ? '
|
|
953
|
+
if (this.logInfo) this.emit('info', `Scene ${name}: ${state ? 'Set' : 'Unset'}`);
|
|
953
954
|
await this.melCloudErv.send(this.accountType, this.displayType, deviceData, 'scene', sceneData);
|
|
954
955
|
} catch (error) {
|
|
955
956
|
if (this.logWarn) this.emit('warn', `Set scene error: ${error}`);
|
|
@@ -983,12 +984,12 @@ class DeviceErv extends EventEmitter {
|
|
|
983
984
|
const mode = button.mode;
|
|
984
985
|
|
|
985
986
|
//get button name
|
|
986
|
-
const
|
|
987
|
+
const name = button.name;
|
|
987
988
|
|
|
988
989
|
//get button name prefix
|
|
989
990
|
const namePrefix = button.namePrefix;
|
|
990
991
|
|
|
991
|
-
const serviceName1 = namePrefix ? `${accessoryName} ${
|
|
992
|
+
const serviceName1 = namePrefix ? `${accessoryName} ${name}` : name;
|
|
992
993
|
const serviceType = button.serviceType;
|
|
993
994
|
const characteristicType = button.characteristicType;
|
|
994
995
|
|
|
@@ -1082,7 +1083,7 @@ class DeviceErv extends EventEmitter {
|
|
|
1082
1083
|
break;
|
|
1083
1084
|
};
|
|
1084
1085
|
|
|
1085
|
-
if (this.logInfo) this.emit('info',
|
|
1086
|
+
if (this.logInfo) this.emit('info', `Button ${name}: ${state ? `Enabled` : `Disabled`}`);
|
|
1086
1087
|
await this.melCloudErv.send(this.accountType, this.displayType, deviceData, flag);
|
|
1087
1088
|
} catch (error) {
|
|
1088
1089
|
if (this.logWarn) this.emit('warn', `Set button error: ${error}`);
|
|
@@ -1094,9 +1095,9 @@ class DeviceErv extends EventEmitter {
|
|
|
1094
1095
|
|
|
1095
1096
|
//sensor
|
|
1096
1097
|
if (this.logDebug) this.emit('debug', `Prepare button control sensor ${name} service`);
|
|
1097
|
-
const buttonControlSensorService = new serviceType(
|
|
1098
|
+
const buttonControlSensorService = new serviceType(serviceName1, `buttonControlSensorService${deviceId} ${i}`);
|
|
1098
1099
|
buttonControlSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
1099
|
-
buttonControlSensorService.setCharacteristic(Characteristic.ConfiguredName,
|
|
1100
|
+
buttonControlSensorService.setCharacteristic(Characteristic.ConfiguredName, serviceName1);
|
|
1100
1101
|
buttonControlSensorService.getCharacteristic(characteristicType)
|
|
1101
1102
|
.onGet(async () => {
|
|
1102
1103
|
const state = button.state;
|
|
@@ -1117,7 +1118,7 @@ class DeviceErv extends EventEmitter {
|
|
|
1117
1118
|
async start() {
|
|
1118
1119
|
try {
|
|
1119
1120
|
//melcloud device
|
|
1120
|
-
this.melCloudErv = new MelCloudErv(this.account, this.device, this.devicesFile, this.defaultTempsFile)
|
|
1121
|
+
this.melCloudErv = new MelCloudErv(this.account, this.device, this.devicesFile, this.defaultTempsFile, this.accountFile)
|
|
1121
1122
|
.on('deviceInfo', (modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion) => {
|
|
1122
1123
|
if (this.logDeviceInfo && this.displayDeviceInfo) {
|
|
1123
1124
|
this.emit('devInfo', `---- ${this.deviceTypeText}: ${this.deviceName} ----`);
|
|
@@ -1251,8 +1252,8 @@ class DeviceErv extends EventEmitter {
|
|
|
1251
1252
|
temperatureIncrement: maxTempHeat,
|
|
1252
1253
|
minTempCoolDry: minTempCoolDry,
|
|
1253
1254
|
maxTempCoolDry: maxTempCoolDry,
|
|
1254
|
-
useFahrenheit: this.useFahrenheit,
|
|
1255
|
-
temperatureUnit: TemperatureDisplayUnits[this.useFahrenheit],
|
|
1255
|
+
useFahrenheit: this.accountInfo.useFahrenheit ? 1 : 0,
|
|
1256
|
+
temperatureUnit: TemperatureDisplayUnits[this.accountInfo.useFahrenheit ? 1 : 0],
|
|
1256
1257
|
isConnected: isConnected,
|
|
1257
1258
|
isInError: isInError,
|
|
1258
1259
|
scheduleEnabled: scheduleEnabled,
|
package/src/melcloud.js
CHANGED
|
@@ -52,17 +52,11 @@ class MelCloud extends EventEmitter {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
// MELCloud
|
|
56
55
|
async checkDevicesList() {
|
|
57
56
|
try {
|
|
58
57
|
const devicesList = { State: false, Info: null, Devices: [], Scenes: [] }
|
|
59
58
|
if (this.logDebug) this.emit('debug', `Scanning for devices...`);
|
|
60
|
-
const listDevicesData = await
|
|
61
|
-
method: 'GET',
|
|
62
|
-
baseURL: ApiUrls.BaseURL,
|
|
63
|
-
timeout: 15000,
|
|
64
|
-
headers: this.headers
|
|
65
|
-
});
|
|
59
|
+
const listDevicesData = await this.axiosInstance(ApiUrls.ListDevices, { method: 'GET', });
|
|
66
60
|
|
|
67
61
|
if (!listDevicesData || !listDevicesData.data) {
|
|
68
62
|
devicesList.Info = 'Invalid or empty response from MELCloud API'
|
|
@@ -131,7 +125,7 @@ class MelCloud extends EventEmitter {
|
|
|
131
125
|
if (this.logDebug) this.emit('debug', `Connecting to MELCloud`);
|
|
132
126
|
|
|
133
127
|
try {
|
|
134
|
-
const accountInfo = { State: false, Info: '',
|
|
128
|
+
const accountInfo = { State: false, Info: '', Account: null, UseFahrenheit: false }
|
|
135
129
|
|
|
136
130
|
const payload = {
|
|
137
131
|
Email: this.user,
|
|
@@ -168,15 +162,21 @@ class MelCloud extends EventEmitter {
|
|
|
168
162
|
return accountInfo;
|
|
169
163
|
}
|
|
170
164
|
|
|
171
|
-
|
|
165
|
+
const headers = {
|
|
172
166
|
'X-MitsContextKey': contextKey,
|
|
173
167
|
'Content-Type': 'application/json'
|
|
174
168
|
};
|
|
169
|
+
this.headers = headers;
|
|
170
|
+
this.axiosInstance = axios.create({
|
|
171
|
+
baseURL: ApiUrls.BaseURL,
|
|
172
|
+
timeout: 30000,
|
|
173
|
+
headers: headers
|
|
174
|
+
});
|
|
175
175
|
|
|
176
176
|
accountInfo.State = true;
|
|
177
177
|
accountInfo.Info = 'Connect to MELCloud Success';
|
|
178
|
-
accountInfo.
|
|
179
|
-
accountInfo.
|
|
178
|
+
accountInfo.UseFahrenheit = loginData.UseFahrenheit;
|
|
179
|
+
accountInfo.Account = account;
|
|
180
180
|
await this.functions.saveData(this.accountFile, accountInfo);
|
|
181
181
|
|
|
182
182
|
return accountInfo
|
|
@@ -184,23 +184,6 @@ class MelCloud extends EventEmitter {
|
|
|
184
184
|
throw new Error(`Connect error: ${error.message}`);
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
|
-
|
|
188
|
-
async send(accountInfo) {
|
|
189
|
-
try {
|
|
190
|
-
const payload = { data: accountInfo.LoginData };
|
|
191
|
-
await axios(ApiUrls.UpdateApplicationOptions, {
|
|
192
|
-
method: 'POST',
|
|
193
|
-
baseURL: ApiUrls.BaseURL,
|
|
194
|
-
timeout: 15000,
|
|
195
|
-
headers: accountInfo.Headers,
|
|
196
|
-
data: payload
|
|
197
|
-
});
|
|
198
|
-
await this.functions.saveData(this.accountFile, accountInfo);
|
|
199
|
-
return true;
|
|
200
|
-
} catch (error) {
|
|
201
|
-
throw new Error(`Send data error: ${error.message}`);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
187
|
}
|
|
205
188
|
|
|
206
189
|
export default MelCloud;
|
package/src/melcloudata.js
CHANGED
|
@@ -5,7 +5,7 @@ import Functions from './functions.js';
|
|
|
5
5
|
import { ApiUrls, ApiUrlsHome, AirConditioner } from './constants.js';
|
|
6
6
|
|
|
7
7
|
class MelCloudAta extends EventEmitter {
|
|
8
|
-
constructor(account, device, devicesFile, defaultTempsFile) {
|
|
8
|
+
constructor(account, device, devicesFile, defaultTempsFile, accountFile) {
|
|
9
9
|
super();
|
|
10
10
|
this.accountType = account.type;
|
|
11
11
|
this.logWarn = account.log?.warn;
|
|
@@ -16,6 +16,7 @@ class MelCloudAta extends EventEmitter {
|
|
|
16
16
|
this.deviceId = device.id;
|
|
17
17
|
this.devicesFile = devicesFile;
|
|
18
18
|
this.defaultTempsFile = defaultTempsFile;
|
|
19
|
+
this.accountFile = accountFile;
|
|
19
20
|
this.functions = new Functions(this.logWarn, this.logError, this.logDebug)
|
|
20
21
|
.on('warn', warn => this.emit('warn', warn))
|
|
21
22
|
.on('error', error => this.emit('error', error))
|
|
@@ -26,7 +27,7 @@ class MelCloudAta extends EventEmitter {
|
|
|
26
27
|
this.headers = {};
|
|
27
28
|
|
|
28
29
|
//lock flag
|
|
29
|
-
this.locks =
|
|
30
|
+
this.locks = false;
|
|
30
31
|
this.impulseGenerator = new ImpulseGenerator()
|
|
31
32
|
.on('checkState', () => this.handleWithLock(async () => {
|
|
32
33
|
await this.checkState();
|
|
@@ -53,12 +54,12 @@ class MelCloudAta extends EventEmitter {
|
|
|
53
54
|
try {
|
|
54
55
|
//read device info from file
|
|
55
56
|
const devicesData = await this.functions.readData(this.devicesFile, true);
|
|
57
|
+
if (!devicesData) return;
|
|
58
|
+
|
|
56
59
|
this.headers = devicesData.Headers;
|
|
57
|
-
const scenes = devicesData.Scenes ?? [];
|
|
58
60
|
const deviceData = devicesData.Devices.find(device => device.DeviceID === this.deviceId);
|
|
59
|
-
|
|
60
61
|
if (this.accountType === 'melcloudhome') {
|
|
61
|
-
deviceData.Scenes =
|
|
62
|
+
deviceData.Scenes = devicesData.Scenes ?? [];
|
|
62
63
|
deviceData.Device.OperationMode = AirConditioner.OperationModeMapStringToEnum[deviceData.Device.OperationMode] ?? deviceData.Device.OperationMode;
|
|
63
64
|
deviceData.Device.ActualFanSpeed = AirConditioner.FanSpeedMapStringToEnum[deviceData.Device.ActualFanSpeed] ?? deviceData.Device.ActualFanSpeed;
|
|
64
65
|
deviceData.Device.SetFanSpeed = AirConditioner.FanSpeedMapStringToEnum[deviceData.Device.SetFanSpeed] ?? deviceData.Device.SetFanSpeed;
|
|
@@ -70,12 +71,7 @@ class MelCloudAta extends EventEmitter {
|
|
|
70
71
|
deviceData.Device.DefaultHeatingSetTemperature = temps?.defaultHeatingSetTemperature ?? 20;
|
|
71
72
|
deviceData.Device.DefaultCoolingSetTemperature = temps?.defaultCoolingSetTemperature ?? 24;
|
|
72
73
|
}
|
|
73
|
-
|
|
74
|
-
const safeConfig = {
|
|
75
|
-
...deviceData,
|
|
76
|
-
Headers: 'removed',
|
|
77
|
-
};
|
|
78
|
-
if (this.logDebug) this.emit('debug', `Device Data: ${JSON.stringify(safeConfig, null, 2)}`);
|
|
74
|
+
if (this.logDebug) this.emit('debug', `Device Data: ${JSON.stringify(deviceData, null, 2)}`);
|
|
79
75
|
|
|
80
76
|
//device
|
|
81
77
|
const serialNumber = deviceData.SerialNumber || '4.0.0';
|
|
@@ -137,36 +133,45 @@ class MelCloudAta extends EventEmitter {
|
|
|
137
133
|
let path = '';
|
|
138
134
|
switch (accountType) {
|
|
139
135
|
case "melcloud":
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
136
|
+
switch (flag) {
|
|
137
|
+
case 'account':
|
|
138
|
+
flagData.Account.LoginData.UseFahrenheit = flagData.UseFahrenheit;
|
|
139
|
+
payload = { data: flagData.LoginData };
|
|
140
|
+
path = ApiUrls.UpdateApplicationOptions;
|
|
141
|
+
await this.functions.saveData(this.accountFile, flagData);
|
|
142
|
+
break;
|
|
143
|
+
default:
|
|
144
|
+
if (displayType === 1 && deviceData.Device.OperationMode === 8) {
|
|
145
|
+
deviceData.Device.SetTemperature = (deviceData.Device.DefaultCoolingSetTemperature + deviceData.Device.DefaultHeatingSetTemperature) / 2;
|
|
146
|
+
}
|
|
147
|
+
deviceData.Device.EffectiveFlags = flag;
|
|
148
|
+
payload = {
|
|
149
|
+
DeviceID: deviceData.Device.DeviceID,
|
|
150
|
+
EffectiveFlags: deviceData.Device.EffectiveFlags,
|
|
151
|
+
Power: deviceData.Device.Power,
|
|
152
|
+
SetTemperature: deviceData.Device.SetTemperature,
|
|
153
|
+
SetFanSpeed: deviceData.Device.FanSpeed,
|
|
154
|
+
OperationMode: deviceData.Device.OperationMode,
|
|
155
|
+
VaneHorizontal: deviceData.Device.VaneHorizontalDirection,
|
|
156
|
+
VaneVertical: deviceData.Device.VaneVerticalDirection,
|
|
157
|
+
DefaultHeatingSetTemperature: deviceData.Device.DefaultHeatingSetTemperature,
|
|
158
|
+
DefaultCoolingSetTemperature: deviceData.Device.DefaultCoolingSetTemperature,
|
|
159
|
+
ProhibitSetTemperature: deviceData.Device.ProhibitSetTemperature,
|
|
160
|
+
ProhibitOperationMode: deviceData.Device.ProhibitOperationMode,
|
|
161
|
+
ProhibitPower: deviceData.Device.ProhibitPower,
|
|
162
|
+
HideVaneControls: deviceData.HideVaneControls,
|
|
163
|
+
HideDryModeControl: deviceData.HideDryModeControl,
|
|
164
|
+
HasPendingCommand: true
|
|
165
|
+
};
|
|
166
|
+
path = ApiUrls.SetAta;
|
|
167
|
+
break;
|
|
143
168
|
}
|
|
144
169
|
|
|
145
|
-
deviceData.Device.EffectiveFlags = flag;
|
|
146
|
-
payload = {
|
|
147
|
-
DeviceID: deviceData.Device.DeviceID,
|
|
148
|
-
EffectiveFlags: deviceData.Device.EffectiveFlags,
|
|
149
|
-
Power: deviceData.Device.Power,
|
|
150
|
-
SetTemperature: deviceData.Device.SetTemperature,
|
|
151
|
-
SetFanSpeed: deviceData.Device.FanSpeed,
|
|
152
|
-
OperationMode: deviceData.Device.OperationMode,
|
|
153
|
-
VaneHorizontal: deviceData.Device.VaneHorizontalDirection,
|
|
154
|
-
VaneVertical: deviceData.Device.VaneVerticalDirection,
|
|
155
|
-
DefaultHeatingSetTemperature: deviceData.Device.DefaultHeatingSetTemperature,
|
|
156
|
-
DefaultCoolingSetTemperature: deviceData.Device.DefaultCoolingSetTemperature,
|
|
157
|
-
ProhibitSetTemperature: deviceData.Device.ProhibitSetTemperature,
|
|
158
|
-
ProhibitOperationMode: deviceData.Device.ProhibitOperationMode,
|
|
159
|
-
ProhibitPower: deviceData.Device.ProhibitPower,
|
|
160
|
-
HideVaneControls: deviceData.HideVaneControls,
|
|
161
|
-
HideDryModeControl: deviceData.HideDryModeControl,
|
|
162
|
-
HasPendingCommand: true
|
|
163
|
-
};
|
|
164
|
-
|
|
165
170
|
if (this.logDebug) this.emit('debug', `Send Data: ${JSON.stringify(payload, null, 2)}`);
|
|
166
|
-
await axios(
|
|
171
|
+
await axios(path, {
|
|
167
172
|
method: 'POST',
|
|
168
173
|
baseURL: ApiUrls.BaseURL,
|
|
169
|
-
timeout:
|
|
174
|
+
timeout: 30000,
|
|
170
175
|
headers: this.headers,
|
|
171
176
|
data: payload
|
|
172
177
|
});
|
|
@@ -244,7 +249,7 @@ class MelCloudAta extends EventEmitter {
|
|
|
244
249
|
};
|
|
245
250
|
method = 'PUT';
|
|
246
251
|
path = ApiUrlsHome.PutAta.replace('deviceid', deviceData.DeviceID);
|
|
247
|
-
this.headers.Referer = ApiUrlsHome.Referers.PutDeviceSettings
|
|
252
|
+
this.headers.Referer = ApiUrlsHome.Referers.PutDeviceSettings;
|
|
248
253
|
break
|
|
249
254
|
}
|
|
250
255
|
|
|
@@ -254,10 +259,11 @@ class MelCloudAta extends EventEmitter {
|
|
|
254
259
|
await axios(path, {
|
|
255
260
|
method: method,
|
|
256
261
|
baseURL: ApiUrlsHome.BaseURL,
|
|
257
|
-
timeout:
|
|
262
|
+
timeout: 30000,
|
|
258
263
|
headers: this.headers,
|
|
259
264
|
data: payload
|
|
260
265
|
});
|
|
266
|
+
|
|
261
267
|
this.updateData(deviceData);
|
|
262
268
|
return true;
|
|
263
269
|
default:
|
|
@@ -270,12 +276,12 @@ class MelCloudAta extends EventEmitter {
|
|
|
270
276
|
}
|
|
271
277
|
|
|
272
278
|
updateData(deviceData) {
|
|
273
|
-
this.
|
|
279
|
+
this.locks = true;
|
|
274
280
|
this.emit('deviceState', deviceData);
|
|
275
281
|
|
|
276
282
|
setTimeout(() => {
|
|
277
|
-
this.
|
|
278
|
-
},
|
|
283
|
+
this.locks = false
|
|
284
|
+
}, 5000);
|
|
279
285
|
}
|
|
280
286
|
};
|
|
281
287
|
export default MelCloudAta;
|
package/src/melcloudatw.js
CHANGED
|
@@ -5,7 +5,7 @@ import Functions from './functions.js';
|
|
|
5
5
|
import { ApiUrls, ApiUrlsHome, HeatPump } from './constants.js';
|
|
6
6
|
|
|
7
7
|
class MelCloudAtw extends EventEmitter {
|
|
8
|
-
constructor(account, device, devicesFile, defaultTempsFile) {
|
|
8
|
+
constructor(account, device, devicesFile, defaultTempsFile, accountFile) {
|
|
9
9
|
super();
|
|
10
10
|
this.accountType = account.type;
|
|
11
11
|
this.logWarn = account.log?.warn;
|
|
@@ -16,6 +16,7 @@ class MelCloudAtw extends EventEmitter {
|
|
|
16
16
|
this.deviceId = device.id;
|
|
17
17
|
this.devicesFile = devicesFile;
|
|
18
18
|
this.defaultTempsFile = defaultTempsFile;
|
|
19
|
+
this.accountFile = accountFile;
|
|
19
20
|
this.functions = new Functions(this.logWarn, this.logError, this.logDebug)
|
|
20
21
|
.on('warn', warn => this.emit('warn', warn))
|
|
21
22
|
.on('error', error => this.emit('error', error))
|
|
@@ -26,7 +27,7 @@ class MelCloudAtw extends EventEmitter {
|
|
|
26
27
|
this.headers = {};
|
|
27
28
|
|
|
28
29
|
//lock flags
|
|
29
|
-
this.locks =
|
|
30
|
+
this.locks = false;
|
|
30
31
|
this.impulseGenerator = new ImpulseGenerator()
|
|
31
32
|
.on('checkState', () => this.handleWithLock(async () => {
|
|
32
33
|
await this.checkState();
|
|
@@ -53,19 +54,14 @@ class MelCloudAtw extends EventEmitter {
|
|
|
53
54
|
try {
|
|
54
55
|
//read device info from file
|
|
55
56
|
const devicesData = await this.functions.readData(this.devicesFile, true);
|
|
57
|
+
if (!devicesData) return;
|
|
58
|
+
|
|
56
59
|
this.headers = devicesData.Headers;
|
|
57
|
-
const scenes = devicesData.Scenes ?? [];
|
|
58
60
|
const deviceData = devicesData.Devices.find(device => device.DeviceID === this.deviceId);
|
|
59
|
-
|
|
60
61
|
if (this.accountType === 'melcloudhome') {
|
|
61
|
-
deviceData.Scenes =
|
|
62
|
+
deviceData.Scenes = devicesData.Scenes ?? [];
|
|
62
63
|
}
|
|
63
|
-
|
|
64
|
-
const safeConfig = {
|
|
65
|
-
...deviceData,
|
|
66
|
-
Headers: 'removed',
|
|
67
|
-
};
|
|
68
|
-
if (this.logDebug) this.emit('debug', `Device Data: ${JSON.stringify(safeConfig, null, 2)}`);
|
|
64
|
+
if (this.logDebug) this.emit('debug', `Device Data: ${JSON.stringify(deviceData, null, 2)}`);
|
|
69
65
|
|
|
70
66
|
//device
|
|
71
67
|
//device
|
|
@@ -144,35 +140,46 @@ class MelCloudAtw extends EventEmitter {
|
|
|
144
140
|
let path = '';
|
|
145
141
|
switch (accountType) {
|
|
146
142
|
case "melcloud":
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
143
|
+
switch (flag) {
|
|
144
|
+
case 'account':
|
|
145
|
+
flagData.Account.LoginData.UseFahrenheit = flagData.UseFahrenheit;
|
|
146
|
+
payload = { data: flagData.LoginData };
|
|
147
|
+
path = ApiUrls.UpdateApplicationOptions;
|
|
148
|
+
await this.functions.saveData(this.accountFile, flagData);
|
|
149
|
+
break;
|
|
150
|
+
default:
|
|
151
|
+
deviceData.Device.EffectiveFlags = flag;
|
|
152
|
+
payload = {
|
|
153
|
+
DeviceID: deviceData.Device.DeviceID,
|
|
154
|
+
EffectiveFlags: deviceData.Device.EffectiveFlags,
|
|
155
|
+
Power: deviceData.Device.Power,
|
|
156
|
+
SetTemperatureZone1: deviceData.Device.SetTemperatureZone1,
|
|
157
|
+
SetTemperatureZone2: deviceData.Device.SetTemperatureZone2,
|
|
158
|
+
OperationMode: deviceData.Device.OperationMode,
|
|
159
|
+
OperationModeZone1: deviceData.Device.OperationModeZone1,
|
|
160
|
+
OperationModeZone2: deviceData.Device.OperationModeZone2,
|
|
161
|
+
SetHeatFlowTemperatureZone1: deviceData.Device.SetHeatFlowTemperatureZone1,
|
|
162
|
+
SetHeatFlowTemperatureZone2: deviceData.Device.SetHeatFlowTemperatureZone2,
|
|
163
|
+
SetCoolFlowTemperatureZone1: deviceData.Device.SetCoolFlowTemperatureZone1,
|
|
164
|
+
SetCoolFlowTemperatureZone2: deviceData.Device.SetCoolFlowTemperatureZone2,
|
|
165
|
+
SetTankWaterTemperature: deviceData.Device.SetTankWaterTemperature,
|
|
166
|
+
ForcedHotWaterMode: deviceData.Device.ForcedHotWaterMode,
|
|
167
|
+
EcoHotWater: deviceData.Device.EcoHotWater,
|
|
168
|
+
HolidayMode: deviceData.Device.HolidayMode,
|
|
169
|
+
ProhibitZone1: deviceData.Device.ProhibitHeatingZone1,
|
|
170
|
+
ProhibitZone2: deviceData.Device.ProhibitHeatingZone2,
|
|
171
|
+
ProhibitHotWater: deviceData.Device.ProhibitHotWater,
|
|
172
|
+
HasPendingCommand: true
|
|
173
|
+
}
|
|
174
|
+
path = ApiUrls.SetAtw;
|
|
175
|
+
break;
|
|
169
176
|
}
|
|
170
177
|
|
|
171
178
|
if (this.logDebug) this.emit('debug', `Send Data: ${JSON.stringify(payload, null, 2)}`);
|
|
172
|
-
await axios(
|
|
179
|
+
await axios(path, {
|
|
173
180
|
method: 'POST',
|
|
174
181
|
baseURL: ApiUrls.BaseURL,
|
|
175
|
-
timeout:
|
|
182
|
+
timeout: 30000,
|
|
176
183
|
headers: this.headers,
|
|
177
184
|
data: payload
|
|
178
185
|
});
|
|
@@ -221,7 +228,7 @@ class MelCloudAtw extends EventEmitter {
|
|
|
221
228
|
};
|
|
222
229
|
method = 'PUT';
|
|
223
230
|
path = ApiUrlsHome.PutAtw.replace('deviceid', deviceData.DeviceID);
|
|
224
|
-
this.headers.Referer = ApiUrlsHome.Referers.PutDeviceSettings
|
|
231
|
+
this.headers.Referer = ApiUrlsHome.Referers.PutDeviceSettings;
|
|
225
232
|
break
|
|
226
233
|
}
|
|
227
234
|
|
|
@@ -231,7 +238,7 @@ class MelCloudAtw extends EventEmitter {
|
|
|
231
238
|
await axios(path, {
|
|
232
239
|
method: method,
|
|
233
240
|
baseURL: ApiUrlsHome.BaseURL,
|
|
234
|
-
timeout:
|
|
241
|
+
timeout: 30000,
|
|
235
242
|
headers: this.headers,
|
|
236
243
|
data: payload
|
|
237
244
|
});
|
|
@@ -247,12 +254,12 @@ class MelCloudAtw extends EventEmitter {
|
|
|
247
254
|
}
|
|
248
255
|
|
|
249
256
|
updateData(deviceData) {
|
|
250
|
-
this.
|
|
257
|
+
this.locks = true;
|
|
251
258
|
this.emit('deviceState', deviceData);
|
|
252
259
|
|
|
253
260
|
setTimeout(() => {
|
|
254
|
-
this.
|
|
255
|
-
},
|
|
261
|
+
this.locks = false
|
|
262
|
+
}, 5000);
|
|
256
263
|
}
|
|
257
264
|
};
|
|
258
265
|
export default MelCloudAtw;
|