Midea A/C via local XYE

New branch to test:
units_switch

This adds in a “Use Fahrenheit” switch. If off, uses 0xC0 for set temp…if on, uses 0xC4.

Also adds Defrost State
Also adds Fan Speed (actual)

Thanks to Cursor for helping fly through the switch add and the two States…

Please test and let me know if this works for you too…

external_components:
  - source: github://mdrobnak/esphome@units_switch
    components: [midea_xye]
    refresh: 0s

# Main settings
climate:
  - platform: midea_xye
    name: Heatpump
    id: heatpump
    period: 1s                  # Optional. Defaults to 1s
    timeout: 200ms              # Optional. Defaults to 100ms
    beeper: false               # Optional. Beep on commands.
    #default_target_temperature_low: 18°C
    #default_target_temperature_high: 24°C
    #custom_auto: true
    use_fahrenheit: true
    defrost:
      name: Defrost Active
    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. 
      - FAN_ONLY
      - HEAT_COOL              
      - COOL
      - HEAT
      - DRY
    supported_presets:      # Optional
      - BOOST
    outdoor_temperature:        # Optional. Outdoor temperature sensor
      name: Outside Temp
    temperature_2a:             # Optional. Inside coil temperature
      name: Inside Coil Inlet Temp
    temperature_3:
      name: Outside Coil Temperature
    timer_start:                # Optional. On timer duration
      name: Timer Start
    timer_stop:                 # Optional. Off timer duration
      name: Timer Stop
    error_flags:                # Optional.
      name: Error Flags
    fan_speed:
      name: Fan Speed
    protect_flags:              # Optional. 
      name: Protect Flags
    static_pressure:
      name: Static Pressure
      min_value: 0

sensor:
  - platform: homeassistant
    entity_id: sensor.thermostat_temperature_source
#    entity_id: climate.thermostat
    id: variable_thermostat_follow_me
#    attribute: current_temperature
    name: "Variable Thermostat"
    filters:
      - throttle: 10s
      - heartbeat: 1min
      - debounce: 1s
      - lambda: return (x - 32.0) * (5.0/9.0);
    on_value:
      midea_ac.follow_me:
        temperature: !lambda "return x;"
  - platform: wifi_signal
    name: ${friendly_name} Wi-Fi Signal
    update_interval: 60s
  - platform: uptime
    name: "Uptime"
    id: uptime_sec
    internal: true
  - platform: template
    name: ${friendly_name} Uptime Days
    lambda: |-
      return (id(uptime_sec).state/60)/60/24;
    icon: mdi:clock-start
    unit_of_measurement: days
    update_interval: 60s

switch:
  - platform: midea_xye
    midea_ac_id: heatpump
    use_fahrenheit:
      name: Use Fahrenheit
1 Like

I thought 0xC4 is for the Extended Query and has different data in its payload. I realize I’m stepping in mid conversation so I don’t have all the history/context for your dev work.

I’ve just spent quite a bit of time integrating the two cmds into my Senville XYE Node-Red parser and I’ve been unsuccessful with 0xC4, the payload seems to mostly be static data, I’ve been parsing it based on @Oscar_Calvo’s repo.

In my setup, I’m using Fahrenheit even with 0xC0 but as soon as I issue a 0xC4 query something changes and the setpoint in 0xC0 changes to Celsius. The other reported T temps also increase slightly but I can’t figure out why or how to decode them to match the pre-0xC4 temps. After a power cycle on the indoor air handler (it’s a ducted central air unit) the 0xC0 temps return back to their proper Fahrenheit values.

Yes.

The difference being that from my initial tests, 0xC0 always returns in C.
If retrieving the set temperature from 0xC4, if you have set it in Fahrenheit (using the offset), it will return it in such. If I remember correctly, 0xC0 does not respect this behavior and is always in C. This is fine for HA which works in C internally anyway…but makes a difference with the unit’s algorithm when working in F.

See this post: Midea A/C via local XYE - #12 by mdrobnak for my understanding of the data.

The item in question here is 0xC4 Field 19, Temperature Setpoint. This is different from 0xC0 field 11, which seems to be in degrees C only.

The issue is some units always seem to return 127 degrees F for some reason… Maybe I need to mask a bit out?

On my AHU the only unique items are the Temp Setpoint in F, and the Outside Temperature.

-Matt

So far so good. I’ve rebased my changes from last year atop your branch:

Oh, nice. Sorry, I missed those changes! I did forget why you had a T1 sensor broken out though, but the rest of it all looks good…I’ll try and pull your patches in.

Does your unit support F or just C? Do you get any funky reading in either mode?

-Matt

I’m joining this conversation now.

Does anyone have a suggestion of a branch to start experimenting with for a Midea MDV-V230WN1(AU)?

I developed a sytem for controlling the Evap via ESPHome and RS485 so I can do some testing & improvements as necessary. Just need to order some more hardware first.

Not sure about that unit specifically. That looks to be much more advanced than what I have.

That said, I’m going to start publishing tags.

I recommend people change to one of the tags listed below:

** BUG FIXES and NEW TAGS **

mdrobnak-0.1.1 - Legacy stable - Use only if you haven’t updated ESPHome
mdrobnak-0.2.1 - Stable code updated for newer ESPHome versions. No AI-assisted code here.
mdrobnak-0.3.0 - This has a few new options (defrost state, Fahrenheit switch in the UI, and current actual fan speed). This is the current working units_switch branch. Most people should run this. Use the YAML from Midea A/C via local XYE - #160 by mdrobnak.
(Replace units_switch in - source: github://mdrobnak/esphome@units_switch with mdrobnak-X.Y.Z)

I am pulling some commits from @rymo including some binary sensors to start…I need to understand the context of some of the others first before pulling more. Maybe I’ll have Cursor look over my code :wink:

My current dev branch will be units_switch, so follow that if you’d like an adventure at home.

-Matt

2 Likes

I’ve reverted the outdoor fan / compressor state sensors - they do not work for my AHU. I need to do some more logging again. Currently running mdrobnak-0.2.1.

Edit: Ran Cusror. Found these issues:

-^-^-^-

1. State machine recovery on bad response

On incorrect message length, controlState is now set to STATE_SEND_C0 so the state machine can recover on the next poll.

2. Action OFF vs IDLE when mode is OFF

  • When mode is OFF, action is set to CLIMATE_ACTION_OFF instead of CLIMATE_ACTION_IDLE.

  • When mode is updated to OFF, action is set to OFF in the same block.

  • The else if branch for mode OFF now sets CLIMATE_ACTION_OFF instead of CLIMATE_ACTION_IDLE.

3. C4 response publish_state

Added if (need_publish) this->publish_state(); before ForceReadNextCycle = 0 in the C4 handler so target temperature changes are published.

4. Action for COOL, DRY, FAN_ONLY

Using the same RXData[9] & 0x0F logic as HEAT:

  • COOL → CLIMATE_ACTION_COOLING when active

  • DRY → CLIMATE_ACTION_DRYING when active

  • FAN_ONLY → CLIMATE_ACTION_FAN when active

5. Use this->mode in C4 case

Replaced mode with this->mode in the C4 condition for clarity.

6. Defensive check for empty supported_modes_

Added a check before dereferencing supported_modes_.begin(). If it is empty, last_on_mode_ is set to CLIMATE_MODE_COOL as a fallback.

7. Single-Slot Command Queue (Design Limitation)

Location: air_conditioner.cpp lines 62-66, 93-97, 455-459

queuedCommand holds only one value. If control() or setPowerState() queues C3, and then do_follow_me() or set_static_pressure() queues C6 before the first completes, the earlier command is overwritten. The last queued command wins. This is a design limitation rather than a bug, but rapid successive controls can cause commands to be dropped.

No new linter issues were reported. The single-slot command queue (item 7) was left as a design limitation and not changed.

-^-^-^-

Item #4 Is kind of a hack, as was the original implementation. Assuming if fan running = doing the thing. This is not true if you allow cold air using the dip switch…

Testing these changes now in units_switch.
-Matt

I’m fine with an adventure. When my RS485 adapter arrives in a fortnight or so I’ll be on it.

Haha I used alot of AI in GitHub - splitice/magiqtouch-modbus-esp32: ESP32 Interface for Seeley MagiqTouch Modbus and it works incredibly well. Although no AI was gettingon a ladder to check the actual result.

Hopefully the Midea MDV-V230WN1(AU) is close enough to your unit that I can work from that. Its so much quicker to work from a good base than to start from scratch.

Hmm. I’m having trouble setting values now…Debugging here…

-Matt

See above.

Move to 0.1.1, 0.2.1, or 0.3.0.

As noted by @rymo and Cursor, my queue design has flaws lol. Fix for the temperature not setting on the first go was fixed for delays / delays_updated branches. Going back to the dev stuff to see how to get this working sanely.

-Matt

@rymo are you still using this method to control your compressor speed? Any way you can share some more details on this?

Changed the “heat/heating” logic to use difference between current_temp and T2A sensor value.

Should turn to idle / fan during compressor off…

Will report back after overnight.

EDIT: Tag mdrobnak-0.3.0 looks good overall. Does not currently account for defrost cycles. But otherwise is much more accurate than before :wink:

-Matt

Don’t have time to explain right now, but here is my implementation:

1 Like

@mdrobnak

Can you give any pointers,for a newbie to this setup.
I have your ‘units_switch’ branch working,all appears to be correct other than the ‘current’ setting. It is always showing 255 a

Also,made some mods with ChatGPT and have the defrost binary sensor working as well.
Thank you, for your efforts.

Current se

Current sensor does not work on my system either. Only some units.

1 Like

Thats pretty cool, the pv specifics could probably be abstracted into a pressure input that would make it more abstracted from your specific setup.

I like the control logic though.

I might rip out the PV stuff anyway as I’ve now got a battery, so my new goal isn’t as simple as tracking PV exports.

I tried using EMHASS with a thermal model for each zone, but for me the solar heat gain is equally significant as the difference between inside and outside ambient temperature so I’ve put that back on the shelf for now.

My system is fully kitted out for BTU/h, power and COP telemetry, with temperature probes on both the return and supply plenum, and CT clamp measuring ODU power.

One interesting finding I stumbled on was that T2A (inside coil inlet temp) tracks the actual supply temperature surprisingly well on my system.

If that’s the case on other systems as well, one could easily add an estimated BTU/h sensor to any one of these Midea-xye branches, where return temp could be approximated as T0, and supply temp is T2A. As for CFM, this will change based on user’s AHU size, but that’s all published in submittal sheets, and fan speeds map to known CFM values. If anyone is interested, I might do a PR to @mdrobnak 's repo

1 Like

Anyone know what protocol is the “TestPort” that is in Midea outdoor units? The Dr Smart tool connects to it labeling it as a “5V interface” and get’s a lot of diagnostic info, and I wonder if it’s also XYE or something else.