Midea branded AC’s with ESPhome (no cloud)

Hi all, I’m using an ESP32-C3 on a Bosch 3000i and it works great.
Yesterday I had the idea to add a counter to measure how long the air conditioner has been on, using the “duty_time” sensor, but it doesn’t seem to work, can someone tell me where I’m going wrong?
Here’s my yaml:

esphome:
  name: bosch-climate-3000i
  friendly_name: Bosch Climate 3000i
  area: Cucina

  on_shutdown:
    then:
      - midea_ac.power_off:

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

# Enable logging
logger:
  baud_rate: 0

# Enable Home Assistant API
api:
  encryption:
    key: "UKCAmFVwyCyhdOUMAymnYnx+vkymNo9cyirrteNOklI="

ota:
  - platform: esphome
    password: "5301b4924b12e50ccd54327287fc9036"

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Bosch-Climate-3000I"
    password: "c223vn7adRYM"

status_led:
  pin:
    number: 8
    inverted: true

captive_portal:

# UART settings for Midea dongle (required)
uart:
  tx_pin: 21         # hardware dependant
  rx_pin: 20         # hardware dependant
  baud_rate: 9600

# Main settings
climate:
  - platform: midea
    name: "Cucina"         # Use a unique name.
    period: 1s                  # Optional
    timeout: 2s                 # Optional
    num_attempts: 3             # Optional
    autoconf: true              # Autoconfigure most options.
    beeper: true                # 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
    supported_modes:            # Optional. All capabilities in this section may be detected by autoconf.
      - FAN_ONLY
      - HEAT_COOL
      - COOL
      - HEAT
      - DRY
    custom_fan_modes:           # Optional
      - SILENT
      - TURBO
    supported_presets:          # Optional. All capabilities in this section may be detected by autoconf.
      - ECO
      - BOOST
      - SLEEP
    custom_presets:             # Optional. All capabilities in this section may be detected by autoconf.
      - FREEZE_PROTECTION
    supported_swing_modes:      # Optional
      - VERTICAL
      - HORIZONTAL
      - BOTH
    outdoor_temperature:        # Optional. Outdoor temperature sensor (may display incorrect values after long inactivity).
      name: "Temp"

remote_transmitter:
  pin:
    number: 10
    inverted: true
  carrier_duty_percent: 50%

switch:
  - platform: template
    name: "Climate Cucina Beeper"
    icon: mdi:volume-source
    restore_mode: 'RESTORE_DEFAULT_ON'
    optimistic: true
    turn_on_action:
      midea_ac.beeper_on:
    turn_off_action:
      midea_ac.beeper_off:

binary_sensor:
  - platform: status
    name: "Climate Cucina Connection Status"
    id: climate_cucina_connection_status
  
  - platform: homeassistant
    name: "Power"
    entity_id: climate.bosch_climate_3000i_cucina
    id: tempo_acceso

text_sensor:
  - platform: template
    name: "Uptime Human Readable"
    id: uptime_human
    icon: mdi:clock-start

  - platform: version
    name: "Climate Cucina ESPHome Version"
    id: climate_cucina_esphome_version

  - platform: wifi_info
    ip_address:
      name: "Climate Cucina IP Address"
      id: climate_cucina_ip_address
      icon: mdi:ip-network

sensor:
  - platform: uptime
    name: "Uptime Sensor"
    id: uptime_sensor
    update_interval: 60s
    on_raw_value:
      then:
        - text_sensor.template.publish:
            id: uptime_human
            state: !lambda |-
              int seconds = round(id(uptime_sensor).raw_state);
              int days = seconds / (24 * 3600);
              seconds = seconds % (24 * 3600);
              int hours = seconds / 3600;
              seconds = seconds % 3600;
              int minutes = seconds /  60;
              seconds = seconds % 60;
              return (
                (days ? to_string(days) + "d " : "") +
                (hours ? to_string(hours) + "h " : "") +
                (minutes ? to_string(minutes) + "m " : "") +
                (to_string(seconds) + "s")
              ).c_str();
    
  - platform: homeassistant
    name: "Follow Me"
    entity_id: sensor.lumi_lumi_weather_temperatura # Sensor from HASS - replace with your own - highly recommended to use (otherwise delete sensor section, or it will not work correctly) - Provides ability for AC unit to use your, external sensor from HomeAss as a main sensor
    id: follow_me
    internal: true
    filters:
      - throttle: 10s
      - heartbeat: 2min             # Maximum interval between updates.
      - debounce: 1s
    on_value:
      midea_ac.follow_me:
        temperature: !lambda "return x;"
        beeper: false               # Optional. Beep on update.

  - platform: wifi_signal
    name: "Climate Cucina WiFi Signal"
    id: climate_cucina_wifi_signal
    update_interval: 30s

  - platform: copy
    source_id: climate_cucina_wifi_signal
    name: "Climate Cucina signal percent"
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    unit_of_measurement: "%"
    entity_category: "diagnostic"
    device_class: ""

  - platform: internal_temperature
    name: "Internal Temperature"
    icon: "mdi:thermometer"

  - platform: duty_time
    name: "Tempo acceso"
    sensor: tempo_acceso

time:
  - platform: sntp
    id: my_time
    timezone: Europe/Rome
    servers: 
      - 192.168.1.1
      - 0.pool.ntp.org
      - 1.pool.ntp.org

button:
  - platform: restart
    name: "Climate Cucina Restart"
    id: climate_cucina_restart
    icon: "mdi:restart"

  - platform: shutdown
    name: "Climate Cucina Shutdown"
    id: climate_cucina_shutdown

  - platform: safe_mode
    name: "Climate Cucina Safe Mode"
    id: climate_cucina_safe_mode

  - platform: factory_reset
    name: "Climate Cucina Factory Reset"

  - platform: template
    name: "Swing Step"
    icon: mdi:tailwind
    on_press:
      midea_ac.swing_step:

  - platform: template
    name: "Display Toggle"
    icon: mdi:theme-light-dark
    on_press:
      midea_ac.display_toggle:

web_server:
  port: 80
  version: 3
  local: true

For units like the ‘slim duct’ model where the room temperature value is taken from the T1 sensor (incoming air stream), ‘Follow Me’ mode is pretty much required to have it cool/heat the room accurately. Many non-ducted units likely also work better with ‘Follow Me’ used, because the temp is actually being sensed at the remote, which isn’t high on the wall or near where air is moving in/out of the unit.

I have a 18K ducted model (Pioneer rebadge) in the attic that is responsible for 3 bedrooms, and it is generally pretty good with the following tweaks:

  • An ESP8266 in the attic connected to XYE (read-only) and an IR LED that is aimed at the control board to set modes/temp and provide the critical “follow me” value
  • Another ESP device in one of the bedrooms using a Dallas temp sensor to provide room temp, which are sent via the above ESP as “follow me” values at 60 second intervals
  • Some basic rounding/ceiling floor tweaks to the room temp (one decimal place) → follow me value (no decimals), in Fahrenheit. These use some of the XYE sensors:
    • In cool mode, if running, send the floor of the actual temp, otherwise the ceiling
    • In heat mode, if running, send the round of the temp, otherwise the floor
  • My 5-wire thermostat sits unused (and ugly) on the wall

There’s still some strange behavior where these units try to be too smart for their own good. In heat mode, mine strongly prefers to run at a low-power level (~500W), and it will happily let the temp drift about -2F from the setpoint before it kicks into high gear (1000W+), where it can overshoot a bit (+1F). Turbo/boost mode will force it to this high gear if I send that IR instruction.

In cool mode, without adjustments, it normally takes about a +3F setpoint delta to turn on, and it will overcool to -3F. My tweaks above bring that delta much closer to +/-1F, which makes a big difference. Again, turbo mode makes it more responsive to the actual setpoint delta.

My ESP for the remote temp sensing also has an LCD display that shows key XYE values, and I’ve debated adding some basic buttons to make it a DIY thermostat. The algorithm could also be tweaked a bit to force turbo mode and/or lie about the room temp to get the unit to ignore its own stupid algorithms, but I’ve gotten it close enough to where I wouldn’t want to lose the effeciency of running at lower power by forcing it to be more of a on/off type unit.

The newest 4-wire thermostats actually look pretty good, but I like how I have mine set up now

If you have a wired XYE controller, you can set up an RS485 listener to decode the messages sent and received to reverse engineer the protocol. It will have to only listen though - can’t have two masters on one bus.

Thanks! I have the Carrier 38MBRCQ36AA3 with 40MBABQ36XA3 which is a “ductless” Midea, even though it’s installed ducted. This device supports 24V thermostat interface and my installer installed an EcoBee. That one I can connect flawlessly via HomeBridge.

However, I feel that using the 24V interface (contrary to claims on the web) reduces the variable speed system to a single stage: It only runs full (or in 2 steps) and tends to be loud. With the HA/HB controller I feel it runs less noisy. But also it runs pretty much all the time and runs way beyond my set point. As I said, sometimes I need to decrease the set point by many degrees and turn off and on again to make it shut up. Do you have the option for 24V thermostat too?

An ESP8266 in the attic connected to XYE (read-only)

What does this ESP do? What’s the point of just reading from XYE?

and an IR LED that is aimed at the control board to set modes/temp and provide the critical “follow me” value

That’s where I am getting confused. For what? Doesn’t the thermostat have an integrated temperature sensor? I can just enable “Follow Me” on my KSACN1001AAA which, if I understand correctly, sends the temperature from the wall to the control board via HA/HB interface.

Also, do you have a picture of your control board? My control board is in the air handler. My thermostat (KSACN1001AAA) has an IR receiver and I also have a wireless remote control but I don’t see the point since the thermostat has the thermometer anyway (to my understanding)

  • My 5-wire thermostat sits unused (and ugly) on the wall

What interface if 5-wire exactly? 24V legacy interface?

The newest 4-wire thermostats actually look pretty good, but I like how I have mine set up now

Is it this one? Why do you call it “4-wire”? It’s HA/HB interface…
Seems very similar to my KSACN1001AAA. I’d be really curious if this one can show the current temperature even when turned off. I am so mad that mine just shows a blank display when turned off…

@exciton

If you have a wired XYE controller, you can set up an RS485 listener to decode the messages sent and received to reverse engineer the protocol. It will have to only listen though - can’t have two masters on one bus.

What do you mean exactly by “wires XYE controller”? Is this a device that can be purchased?

That was my assumption about that add-on module (Pioneer sells one, but I don’t own it.) It makes these variable speed, inverter-driven compressor minisplits act more like the bang-on/bang-off traditional split systems that are still common in the USA.

I can get access to some (I wish for more) data from the unit’s sensors and control logic. Namely, T1 (air in temp), T2 (indoor coil temp), T4 (outdoor coil/air temp), compressor run/defrost state, and actual fan speed in auto mode. I have my EPA 608 Type 2, and these sensors help me to understand what the unit is actually doing and how to work around its crazy logic.

My unit came with the biggest POS ‘thermostat’ Midea makes (KJRC-12B), which is really just a wired IR remote. There’s no communication back to the thermostat (besides on/off), and the ‘Follow Me’ never worked correctly. It also doesn’t receive IR like some of the newer thermostats do.

The controller just sends the IR commands over 2 of the wires, and there’s literally an IR LED sitting on the ‘display board’ that shines over to the IR receiver on the same board.


5wire-board

Midea units have numerous control options, and some units implement a subset of these. Midea doesn’t even have universal names or circuit board connector ID numbers for these. This forum thread also has posts that reference different types; here’s my attempt at a breakdown:

  • 5-wire: IR over the wire, basically
  • 4-wire: RS-485 (2 wires), and 5V/12V +/- (2 wires)
  • HA/HB (2 wire): modbus?
  • XYE (3 wires): RS-485 (2 wires), ground (1 wire)
  • UART
  • LNS: high voltage modulated signal between indoor/outdoor

Nobody has confirmed if some of these ports can handle multiple protocols or what overlap there is. I’m hoping someone with a modern 4-wire controller (KJR 120N/M) could sniff the RS485 lines and see if it talks the XYE-protocol, modbus or something else. If it talks XYE-protocol, there’s some functionality that hasn’t been documented yet.

Look for midea CCM (centralized controller) units (I have one in the picture above.) I believe the XYE protocol documented on the codberg site was sniffed from one of these, so it’s mostly just basic query/set commands. If the 4-wire controllers also speak XYE, there’s more set/query commands to sniff that aren’t documented anywhere.

Im trying to find which pins correspond to potential ground, vcc,tx and rx and making sure if its 3.3v or 5v. But none of those pins (EYX or the S485) give me a ground to the ground screw right besides the board… Im confused…

Tho this is what I found (from top to bottom)

E(suppossedly ground?) Is linked to 485 pin 1(if + polarity) and 2 (if - polarity on the probes)

Y is linked to 485 pin 3

X is linked to 485 pin 4.

Neither pin 1 ,2 or E give me ground on the ground
How is that possible ?

I would like to read those pins with Rasp.Pi eventually and figure out if there might be a kernel behind all this… Any thought on the pins multimeter reading ?

Yours looks like exactly my board! (Carrier 40MBABQ36XA3). I have just tried measuring this myself yesterday and accidentally shorted my test leads. The good news: It seems to have short protection. I heard a relays switching quickly and the whole machine turned off. I flipped the breaker, then turned it back on and the system still seems to work as normal. Didn’t continue because it was late and cold.
My intention was to get +12V for supplying ESP32.

What did you measure exactly? Resistance measurement when unit turned off?

Question: Are you suggesting the blue and cyan pins are shorted/connected? Did you confirm? I was wondering already if the “S-485” connector is a different interface than EYX but it seems you assume it’s just the same with a different connector?

PS: There is no RX or TX in RS485. It’s a differential interface that carries data both ways. So technically not even ground would be needed.

I found this solution:

    on_state:
      - logger.log: "State updated!"
      - lambda: |-
          if (x.mode != CLIMATE_MODE_OFF)
            id(tempo_acceso).publish_state(true); 

But it doesn’t work properly, how do I make the counter scroll when it’s on in any mode and stay at 0 when it’s off?

I am pretty sure that the manual for my Pioneer said that there was a built-in interface for an old-school bang-bang thermostat. I don’t think that it supplied 24V to power a smart thermostat, and there are cheaper options out there if that’s all that the linked Pioneer interface does.

I ruled out using a bang-bang thermostat before even starting my ducted 18K RYB install, because it defeated the main benefit of an inverter AC/heat pump…

I measured the continuity to try and find the ground pin first to not short anything. The machine was off I didnt wanna risk the brand new 5K $ machine lol. I was trying to figure out , ultimately the voltage on those pins… and if there was a Kernel behind those ports … and If I could play with a Raspberry Pi directly on it. But I guess that this 485 port is the same one as the other mini units up this tread and with the TTL and ESP32 I could do the same thing? And if I need a voltage step level shfiter before I hook it up…

Ok, that works, but the timer doesn’t reset to 0 when the air conditioner is turned off.
Does anyone have a solution?

    on_state:
      - logger.log: "State updated!"
      - lambda: |-
          if (x.mode != CLIMATE_MODE_OFF)
            id(tempo_acceso).publish_state(true);
      - lambda: |-
          if (x.mode != CLIMATE_MODE_FAN_ONLY)
          if (x.mode != CLIMATE_MODE_HEAT_COOL)
          if (x.mode != CLIMATE_MODE_COOL)
          if (x.mode != CLIMATE_MODE_HEAT)
          if (x.mode != CLIMATE_MODE_DRY)
            id(tempo_acceso).publish_state(false);

Edit: Resolved with:

  - platform: template
    name: "Power"
    id: tempo_acceso
    internal: True
    on_state:
      then:
        - sensor.duty_time.reset: runtime

Hello,

I have a Vaillant VA 2-035 CN fan coil, which is identical to the Midea MKH2-V350-R3 type. I am currently using it with a Vaillant VA 2-WC C wired controller, which is identical to the Midea KJRP-75A/BK-E wired controller.

Unfortunately, this controller is not suitable for the control I want (no WiFi, weekly programming, reduced temperature programming, etc.). Unfortunately, Midea does not sell a WiFi controller for this fan coil and I was wondering if it could be solved with the help of HA if I could create a WiFi controller for fan coils.

This solution is designed for indoor air conditioning, does it work with the above parapet fan coils? Has anyone tried something like this?

Thank you for your help.

My Carrier Performance system is identical to the Midea Ductless system. Even the part numbers are the same. From my service manual:

From this text it’s really suggested that using the 24V interface (SCENARIO #2) does not result in any performance degradation. My installer installed the Ecobee with that interface and insists that’s the right thing (he has no f** clue though). Online I found many claims that in that configuration, T1 would be used for control (as opposed to just the on/off from the thermostat) and as such, the operation would be very similar to using the included thermostat and in particular, it would still operate as a variable speed system.

However, based on the power draw, this just doesn’t seem to be the case:

The pink one is the EcoBee. It can be seen that with the EcoBee (24V interface) it’s basically on at ~5kW or off.

I also measured noise level: ~33dB on low speed, ~39dB when running a bit more when the included thermostat. And 47dB (!) with the EcoBee.

1 Like

Sorry I really have a hard time following you. What’s a kernel behind the ports? I am pretty sure the S-485 connector is actual RS485 with 12V. No TTL. I haven’t tried connecting anything yet but given that XYE is actually also RS485 and that connector is right next to it, I am wondering if it’s just the same interface. I’ll try as well once I get the chance.

I just tried using modbus on the XYE terminals (9600 baud, 1 stop bit, address 0x1), and I got no response trying to read registers 0x3 (air temp), 0x66 (fanspeed). I saw those settings used in other Midea modbus configs hooked to the HA/HB terminals, and I assumed I’d see something.

It’s too much of a pain to lug the oscilloscope up to the attic to really dig into it, but I assumed that XYE didn’t talk modbus anyway, considering there are add-on devices sold by Midea and others to adapt XYE to modbus.

Thanks for confirming, that’s what I thought as well.

For @th4h4x and my board, we have HA/HB, XYE and S-485 on the board in our air handler (see Midea branded AC’s with ESPhome (no cloud) - #1240 by th4h4x).

I am curious is the S-485 port is modbus or maybe just another connector for XYE.

Would you mind sharing the ESPhome yaml (I assume that’s what you used) to test? I haven’t used modbus before. I’d like to see what I can get out of the S-485 port…

Sure. There’s nothing interesting in my common.yaml, it’s just Wifi signal sensors and such.

substitutions:
    location: attic
    locationName: Attic
    device: esp8266
    deviceName: Esp8266
    deviceDescription: Attic Esp8266 192.168.50.80
    static_ip: 192.168.50.80

packages:
    common: !include common/common-mqtt.yaml

esp8266:
  board: nodemcuv2

# Disable serial logging (we're using that UART channel)
logger:
  baud_rate: 0
  level: VERBOSE

uart:
  id: mod_bus
  baud_rate: 9600
  stop_bits: 1
  tx_pin: GPIO1
  rx_pin: GPIO3

modbus:
  id: heatpump_modbus
  uart_id: mod_bus

modbus_controller:
  - id: heatpump_modbus_ctrl
    ## the Modbus device addr
    address: 0x1
    modbus_id: heatpump_modbus
    setup_priority: -10
    update_interval: 10s


# Individual sensors
sensor:

  - platform: modbus_controller
    modbus_controller_id: heatpump_modbus_ctrl
    name: "Air Temperature Ts"
    id: "test_air_temperature_ts"
    icon: mdi:temperature-celsius
    register_type: holding
    address: 0x3
    value_type: U_WORD
    unit_of_measurement: "°C"
    filters:
      - multiply: 0.5

  - platform: modbus_controller
    modbus_controller_id: heatpump_modbus_ctrl
    name: "Test Fanspeed"
    id: "test_fanspeed"
    register_type: read
    address: 0x66
    value_type: U_WORD
  

I don’t think so. The pins are indicated as HA/HB, same as my wired controller (KSACN1001AAA). It is similar as RS485 but it also carries power. This likely corresponds to the proprietary protocol we don’t know much about yet (@fabius found the patent)

Note that I connected RS485 receiver to HA/HB, but the unit shuts off (probably due to some protection mechanism).

Why is XYE better than modbus (=H1/H2 pins)?
I thought modbus provides direct access to all registers whereas XYE is a predefined protocol with limited function set.

And I thought follow-me can be set via modus … is that not true?

Fair enough. I know many of the thermostats designed for HA/HB (2-pipe as it’s translated in Midea manuals) have terminals inside the shell for modbus hookups. The only modbus info I’ve seen for Midea stuff is mostly for their air:water units popular in Europe. You should see if your thermostat has them.

It’s not, at least with what’s been documented so far. It’s not clear how the 4-wire thermostats set the internal reference temp (what follow-me sets). Modbus would be easier to explore (many registers are listed in those air:water HP manuals), instead of the XYE protocol with the unknown command byte.

After getting frustrated with fan settings on mine today, I’m about to ESPHome lambda my way to one of those bang on/bang off controllers. “If I set the fan to ‘High’, that’s what speed I want - [Midea smugly sets it to Low] - stop trying to outsmart me!”

Thanks for the pointer!

My controller (KSACN1001AAA) is identical with @dbaq (see here and pictures here) and also @th4h4x looks identical (both from picture and board). There is indeed a COM485 connector. I’ll also check there on the weekend if I can get anything out there. You say, this would be modbus? (and would be “bridged” to the HA/HB interface)?

Actually, @dbaq , in your pictures there is something connected but I’m not able to see what. What exactly do you have connected here?

PS: Where did you actually get this picture from?