Any Support for Midea A/C?

Hi, @mac_zhou.

First of all, my english isn’t good too. So let’ts get it past us. hahhahaha
Second, after the @Hypfer’s idea, last night I’ve been debuggin your code and MSmart (the app, not the module) code
As I’ve said before my AC unit DO NOT work on midea cloud app, instead, it works with another apps (Midea Start, Midea MSmart and NetHome)

I’ll post some details later, but the protocol is a bit different
From the ports it uses, to the broadcast method to the size of the packets and basecommand
It’s a AC unit and the protocol starts With 5a5a and has a applience code equals to 172 (0XAC), don’t work out of the box with your code
I’ve managed to get the discover working using your code, but I’m still working in mapping the data fields (already got some like date and deviceid) and the security method that’s different too (I guess it’s a MD5 of something, but don’t know exactly what)

As said, I’ll post detailed info later. Hope we all together can solve the mistery

Att,
Will

You’re right. It’s indeed more complex than anticipated.

I was able to decrypt the first four messages of my dehumidifier connecting to the cloud using the known key from the github repository.
Decryption fails for all the following messages it seems.

I’d assume that they’re negotiating a session key using the shared secret and then switch to that?

To the point I’ve got, there’s more than just a session key (but there’s one too)
There’s cookies and a special HTTP header called X-Smart-Sign that the cloud server sends back in it’s ACK that enters in “the numeric dance” too

As a side note, it SEEMS (take it with a MOUNTAIN of salt) that the LAN part of the talk, packet formation and sign is not obfuscated in the app code. So combining it with @mac_zhou’s code may be a little simpler than I’ve thought

The app seems to ALWAYS use an internal XML to control the protocol steps and than use the obscured lib to translate it to the one that we see in wireshark. But in mac’s code we got most of the fields mappings and the sign part that his protocol don’t seem to have, as I expected, is a MD5 string calculated usign half a dozen parameters

As I’m really busy in work today, I guess next week I’ll get back to decoding it

Are you sure that there’s HTTP involved in the cloud communication of the device?

As far as I’ve seen, my dehumidifier only uses the midea protocol on a raw tcp socket (or UDP broadcasts respectively).

As I said, my device uses another midea cloud and protocol
In MY case I’m absolutely sure that HTTP headers are involved

Not sure if it’s the case in the new cloud devices that use the midea air app

Just to exemplify a difference. In the command header, my AC unit receives 5A5A1501… and replies 5A5A0101… (confirmed in wireshark)

In the decompiled source code (comments by me)

public class v2_message_header {
    public short ckCode;
    public short cmd;
    public byte[] createTime = new byte[8];
    public byte[] devId = new byte[6];
    public byte othParam;
    public short packLen;
    public byte[] reserver = new byte[3];
    public byte secFlag;
    public int seq;
    public byte[] subId = new byte[6];
    public byte[] syncHead = new byte[2];
    public short timeOut = 3000;
    public byte ver;

    public v2_message_header() {
        this.syncHead[0] = 90;  //0x5A
        this.syncHead[1] = 90; //0x5A
        this.ver = 21; //0x15
        this.packLen = 0;
        this.cmd = 0;
        this.seq = 0;
        this.timeOut = 0;
        this.othParam = 0;
        this.reserver[0] = 0;
        this.reserver[1] = 0;
        this.reserver[2] = 0;
        this.createTime[6] = 0;
        this.createTime[7] = 0;
        for (int i = 0; i < 6; i++) {
            this.devId[i] = 0;
            this.subId[i] = 0;
            this.createTime[i] = 0;
        }
    }

That’s only one of the differences but I guess I’ll be able to rebuild all the packet and probably the base command too (also different im my case despite starting with 0XAA)

1 Like

Mac,

I saw the update to 0.1.19, and tried to discover with that version. I am seeing the my unit is using the encryption starting with 8370. Anything I can supply for you to help with this?

Thanks!

CAB426

My library can decrypt the discover udp data that start with 8370, but can’t decrypt the tcp data that start with 8370 , that is new midea protocol .

Hi @mac_zhou

I am try run midea-discover, but I get error:

pip3 install msmart
>pip3 install msmart
Collecting msmart
  Downloading https://files.pythonhosted.org/packages/62/30/24d70c52840e57aabc5807fcae0170d1bf06dc365cdc5f567328886887fc/msmart-0.1.19-py3-none-any.whl
Collecting pycryptodome
  Downloading https://files.pythonhosted.org/packages/d0/af/8621cab02c6ce4eac6c4b5e0839619fc7b1c715ed6aacedee628e0f83364/pycryptodome-3.9.7-cp38-cp38-win32.whl (14.1MB)
     |████████████████████████████████| 14.1MB 1.6MB/s
Installing collected packages: pycryptodome, msmart
Successfully installed msmart-0.1.19 pycryptodome-3.9.7

Output:

midea-discover
>midea-discover
Traceback (most recent call last):
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\runpy.py", line 192, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Users\albina\AppData\Local\Programs\Python\Python38-32\Scripts\midea-discover.exe\__main__.py", line 4, in <module>
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages\msmart\cli.py", line 8, in <module>
    from msmart.device import convert_device_id_int
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages\msmart\device.py", line 6, in <module>
    from msmart.lan import lan
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages\msmart\lan.py", line 3, in <module>
    import requests
ModuleNotFoundError: No module named 'requests'

or:

midea-discover -d
>midea-discover -d
Traceback (most recent call last):
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\runpy.py", line 192, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Users\albina\AppData\Local\Programs\Python\Python38-32\Scripts\midea-discover.exe\__main__.py", line 4, in <module>
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages\msmart\cli.py", line 8, in <module>
    from msmart.device import convert_device_id_int
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages\msmart\device.py", line 6, in <module>
    from msmart.lan import lan
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages\msmart\lan.py", line 3, in <module>
    import requests
ModuleNotFoundError: No module named 'requests'

What’s my mistake? Thanks.

my mistake, no use requests, but import. next version, i will fix it.
but you can pip3 install requests to skip it.

Hi, I am using Kaisai air-conditioner with WiFi module. I was able to connect it to hassio using anderson-midea-ac-py but I prefer to communication using local network only.
I was able to get device id using provider nethome application (share -> qr code -> decode from base64), I have set up fixed IP for this unit on DHCP server.
But unfortunately - still not working. Only log I have is - Update of climate.midea_ac_e75901000011 is taking over 10 seconds

Does anybody have any clue is there any difference beetwen midea and kaisai?

Good news (not fully, but stiil good)

As with the cloud protocol I was able to reverse two first steps (broadcast search and “login”) engeneer the LAN protocol
Next step is the command portion. Guess it will be simple despite two or three bytes in the end off the command string right before the MD5 hash (as I said before, my device do not use EAS encryption but the V2 protocol that uses MD5 hashing instead)

Fingers crossed

Att,
Will

1 Like

Hi, @mac_zhou

After update to msmart-0.1.20

Update msmart
>pip3 uninstall msmart
Found existing installation: msmart 0.1.19
Uninstalling msmart-0.1.19:
  Would remove:
    c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages\msmart-0.1.19.dist-info\*
    c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages\msmart\*
    c:\users\albina\appdata\local\programs\python\python38-32\scripts\midea-discover.exe
Proceed (y/n)? y
  Successfully uninstalled msmart-0.1.19

C:\WINDOWS\system32>pip3 install msmart
Collecting msmart
  Downloading msmart-0.1.20-py3-none-any.whl (14 kB)
Requirement already satisfied: pycryptodome in c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages (from msmart) (3.9.7)
Installing collected packages: msmart
Successfully installed msmart-0.1.20

>pip3 install msmart
Collecting msmart
  Downloading msmart-0.1.20-py3-none-any.whl (14 kB)
Requirement already satisfied: pycryptodome in c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages (from msmart) (3.9.7)
Installing collected packages: msmart
Successfully installed msmart-0.1.20

Output:

midea-discover
>midea-discover
Traceback (most recent call last):
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\runpy.py", line 192, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Users\albina\AppData\Local\Programs\Python\Python38-32\Scripts\midea-discover.exe\__main__.py", line 7, in <module>
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages\click\core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages\click\core.py", line 717, in main
    rv = self.invoke(ctx)
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages\click\core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages\click\core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages\msmart\cli.py", line 49, in discover
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
AttributeError: module 'socket' has no attribute 'SO_REUSEPORT'

or:

midea-discover -d
>midea-discover -d
INFO:msmart.cli:Debug mode active
Traceback (most recent call last):
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\runpy.py", line 192, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Users\albina\AppData\Local\Programs\Python\Python38-32\Scripts\midea-discover.exe\__main__.py", line 7, in <module>
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages\click\core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages\click\core.py", line 717, in main
    rv = self.invoke(ctx)
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages\click\core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages\click\core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages\msmart\cli.py", line 49, in discover
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
AttributeError: module 'socket' has no attribute 'SO_REUSEPORT'

What’s my mistake? Thanks.

Windows networking do not support SO_REUSEPORT
Just comment the 49th line in c:\users\albina\appdata\local\programs\python\python38-32\lib\site-packages\msmart\cli.py

How to do it? I have little knowledge. Thanks.

Open the file in “Editor” (<- Windows Editor), go to line 49 and make a # before that line. Save it and restart. :slight_smile:

1 Like

@paddy0174 @aleksey_z
Sorry. My mistake.
Previously it was intended to use x.x.x.255.
Then I found out that Broadcast is fine. :laughing:

First you have to run midea-discover -d.
Check that your device supported.

After updating msmart to 0.1.20 I was able to get output:
INFO:msmart.cli:*** Found a unsupported ‘0xac’ at 192.168.0.140 - id: my_secret_id - sn: my_secret_seral - ssid: net_ac_5E75

I have air-conditioners Kaisai KWX -18 HRDI and KWX - 09HRDI KDV6 with wifi-modules working fine with Nethome application. Is there something I can do to make it work?

1 Like

Is it possible to have a go and get it up on Github?
That would be of real interest !!!

I am very interested too