Midea branded AC’s with ESPhome (no cloud)

Yes, this is the method I use. but Mosibi documented the project much better.

I hope you’re right:) It would be awesome to get a 16kW model out of a 12kW one…

Hi @exciton thank you for your efforts! Great work!!

I have a US Carrier machine and it seems my protocol is slightly different. All my temperatures from the unit show up directly in Fahrenheit. It seems that neither do I have to perform the arithmetic (subtract by 0x30 and divide by 2), nor is it different for the temperature fields. All seem to show Fahrenheit directly.

Here is an example:
AA:C0:80:00:00:00:30:14:00:80:3C:3D:3C:00:36:FF:00:00:00:00:00:00:00:00:00:00:00:14:FF:FF:00:55

Set Temp: 60F, T1=61F, T2A=60F, T2B=0 (maybe unsupported??), T3=54F.

Yet, my numbers in Home Assistant show up as if the raw numbers were in C. For example, my set point shows as 140F (which would correspond to 60C). But 60 is already in F. CalculateTemp() will be just unity function for me.

But where does a double conversion happen here? Where (either in the yaml or the CPP file) is the unit assigned to the sensors? I assume HA believes it’s C and converts to F. But I need to tell ESPhome that all the temperature sensors are in F. Any advice?

I finally got my SLWF-01pro board. It looks Like I have a revision 2 of the board. It worked on first boot. I went to change the yaml so I could get whole degree movements instead of .5. Now I get

Sending request again. Attempts left: 1…
13:57:39 [D] [ApplianceBase:162]
TX: AA 21 AC 8D 00 00 00 00 00 03 41 81 00 FF 03 FF 00 02 00 00 00 00 00 00 00 00 00 00 00 00 03 CC 5E B1
13:57:39 [W] [component:237]
Component midea.climate took a long time for an operation (193 ms).
13:57:39 [W] [component:238]
Components should block for at most 30 ms.

EDIT: R2.1 of the board changes the uart pis so the config should be like this:

uart:
  tx_pin: 12
  rx_pin: 14
  baud_rate: 9600

1 Like

The units are set in climate.py e.g. line 143:

            cv.Optional(CONF_OUTDOOR_TEMPERATURE): sensor.sensor_schema(
                unit_of_measurement=UNIT_CELSIUS,
                icon=ICON_THERMOMETER,
                accuracy_decimals=1,
                device_class=DEVICE_CLASS_TEMPERATURE,
                state_class=STATE_CLASS_MEASUREMENT,
            ),

Thank you!! It seems though UNIT_FAHRENHEIT does not exist:

ERROR Unable to import component midea_xye.climate:
Traceback (most recent call last):
  File "/esphome/esphome/loader.py", line 176, in _lookup_module
    module = importlib.import_module(f"esphome.components.{domain}")
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1206, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1178, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1149, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 940, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/data/external_components/812aeddb/esphome/components/midea_xye/climate.py", line 7, in <module>
    from esphome.const import (
ImportError: cannot import name 'UNIT_FAHRENHEIT' from 'esphome.const' (/esphome/esphome/const.py)

I am not really proficient in ESPhome. In your opinion, what is the proper way to implement this (case: US device that reports raw data in F and I also want to show it in F).

Is the best to just add a conversion function directly in C++ ? How could I add a property to AirConditioner class to define whether I have a US model or non US model? I was thinking of something like:

climate:
  - platform: midea_xye
    name: Heatpump
    type: fahrenheit

And then in the code:

if(this->type == CELCIUS)
   setClientCommand(CLIENT_COMMAND_CELCIUS);
[...]
if(this->type == FAHRENHEIT) {
  TXData[8] =  Celsius2Fahrenheit(this->target_temperature);
} else {
  TXData[8] =  this->target_temperature;
}
[...]

if(this->type == CELSIUS) {
  update_property(this->current_temperature, (float)CalculateTemp(RXData[RX_BYTE_T1_TEMP]), need_publish);
} else {
  update_property(this->current_temperature, (float)Fahrenheit2Celsius(RXData[RX_BYTE_T1_TEMP]), need_publish);
}
[...]

Well … I did it on mine and it works just fine (and reports itself as 16kW model) and I’ve seen a few peaks to about 15kW in heating power when the weather was right :slight_smile:

1 Like

Where can you see what model it reports itself?

Most likely you will need wf-60a1 module that connects to CN40 port on mainboard, than you can connect esphome stick to it:
obraz

1 Like

You can check this on the wired controller in “Operation parameter” menu, it is called outdoor unit model or something similar. You can also read it over modbus, it’s register address 123.

awesome, thank you! hopefully I’ll have mine connected in a week or two and can test it.

I just installed a SLWF-01 purchased from Smartlight for use in my new Midea U-shaped A/C. This is the new 2024 revision that comes with an SK-109 dongle.

Works great but the only thing I noticed is that the power consumption entity is really inaccurate (reporting 45 watts when running, 150 watts when compressor is going full tilt). Is there any way to adjust this properly? I’ve already flashed my own YAML config (the stock config was completely wrong) so making additional changes is no longer an issue.

Second issue, in the ESPHome dashboard it shows as “offline”. I can connect to it to view the logs. Everything else seems ok, but the “offline” status bothers me. Here is my config.

 esphome:
  name: upstairs_hallway_ac
  platform: ESP8266
  board: esp12e
  name_add_mac_suffix: true

wifi:
  ssid: "redacted"
  password: "redacted"
  manual_ip:
    static_ip: 192.168.1.129
    gateway: 192.168.1.1
    subnet: 255.255.255.0
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "upstairs hallway fallback"
    password: "slwf01pro"

# Enable logging
logger:
  baud_rate: 0

# Enable Home Assistant API
api:
  encryption:
    key: "redacted"

ota:
  password: "redacted"


captive_portal:
    

uart:
  tx_pin: 1
  rx_pin: 3
  baud_rate: 9600
  
  
climate:
  - platform: midea
    name: "Upstairs Hallway A/C"         # Use a unique name.
    period: 1s                  # Optional
    timeout: 2s                 # Optional
    num_attempts: 3             # Optional
    autoconf: true              # Autoconfigure most options.
    beeper: false                # Beep on commands.
    visual:                     # Optional. Example of visual settings override.
      min_temperature: 17 °C    # min: 17
      max_temperature: 30 °C    # max: 30
      temperature_step: 0.5 °C  # min: 0.5
    outdoor_temperature:        # Optional. Outdoor temperature sensor (may display incorrect values after long inactivity).
      name: "Outside Temp"
    power_usage:                # Optional. Power usage sensor (only for devices that support this feature).
      name: "Power Consumption"

web_server:
  port: 80

I picked up the Smartlite USB Dongle, which seems to work well with my Midea U AC, the power, temp, beep, fan oscillation, and modes all work, and it seems like it can read the fan speed/mode, as in I can change it on the AC unit and it shows up in HA but setting it from HA doesn’t seem to do anything. Any ideas?

Not 100% sure this is your issue, but make sure this is checked. Click “configure” on the device you just added.

Ok, I ended up adding conversion and this is controlled via a reports_fahrenheit property. It is false by default but can be set to true if someone has a US unit (like me). I created a PR for this.

But more general question: The current temperature is actually identical to “Inside Coil Temp”. This is pretty useless because the air handler is in the basement. True, if running, it should be similar to the air temperature in the living space but even then it’s not accurate. And if not running, it’s totally inaccurate in the first place, because air handler is in non-conditioned space.

For this reason, the wired remote has the “Follow Me” function.

Do you know if this can be made to work in conjunction with the the remote controller?

I think wired controllers also use the XYE bus. Should be possible to use it alongside the XYE dongle, but may need to adapt the code a bit to ignore commands from the remote, and may need to set a different address on the bus.

Would be a perfect setup for reverse engineering actually!

Hello there!

I has a Hommyn “usb” stick for AC controlling, and wire for my conditioner. It has proprietary firmware with cloud. On standart firmware stick works with my ac.

But this cloud doesn’t has HA integration. Internet says, this stick is ESP32-C3 and i already put esp32 firmware in it, and it’s avaliable thru network, but i has no answer from AC:

|18:19:40|[D]|[ApplianceBase:146]|Sending request again. Attempts left: 1...|
| --- | --- | --- | --- |
|18:19:40|[D]|[ApplianceBase:162]|TX: AA 21 AC 8D 00 00 00 00 00 03 41 81 00 FF 03 FF 00 02 00 00 00 00 00 00 00 00 00 00 00 00 03 15 95 31|
|18:19:42|[D]|[ApplianceBase:139]|Response timeout...|

Config part (from internet too):

esphome:
  name: esphome-web-d7d4d0
  friendly_name: ZAL_AC

esp32:
  board: esp32-c3-devkitm-1
  framework:
    type: arduino

# Enable Home Assistant API
api:
  encryption:
    key: "TNC4ztZw/CWZwwOj7OC/5YLqCDyxThNrU0D3uUvEIJM="

ota:
  password: !secret ota_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Midea-AC"
    password: "Midea-AC"

captive_portal:

web_server:
  port: 80

uart:
  id: uart_bus
  tx_pin: GPIO21
  rx_pin: GPIO20
  baud_rate: 9600

# Enable logging
logger:
  baud_rate: 0 # ВАЖНО! БЕЗ ЭТОЙ СТРОЧКИ НЕ СТАРТАНЕТ!

climate:
  - platform: midea

USB D+ is TX, D- is RX from ESP

How can i detect, which pin is correct?

But it doesn’t look like a default esp32-c3-devkitm-1

If I take a look at the pin layout of the ESP32-C3:


It looks like it can use
GPIO2
GPIO3
GPIO8
GPIO9
GPIO10
GPIO18
GPIO19

so

Sounds wrong on a ESP32-C3 :

Which GPIO’s are actually used on the USB plug is up to the manufacturer of the board…maybe you can use a multimeter to determen which GPIO’s are going to the USB?
Or ask the manufacturer (if he is willing to provide it)?

its sure named esp32-c3 on chip

this theme is new for me, so how i can use multimeter for diegnose?

Just noticed I overlooked 2 pins,
U0TXD and U0RXD (pins 27 & 28),
and if I trace the copper traces from your picture, I think those are the ones going into the direction of the usb plug…

Reading some more on ESP32-C3 found this:


so i have to redraw my earlier statement regarding GPIO20/21 :thinking:

And just to be clear…this is a midea branded AC?

Just checking, as the cloud for midea branded AC’s is supported by HA (using midea integration on hacs)
(what is the type and brand anyway?)