ESP32-based bidirectional MQTT <-> D1D2 gateway for Midea VRF air conditioning systems.
This project listens to the Midea D1D2 bus, tracks the state of indoor units (IDUs), publishes their status to MQTT, and allows MQTT commands to control the units. The MQTT interface is compatible with Home Assistant MQTT Climate (HVAC) integration.
The D1D2 protocol used by this project is documented in the companion repository: midea-d1d2-protocol
Community discussions can be found here
- Monitor multiple indoor units on the D1D2 bus
- Publish indoor unit state to MQTT
- Control indoor units via MQTT
- ESP32-based implementation
- RS485 interface for D1D2 communication
- Local control - no internet needed
- Home Assistant friendly
Tested with:
- ESP32
- MAX485-compatible TTL-to-RS485 transceiver
- Midea VRF system
Midea D1D2 Bus <-> RS485 Transceiver <-> ESP32 <-> MQTT Broker <-> Home Assistant
The project requires:
- ESP32 development board
- Arduino IDE
- MQTT broker (e.g. Mosquitto in Home Assistant Apps)
Edit secrets.h and replace the example values with your own.
Edit the AcUnit ac[] array in ac_config.h and configure the names and addresses of your indoor units.
In the provided file, I have 6 indoor units and e.g. study's address is 0x01
Note that the D1D2 protocol uses 16-bit addresses internally, but only the lower byte is used in this implementation (e.g. 0x0001 -> 0x01)
Example:
const int NUM_ACS = 3;
AcUnit ac[NUM_ACS] = {
{ "gaming_room", 0x01, ... },
{ "living_room", 0x04, ... },
{ "master_bedroom", 0x05, ... },
};Note that the names are used as MQTT topic names and should be unique. The addresses must match the addresses configured in your VRF installation.
Published by the controller:
midea_ac_vrf/<room>/state/mode
midea_ac_vrf/<room>/state/temp
midea_ac_vrf/<room>/state/fan
midea_ac_vrf/<room>/state/swing_h
midea_ac_vrf/<room>/state/swing_v
Subscribed by the controller:
midea_ac_vrf/<room>/cmnd/power
midea_ac_vrf/<room>/cmnd/mode
midea_ac_vrf/<room>/cmnd/temp
midea_ac_vrf/<room>/cmnd/fan
midea_ac_vrf/<room>/cmnd/swing_h
midea_ac_vrf/<room>/cmnd/swing_v
A sample MQTT Climate configuration (for two rooms) is included here and can be used as a starting point for Home Assistant integration.
I also added a dashboard example here using mashroom-cards.
This project is actively used to control my own Midea VRF installation.
The implementation currently focuses on the subset of D1D2 commands required for practical monitoring and control of indoor units.
Additional protocol features may be added in the future as they are decoded and validated.
In my VRF system, a WiFi wall controller is connected to the living room IDU. This has forced this unit to become the master on the D1D2 bus.
I initially disconnected the wall controller from this IDU, hoping the unit would stop acting as master and become a slave. That did not work, and this unit is still acting as master and continuously communicates.
I have now disconnected this unit from the bus and am controlling the remaining units. I am still trying to find a way to fix this behaviour. Any help is appreciated.
-
Decode room temperature (and humidity if supported by the indoor unit) from the D1D2 protocol and publish it to MQTT and Home Assistant HVAC Climate integration.
-
Add per-IDU
availabilitystatus. For example, if an indoor unit stops responding (e.g. power failure or bus issue), mark it asunavailablein Home Assistant. This could be implemented using a timeout (e.g. 60 seconds without valid response). -
Add over-the-air (OTA) WiFi firmware update capability.
-
Migrate the project to a more structured build environment such as PlatformIO for improved dependency and project management.
During installation, by accessing the engineering menu on the wall controller, it was able to communicate with the living room IDU and assign it as the master.
It also assigned random addresses to all units, which were displayed on the wall controller.
Interestingly, it is possible to set or modify IDU addresses using the IR remote controller. This is documented on page 26 of this user manual
I assume that in a system without a wall controller, the D1D2 bus is still physically wired. In that case, it is possible that the IDUs are in an uninitialised state and default to acting as slaves with address 0.
If this assumption is correct, there are two possible approaches:
- Assign different addresses to each IDU using the IR remote controller, then wire all D1D2 lines together and connect the ESP32 controller
- Leave each IDU at address 0x00 (or default), and use one ESP32 controller per IDU
This project is an independent reverse-engineering effort and is not affiliated with or endorsed by Midea.
It has been tested on a single Midea VRF installation. Use at your own risk.
This controller directly writes to HVAC system control bus. Improper configuration may affect system operation.

