Monitor and control Midea air conditioners over the internet — no local network access needed.
Works with accounts registered in the Midea Air or NetHome Plus apps.
Every existing open-source Midea library fails to communicate with devices through the cloud, returning the infamous error 1000 ("system error") on the transparent/send endpoint. After reverse-engineering the Midea Air APK, I discovered four things that all existing libraries get wrong:
-
/newAPI endpoints are required — The old endpoints (/v1/user/login,/v1/appliance/transparent/send) are broken server-side. The working variants end in/newand requireencryptVersion=1. -
m0 packet framing is mandatory — Device commands must be wrapped in a 56-byte transport frame (0x5A5A magic header) before sending. Every library sends raw command bytes, which the cloud relay silently rejects.
-
AES-CBC encryption — The
/newlogin returnsrandomDataused to derive an AES-CBC IV. The old login only supports ECB, which the/newtransparent send rejects. -
33-byte command frames for SET — Control commands must use the same 33-byte frame size as query commands. The 35-byte format used by other libraries is silently ignored by the device (error 3176).
pip install -r requirements.txtRequires Python 3.8+.
# Using command-line arguments
python midea_cloud.py --account your@email.com --password yourpassword
# Using environment variables
export MIDEA_ACCOUNT=your@email.com
export MIDEA_PASSWORD=yourpassword
python midea_cloud.py# Turn on in heat mode at 22°C
python midea_cloud.py --device "Living room" --on --mode heat --temp 22
# Turn off
python midea_cloud.py --device "Living room" --off
# Change temperature (keeps current mode)
python midea_cloud.py --device "Living room" --on --temp 24
# Set fan speed
python midea_cloud.py --device "Living room" --on --mode cool --temp 25 --fan low| Flag | Description |
|---|---|
--account |
Midea account email (or MIDEA_ACCOUNT env var) |
--password |
Midea account password (or MIDEA_PASSWORD env var) |
--app |
App your account is registered with: midea_air (default) or nethome_plus |
--server |
Override API server URL (auto-detected by default) |
--list-only |
Only list devices, don't query temperatures |
--json |
Output results as JSON |
--device |
Device name or ID to control |
--on |
Turn AC on |
--off |
Turn AC off |
--mode |
Set mode: auto, cool, dry, heat, fan |
--temp |
Set target temperature (16-30) |
--fan |
Set fan speed: auto, low, medium, high |
Logging in...
Logged in (server: https://mapp-eu.appsmb.com)
Living room:
Indoor: 22.5 C
Outdoor: 8.0 C
Target: 23 C
Running: True
Mode: Heat
Bedroom:
Indoor: 20.0 C
Outdoor: 8.0 C
Target: 21 C
Running: False
Mode: Auto
python midea_cloud.py --json{
"Living room": {
"running": true,
"mode": "Heat",
"target_temp": 23,
"indoor_temp": 22.5,
"outdoor_temp": 8.0
}
}from midea_cloud import MideaCloud, AC_MODE_HEAT
client = MideaCloud("your@email.com", "yourpassword")
client.login()
# List all devices
devices = client.list_appliances()
# Get AC status
for dev_id, info in devices.items():
if info["type"] == 0xAC and info["online"]:
status = client.get_ac_status(dev_id)
print(f"{info['name']}: {status['indoor_temp']} C")
# Control an AC
client.set_ac(dev_id, power_on=True, mode=AC_MODE_HEAT, temp=22)- Air conditioners (type 0xAC) — full monitoring and control
- Other Midea device types can be added by implementing their command/response protocols
┌──────────────┐
│ Midea Cloud │
│ (mapp*. │
You ──────────────►│ appsmb.com) │──────────────► AC Unit
login/new │ │ transparent/
CBC encryption │ │ send/new
m0 framing └──────────────┘
- Login via
/v1/user/login/newwithencryptVersion=1— returnsaccessTokenandrandomData - Derive AES-CBC keys from
sha256(appKey)→ decryptaccessToken(data key) andrandomData(data IV) - Build command — 33-byte AC command with CRC8 checksum (query or set)
- Wrap in m0 frame — 0x5A5A header, message type, timestamp, device SN, payload
- Encrypt — Convert frame to signed CSV, AES-CBC encrypt with session keys
- Send via
/v1/appliance/transparent/send/newwithfunId=0008 - Decrypt response — AES-CBC decrypt, parse CSV, unwrap m0 frame, parse AC status bytes
The API server is auto-detected based on your account. Known servers:
https://mapp.appsmb.com— Globalhttps://mapp-eu.appsmb.com— Europehttps://mapp-us.appsmb.com— Americas
| Error | Cause | Fix |
|---|---|---|
error 3101 |
Wrong email/password | Check credentials |
error 3102 |
Account not found on this cloud | Try --app nethome_plus |
error 3004 |
Invalid appliance ID | Report as a bug |
error 3176 |
Device didn't reply | Check if device is online; may need retry |
error 1000 |
Shouldn't happen with this tool | File an issue with full output |
error 1011 |
Encryption mismatch | File an issue |
Built by reverse-engineering the Midea Air APK (com.midea.aircondition.obm v5.13.0801). Inspired by midea-beautiful-air, midea-local, and midea_auto_cloud — none of which support working cloud communication.
MIT