homebridge-midea-platform 0.4.13 → 1.0.0
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/.gitattributes +3 -0
- package/.husky/pre-commit +2 -1
- package/.prettierrc +1 -0
- package/README.md +14 -156
- package/config.schema.json +162 -1
- package/dist/accessory/AccessoryFactory.d.ts +3 -1
- package/dist/accessory/AccessoryFactory.d.ts.map +1 -1
- package/dist/accessory/AccessoryFactory.js +6 -0
- package/dist/accessory/AccessoryFactory.js.map +1 -1
- package/dist/accessory/AirConditionerAccessory.d.ts +9 -0
- package/dist/accessory/AirConditionerAccessory.d.ts.map +1 -1
- package/dist/accessory/AirConditionerAccessory.js +88 -12
- package/dist/accessory/AirConditionerAccessory.js.map +1 -1
- package/dist/accessory/DehumidifierAccessory.d.ts +5 -0
- package/dist/accessory/DehumidifierAccessory.d.ts.map +1 -1
- package/dist/accessory/DehumidifierAccessory.js +42 -2
- package/dist/accessory/DehumidifierAccessory.js.map +1 -1
- package/dist/accessory/ElectricWaterHeaterAccessory.d.ts +45 -0
- package/dist/accessory/ElectricWaterHeaterAccessory.d.ts.map +1 -0
- package/dist/accessory/ElectricWaterHeaterAccessory.js +179 -0
- package/dist/accessory/ElectricWaterHeaterAccessory.js.map +1 -0
- package/dist/accessory/GasWaterHeaterAccessory.d.ts +52 -0
- package/dist/accessory/GasWaterHeaterAccessory.d.ts.map +1 -0
- package/dist/accessory/GasWaterHeaterAccessory.js +219 -0
- package/dist/accessory/GasWaterHeaterAccessory.js.map +1 -0
- package/dist/core/MideaCloud.d.ts +14 -14
- package/dist/core/MideaCloud.d.ts.map +1 -1
- package/dist/core/MideaCloud.js +150 -92
- package/dist/core/MideaCloud.js.map +1 -1
- package/dist/core/MideaConstants.d.ts +7 -2
- package/dist/core/MideaConstants.d.ts.map +1 -1
- package/dist/core/MideaConstants.js +8 -1
- package/dist/core/MideaConstants.js.map +1 -1
- package/dist/core/MideaPacketBuilder.d.ts.map +1 -1
- package/dist/core/MideaPacketBuilder.js +3 -2
- package/dist/core/MideaPacketBuilder.js.map +1 -1
- package/dist/core/MideaSecurity.d.ts +35 -11
- package/dist/core/MideaSecurity.d.ts.map +1 -1
- package/dist/core/MideaSecurity.js +75 -28
- package/dist/core/MideaSecurity.js.map +1 -1
- package/dist/core/MideaUtils.js +2 -1
- package/dist/core/MideaUtils.js.map +1 -1
- package/dist/devices/DeviceFactory.d.ts +4 -2
- package/dist/devices/DeviceFactory.d.ts.map +1 -1
- package/dist/devices/DeviceFactory.js +6 -0
- package/dist/devices/DeviceFactory.js.map +1 -1
- package/dist/devices/e2/MideaE2Device.d.ts +45 -0
- package/dist/devices/e2/MideaE2Device.d.ts.map +1 -0
- package/dist/devices/e2/MideaE2Device.js +120 -0
- package/dist/devices/e2/MideaE2Device.js.map +1 -0
- package/dist/devices/e2/MideaE2Message.d.ts +34 -0
- package/dist/devices/e2/MideaE2Message.d.ts.map +1 -0
- package/dist/devices/e2/MideaE2Message.js +133 -0
- package/dist/devices/e2/MideaE2Message.js.map +1 -0
- package/dist/devices/e3/MideaE3Device.d.ts +44 -0
- package/dist/devices/e3/MideaE3Device.d.ts.map +1 -0
- package/dist/devices/e3/MideaE3Device.js +126 -0
- package/dist/devices/e3/MideaE3Device.js.map +1 -0
- package/dist/devices/e3/MideaE3Message.d.ts +52 -0
- package/dist/devices/e3/MideaE3Message.d.ts.map +1 -0
- package/dist/devices/e3/MideaE3Message.js +137 -0
- package/dist/devices/e3/MideaE3Message.js.map +1 -0
- package/dist/platformUtils.d.ts +26 -0
- package/dist/platformUtils.d.ts.map +1 -1
- package/dist/platformUtils.js +24 -0
- package/dist/platformUtils.js.map +1 -1
- package/docs/a1.md +20 -0
- package/docs/ac.md +41 -0
- package/docs/e2.md +21 -0
- package/docs/e3.md +27 -0
- package/homebridge-ui/public/index.html +78 -25
- package/homebridge-ui/server.js +23 -4
- package/package.json +8 -1
package/docs/a1.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Dehumidifier
|
|
2
|
+
|
|
3
|
+
Providing dehumidifier settings is optional and the whole section or individual options may be ommitted and default values (noted below) will be used. Within the *devices.config* object the following dehumidifier specific options.
|
|
4
|
+
|
|
5
|
+
```json
|
|
6
|
+
"A1_options": {
|
|
7
|
+
"minHumidity": 35,
|
|
8
|
+
"maxHumidity": 85,
|
|
9
|
+
"humidityStep": 5,
|
|
10
|
+
"temperatureSensor": false,
|
|
11
|
+
"pumpSwitch": false
|
|
12
|
+
}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Options
|
|
16
|
+
- **minHumidity** *(optional)*: The minimum relative humidity that the unit can be set for. Default is 35%
|
|
17
|
+
- **maxHumidity** *(optional)*: The maximum relative humidity that the unit can be set for. Default is 85%
|
|
18
|
+
- **humidityStep** *(optional)*: Increment in which the relative himidity setting can be changed, may be set to either 5% or 10%. The default is 5%.
|
|
19
|
+
- **temperatureSensor** *(optional)*: Toggles if the temperature sensor is created with the accessory. Default is false.
|
|
20
|
+
- **pumpSwitch** *(optional)*: Toggles if the pump switch is created with the accessory. Default is false.
|
package/docs/ac.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Air Conditioner
|
|
2
|
+
|
|
3
|
+
Providing air conditioner settings is optional and the whole section or individual options may be ommitted and default values (noted below) will be used. Within the *devices.config* object the following air conditioner specific options.
|
|
4
|
+
|
|
5
|
+
```json
|
|
6
|
+
"AC_options": {
|
|
7
|
+
"swingMode": "Both",
|
|
8
|
+
"heatingCapable": false,
|
|
9
|
+
"ecoSwitch": false,
|
|
10
|
+
"displaySwitch": {
|
|
11
|
+
"flag": true,
|
|
12
|
+
"command": false
|
|
13
|
+
},
|
|
14
|
+
"minTemp": 16,
|
|
15
|
+
"maxTemp": 30,
|
|
16
|
+
"tempStep": 1,
|
|
17
|
+
"fahrenheit": false,
|
|
18
|
+
"fanOnlyMode": false,
|
|
19
|
+
"breezeAwaySwitch": false,
|
|
20
|
+
"dryModeSwitch": false,
|
|
21
|
+
"auxHeatingSwitches": false,
|
|
22
|
+
"outDoorTemp": false,
|
|
23
|
+
"audioFeedback": false
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
## Options
|
|
27
|
+
- **swingMode** *(optional)*: The swing mode of the unit. Options are "Both", "Vertical", "Horizontal", or "None". Default is "None".
|
|
28
|
+
- **heatingCapable** *(optional)*: Toggles if the unit is capable of heating. Default is false.
|
|
29
|
+
- **displaySwitch** *(optional)*: Object with following two options...
|
|
30
|
+
- * **flag** *(optional)*: Toggles if a switch, which can turn the display on or off will be created or not. Default is true.
|
|
31
|
+
- * **command** *(optional)*: Use this if the switch display command does not work. If it doesn't work either way then you unit does not support this feature. Default is false.
|
|
32
|
+
- **minTemp** *(optional)*: The minimum temperature that the unit can be set for. Default is 16 celsius
|
|
33
|
+
- **maxTemp** *(optional)*: The maximum temperature that the unit can be set for. Default is 30 celsius
|
|
34
|
+
- **tempStep** *(optional)*: Increment in which the temperature setting can be changed, may be set to either 0.5 or 1 degree celsius. The default is one degree.
|
|
35
|
+
- **fahrenheit** *(optional)*: Toggles if the temperature on the unit is displayed in Fahrenheit or Celsius. Default is false (displays in Celsius).
|
|
36
|
+
- **fanOnlyMode** *(optional)*: Toggles if the fan only mode is created with the accessory. Default is false.
|
|
37
|
+
- **breezeAwaySwitch** *(optional)*: Toggles if the breeze away switch is created with the accessory. Default is false.
|
|
38
|
+
- **dryModeSwitch** *(optional)*: Toggles if the dry mode switch is created with the accessory. Default is false.
|
|
39
|
+
- **auxHeatingSwitches** *(optional)*: Toggles if the aux heating switches are created with the accessory. Default is false.
|
|
40
|
+
- **outDoorTemp** *(optional)*: Toggles if the outdoor temperature sensor is created with the accessory. Default is false.
|
|
41
|
+
- **audioFeedback** *(optional)*: Toggles if the unit beeps when a command is sent, default is false.
|
package/docs/e2.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Electric Water Heater
|
|
2
|
+
|
|
3
|
+
Providing electric water heater settings is optional and the whole section or individual options may be ommitted and default values (noted below) will be used. Within the *devices.config* object the following electric water heater specific options.
|
|
4
|
+
|
|
5
|
+
```json
|
|
6
|
+
"E2_options": {
|
|
7
|
+
"protocol": "auto",
|
|
8
|
+
"minTemp": 30,
|
|
9
|
+
"maxTemp": 75,
|
|
10
|
+
"tempStep": 1,
|
|
11
|
+
"variableHeatingSwitch": false,
|
|
12
|
+
"wholeTankHeatingSwitch": false,
|
|
13
|
+
}
|
|
14
|
+
```
|
|
15
|
+
## Options
|
|
16
|
+
- **protocol** *(optional)*: The protocol used to control the water heater. Only change this if the device is not responding to the commands. Default is "auto". Other options are "auto", "old", "new".
|
|
17
|
+
- **minTemp** *(optional)*: The minimum temperature that the unit can be set for. Default is 30 celsius
|
|
18
|
+
- **maxTemp** *(optional)*: The maximum temperature that the unit can be set for. Default is 75 celsius
|
|
19
|
+
- **tempStep** *(optional)*: Increment in which the temperature setting can be changed, may be set to either 0.5 or 1 degree celsius. The default is one degree.
|
|
20
|
+
- **variableHeatingSwitch** *(optional)*: Toggles if the variable heating switch is created with the accessory. Default is false.
|
|
21
|
+
- **wholeTankHeatingSwitch** *(optional)*: Toggles if the whole tank heating switch is created with the accessory. Default is false.
|
package/docs/e3.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Gas Water Heater
|
|
2
|
+
|
|
3
|
+
Providing gas water heater settings is optional and the whole section or individual options may be ommitted and default values (noted below) will be used. Within the *devices.config* object the following gas water heater specific options.
|
|
4
|
+
|
|
5
|
+
```json
|
|
6
|
+
"E3_options": {
|
|
7
|
+
"precisionHalves": false,
|
|
8
|
+
"minTemp": 35,
|
|
9
|
+
"maxTemp": 65,
|
|
10
|
+
"tempStep": 1,
|
|
11
|
+
"burningStateSensor": false,
|
|
12
|
+
"protectionSensor": false,
|
|
13
|
+
"zeroColdWaterSwitch": false,
|
|
14
|
+
"zeroColdPulseSwitch": false,
|
|
15
|
+
"smartVolumeSwitch": false
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
## Options
|
|
19
|
+
- **precisionHalves** *(optional)*: This option must be enabled if the temperature on your unit is displayed in half degree increments. Default is false.
|
|
20
|
+
- **minTemp** *(optional)*: The minimum temperature that the unit can be set for. Default is 35 celsius
|
|
21
|
+
- **maxTemp** *(optional)*: The maximum temperature that the unit can be set for. Default is 65 celsius
|
|
22
|
+
- **tempStep** *(optional)*: Increment in which the temperature setting can be changed, may be set to either 0.5 or 1 degree celsius. The default is one degree.
|
|
23
|
+
- **burningStateSensor** *(optional)*: Toggles if the burning state sensor is created with the accessory. Default is false.
|
|
24
|
+
- **protectionSensor** *(optional)*: Toggles if the protection sensor is created with the accessory. Default is false.
|
|
25
|
+
- **zeroColdWaterSwitch** *(optional)*: Toggles if the zero cold water switch is created with the accessory. Default is false.
|
|
26
|
+
- **zeroColdPulseSwitch** *(optional)*: Toggles if the zero cold pulse switch is created with the accessory. Default is false.
|
|
27
|
+
- **smartVolumeSwitch** *(optional)*: Toggles if the smart volume switch is created with the accessory. Default is false.
|
|
@@ -26,25 +26,41 @@
|
|
|
26
26
|
<div class="card-body">
|
|
27
27
|
<form>
|
|
28
28
|
<div class="mb-3 bg-info-subtle border-info-subtle p-3 rounded-2">
|
|
29
|
-
You can discover your devices without providing credentials. However, if you see <i>No Credentials</i> in
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
You can discover your devices without providing credentials. However, if you see <i>No Credentials</i> in
|
|
30
|
+
the
|
|
31
|
+
Add/Update column then you must provide login credentials or use the default profile option so the
|
|
32
|
+
<i>token/key</i> pair can be retrieved
|
|
33
|
+
from Midea cloud servers.<br/>
|
|
34
|
+
<i>Note: you don't have to have your devices connected to the account you are using to fetch the token/key pair.</i>
|
|
32
35
|
</div>
|
|
33
|
-
<div class="mb-3">
|
|
34
|
-
<
|
|
35
|
-
<
|
|
36
|
-
<option selected value="Midea SmartHome (MSmartHome)">Midea SmartHome (MSmartHome)</option>
|
|
37
|
-
<option value="NetHome Plus">NetHome Plus</option>
|
|
38
|
-
<option value="Meiju">Meiju</option>
|
|
39
|
-
</select>
|
|
36
|
+
<div class="mb-3 form-check form-switch">
|
|
37
|
+
<input id="useDefaultProfile" type="checkbox" class="form-check-input" role="switch">
|
|
38
|
+
<label for="useDefaultProfile" class="form-check-label">Use default Midea SmartHome profile</label>
|
|
40
39
|
</div>
|
|
41
|
-
<div class="mb-3">
|
|
42
|
-
<
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
40
|
+
<div class="mb-3" id="login">
|
|
41
|
+
<div class="mb-3">
|
|
42
|
+
<label for="registeredApp" class="form-label">Registered app</label>
|
|
43
|
+
<select id="registeredApp" class="form-select">
|
|
44
|
+
<option selected value="Midea SmartHome (MSmartHome)">Midea SmartHome (MSmartHome)</option>
|
|
45
|
+
<option value="NetHome Plus">NetHome Plus</option>
|
|
46
|
+
<option value="Meiju">Meiju</option>
|
|
47
|
+
<option value="Artison Clima">Artison Clima</option>
|
|
48
|
+
</select>
|
|
49
|
+
</div>
|
|
50
|
+
<div class="mb-3 hide bg-warning-subtle border-warning-subtle p-3 rounded-2" id="meijuWarning">
|
|
51
|
+
The Meiju app disabled the process of obtaining the required token/key pair for protocol version 3 devices.
|
|
52
|
+
When choosing Meiju, it will utilize the default Midea SmartHome profile to retrieve the token/key pair.
|
|
53
|
+
</div>
|
|
54
|
+
<div id="userPass">
|
|
55
|
+
<div class="mb-3">
|
|
56
|
+
<label for="username" class="form-label">Username</label>
|
|
57
|
+
<input type="text" class="form-control" id="username">
|
|
58
|
+
</div>
|
|
59
|
+
<div class="mb-3">
|
|
60
|
+
<label for="password" class="form-label">Password</label>
|
|
61
|
+
<input type="password" class="form-control" id="password">
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
48
64
|
</div>
|
|
49
65
|
<div class="mb-3">
|
|
50
66
|
<label for="ip" class="form-label">IP Addresses (comma or space separated list for when devices are on
|
|
@@ -82,6 +98,19 @@
|
|
|
82
98
|
|
|
83
99
|
</div>
|
|
84
100
|
|
|
101
|
+
<style>
|
|
102
|
+
|
|
103
|
+
.hide {
|
|
104
|
+
display: none;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.disabled {
|
|
108
|
+
pointer-events: none;
|
|
109
|
+
opacity: 0.5;
|
|
110
|
+
}
|
|
111
|
+
</style>
|
|
112
|
+
|
|
113
|
+
|
|
85
114
|
<script>
|
|
86
115
|
|
|
87
116
|
(async () => {
|
|
@@ -174,6 +203,30 @@
|
|
|
174
203
|
createForm(configSchema, configuration);
|
|
175
204
|
homebridge.hideSpinner();
|
|
176
205
|
|
|
206
|
+
const loginSection = document.getElementById('login')
|
|
207
|
+
const userPass = document.getElementById('userPass');
|
|
208
|
+
const meijuWarning = document.getElementById('meijuWarning');
|
|
209
|
+
|
|
210
|
+
document.getElementById('useDefaultProfile').addEventListener('change', function (e) {
|
|
211
|
+
if (e.target.checked === true) {
|
|
212
|
+
loginSection.classList.add('disabled');
|
|
213
|
+
} else {
|
|
214
|
+
loginSection.classList.remove('disabled');
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
document.getElementById('registeredApp').addEventListener('change', function (e) {
|
|
219
|
+
if (e.target.value === 'Meiju') {
|
|
220
|
+
meijuWarning.classList.remove('hide');
|
|
221
|
+
userPass.classList.add('disabled');
|
|
222
|
+
} else {
|
|
223
|
+
meijuWarning.classList.add('hide');
|
|
224
|
+
userPass.classList.remove('disabled');
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
|
|
177
230
|
/*********************************************************************
|
|
178
231
|
* Discover button clicked....
|
|
179
232
|
*/
|
|
@@ -183,6 +236,9 @@
|
|
|
183
236
|
const username = document.getElementById('username').value;
|
|
184
237
|
const password = document.getElementById('password').value;
|
|
185
238
|
const registeredApp = document.getElementById('registeredApp').value;
|
|
239
|
+
const isMeiju = registeredApp === 'Meiju';
|
|
240
|
+
const useDefaultProfile = document.getElementById('useDefaultProfile').checked === true || isMeiju;
|
|
241
|
+
|
|
186
242
|
let ipAddrs = document.getElementById('ip').value ? document.getElementById('ip').value.split(/[\s,]+/) : [];
|
|
187
243
|
|
|
188
244
|
homebridge.showSpinner();
|
|
@@ -190,7 +246,7 @@
|
|
|
190
246
|
|
|
191
247
|
console.info(`Request login...`);
|
|
192
248
|
try {
|
|
193
|
-
await homebridge.request('/login', { username, password, registeredApp });
|
|
249
|
+
await homebridge.request('/login', { username, password, registeredApp, useDefaultProfile });
|
|
194
250
|
} catch (e) {
|
|
195
251
|
homebridge.toast.error(e.message);
|
|
196
252
|
homebridge.hideSpinner();
|
|
@@ -201,6 +257,7 @@
|
|
|
201
257
|
const table = document.getElementById('discoverTable').getElementsByTagName('tbody')[0];
|
|
202
258
|
table.innerHTML = '';
|
|
203
259
|
|
|
260
|
+
|
|
204
261
|
// Merge current config over to the server so discover has latest device config...
|
|
205
262
|
let currentConfig = await homebridge.getPluginConfig();
|
|
206
263
|
currentConfig = currentConfig.length > 0 ? currentConfig[0] : {};
|
|
@@ -218,7 +275,7 @@
|
|
|
218
275
|
return (regexIPv4.test(ip));
|
|
219
276
|
});
|
|
220
277
|
if (!validIPs) {
|
|
221
|
-
|
|
278
|
+
homebridge.toast.error(`Invalid IP address provided`);
|
|
222
279
|
homebridge.hideSpinner();
|
|
223
280
|
// Abort if we have invalid IP address
|
|
224
281
|
return;
|
|
@@ -246,12 +303,8 @@
|
|
|
246
303
|
tr.insertCell().appendChild(document.createTextNode(device.version));
|
|
247
304
|
if (device.version === 3) {
|
|
248
305
|
tr.insertCell().appendChild(document.createTextNode(
|
|
249
|
-
device.token ?
|
|
250
|
-
|
|
251
|
-
'token missing' + '\n' +
|
|
252
|
-
device.key ?
|
|
253
|
-
device.key.slice(0, 6) + '...' + device.key.slice(-4) :
|
|
254
|
-
'key missing'
|
|
306
|
+
(device.token ? (device.token.slice(0, 6) + '...' + device.token.slice(-4)) : 'token missing') + '\n' +
|
|
307
|
+
(device.key ? (device.key.slice(0, 6) + '...' + device.key.slice(-4)) : 'key missing')
|
|
255
308
|
));
|
|
256
309
|
} else {
|
|
257
310
|
tr.insertCell().appendChild(document.createTextNode('not needed'));
|
package/homebridge-ui/server.js
CHANGED
|
@@ -10,11 +10,17 @@
|
|
|
10
10
|
const { HomebridgePluginUiServer, RequestError } = require('@homebridge/plugin-ui-utils');
|
|
11
11
|
const Discover = require('../dist/core/MideaDiscover.js').default;
|
|
12
12
|
const CloudFactory = require('../dist/core/MideaCloud.js').default;
|
|
13
|
-
const { DeviceType, TCPMessageType, ProtocolVersion } = require("../dist/core/MideaConstants.js");
|
|
13
|
+
const { DeviceType, TCPMessageType, ProtocolVersion, Endianness } = require("../dist/core/MideaConstants.js");
|
|
14
14
|
const { LocalSecurity } = require("../dist/core/MideaSecurity.js");
|
|
15
15
|
const { PromiseSocket } = require("../dist/core/MideaUtils.js");
|
|
16
16
|
const { defaultConfig, defaultDeviceConfig } = require('../dist/platformUtils.js');
|
|
17
17
|
|
|
18
|
+
const DEFAULT_ACCOUNT = [
|
|
19
|
+
BigInt("39182118275972017797890111985649342047468653967530949796945843010512"),
|
|
20
|
+
BigInt("29406100301096535908214728322278519471982973450672552249652548883645"),
|
|
21
|
+
BigInt("39182118275972017797890111985649342050088014265865102175083010656997")
|
|
22
|
+
]
|
|
23
|
+
|
|
18
24
|
var _ = require('lodash');
|
|
19
25
|
|
|
20
26
|
/*********************************************************************
|
|
@@ -81,8 +87,14 @@ class UiServer extends HomebridgePluginUiServer {
|
|
|
81
87
|
this.security = new LocalSecurity();
|
|
82
88
|
this.promiseSocket = new PromiseSocket(this.logger, config?.logRecoverableErrors ? config.logRecoverableErrors : false);
|
|
83
89
|
|
|
84
|
-
this.onRequest('/login', async ({ username, password, registeredApp }) => {
|
|
90
|
+
this.onRequest('/login', async ({ username, password, registeredApp, useDefaultProfile }) => {
|
|
85
91
|
try {
|
|
92
|
+
if (useDefaultProfile) {
|
|
93
|
+
this.logger.debug(`Using default profile.`);
|
|
94
|
+
registeredApp = 'Midea SmartHome (MSmartHome)';
|
|
95
|
+
username = Buffer.from((DEFAULT_ACCOUNT[0] ^ DEFAULT_ACCOUNT[1]).toString(16), 'hex').toString('ascii')
|
|
96
|
+
password = Buffer.from((DEFAULT_ACCOUNT[0] ^ DEFAULT_ACCOUNT[2]).toString(16), 'hex').toString('ascii')
|
|
97
|
+
}
|
|
86
98
|
this.cloud = CloudFactory.createCloud(username, password, registeredApp);
|
|
87
99
|
if (username && password && registeredApp) {
|
|
88
100
|
await this.cloud.login();
|
|
@@ -90,6 +102,7 @@ class UiServer extends HomebridgePluginUiServer {
|
|
|
90
102
|
} catch (e) {
|
|
91
103
|
const msg = e instanceof Error ? e.stack : e;
|
|
92
104
|
this.logger.warn(`Login failed:\n${msg}`);
|
|
105
|
+
throw new RequestError(`Login failed! Check the logs for more information.`);
|
|
93
106
|
}
|
|
94
107
|
});
|
|
95
108
|
|
|
@@ -149,9 +162,9 @@ class UiServer extends HomebridgePluginUiServer {
|
|
|
149
162
|
// works or having tried both.
|
|
150
163
|
while (i <= 1 && !connected) {
|
|
151
164
|
// Start with big-endianess as it is more likely to succeed.
|
|
152
|
-
const endianess = i === 0 ?
|
|
165
|
+
const endianess = i === 0 ? Endianness.Little : Endianness.Big;
|
|
153
166
|
try {
|
|
154
|
-
const [token, key] = await this.cloud.
|
|
167
|
+
const [token, key] = await this.cloud.getTokenKey(device.id, endianess);
|
|
155
168
|
device.token = token ? token.toString('hex') : undefined;
|
|
156
169
|
device.key = key ? key.toString('hex') : undefined;
|
|
157
170
|
await this.authenticate(device);
|
|
@@ -226,6 +239,12 @@ class UiServer extends HomebridgePluginUiServer {
|
|
|
226
239
|
case DeviceType.DEHUMIDIFIER:
|
|
227
240
|
device['displayName'] = 'Dehumidifier';
|
|
228
241
|
break;
|
|
242
|
+
case DeviceType.ELECTRIC_WATER_HEATER:
|
|
243
|
+
device['displayName'] = 'Electric Water Heater';
|
|
244
|
+
break;
|
|
245
|
+
case DeviceType.GAS_WATER_HEATER:
|
|
246
|
+
device['displayName'] = 'Gas Water Heater';
|
|
247
|
+
break;
|
|
229
248
|
default:
|
|
230
249
|
device['displayName'] = 'Unknown';
|
|
231
250
|
break;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"displayName": "Homebridge Midea Platform",
|
|
3
3
|
"name": "homebridge-midea-platform",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "1.0.0",
|
|
5
5
|
"description": "Homebridge plugin for Midea devices",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"repository": {
|
|
@@ -24,6 +24,12 @@
|
|
|
24
24
|
"format": "prettier --log-level warn --write \"**/*.ts\" && npm run lint -- --fix",
|
|
25
25
|
"prepare": "husky install"
|
|
26
26
|
},
|
|
27
|
+
"lint-staged": {
|
|
28
|
+
"*.ts": [
|
|
29
|
+
"prettier --write",
|
|
30
|
+
"eslint --fix"
|
|
31
|
+
]
|
|
32
|
+
},
|
|
27
33
|
"keywords": [
|
|
28
34
|
"homebridge-plugin"
|
|
29
35
|
],
|
|
@@ -46,6 +52,7 @@
|
|
|
46
52
|
"eslint-plugin-prettier": "^5.0.1",
|
|
47
53
|
"homebridge": "^1.6.0",
|
|
48
54
|
"husky": "^8.0.0",
|
|
55
|
+
"lint-staged": "^15.2.2",
|
|
49
56
|
"nodemon": "^3.0.1",
|
|
50
57
|
"prettier": "^3.0.3",
|
|
51
58
|
"rimraf": "^3.0.2",
|