Skip to content

[heatpumpir] Fix fan speeds for mitsubishi_msc protocol - #20460

Merged
Jonathan Swoboda (swoboda1337) merged 1 commit into
esphome:devfrom
r3wretrhy:fix/heatpumpir-mitsubishi-msc-fan-speeds
Oct 10, 2026
Merged

Jonathan Swoboda (swoboda1337) merged 1 commit into
esphome:devfrom
r3wretrhy:fix/heatpumpir-mitsubishi-msc-fan-speeds

Conversation

@r3wretrhy

Copy link
Copy Markdown
Contributor

What does this implement/fix?

With protocol: mitsubishi_msc, the fan modes from Home Assistant send the wrong speed: Low sends Medium, Medium sends High, and High falls back to Auto.

transmit_state() maps Low/Medium/High to FAN_2/FAN_3/FAN_4 for every protocol. MitsubishiMSCHeatpumpIR::send() in HeatpumpIR 1.0.42 only has cases for FAN_AUTO and FAN_1..FAN_3 (frame values 0x02/0x03/0x05), so everything is shifted up by one and FAN_4 hits no case and stays at the Auto default. This change uses FAN_1..FAN_3 for that protocol only; every other protocol keeps the current mapping.

Tested on the host: I compiled the fan switch from heatpumpir.cpp together with the real MitsubishiMSCHeatpumpIR.cpp / HeatpumpIR.cpp / IRSender.cpp from HeatpumpIR 1.0.42 and decoded the fan bits of the sent frame. On dev, Low/Medium/High give 0x03/0x05/0x00; with this change they give 0x02/0x03/0x05, which are the values from the reporter's remote capture. Other protocols still get FAN_2/FAN_3/FAN_4. I also built the component test with script/test_build_components.py -c heatpumpir -t esp32-ard, which passes. I don't have this unit, so it's not tested on hardware.

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • New developer-facing feature (adds functionality for component developers; no end-user configuration change)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected) — policy
  • Developer breaking change (an API change that could break external components) — policy
  • Undocumented C++ API change (removal or change of undocumented public methods that lambda users may depend on) — policy
  • Code quality improvements to existing code or addition of tests
  • Other

Related issue or feature (if applicable):

Pull request in esphome.io with documentation (if applicable):

  • N/A

Pull request in developers.esphome.io with developer documentation (if applicable):

  • N/A

Test Environment

  • ESP32
  • ESP32 IDF
  • ESP8266
  • RP2040/RP2350
  • BK72xx
  • RTL87xx
  • LN882x
  • nRF52840

Example entry for config.yaml:

# Example config.yaml
climate:
  - platform: heatpumpir
    name: "Mitsubishi AC"
    protocol: mitsubishi_msc
    min_temperature: 17
    max_temperature: 30
    horizontal_default: auto
    vertical_default: auto
    transmitter_id: ir_transmitter

Checklist:

  • The code change is tested and works locally.
  • Tests have been added to verify that the new code works (under tests/ folder).

If user exposed functionality or configuration variables are added/changed:

MitsubishiMSCHeatpumpIR only handles FAN_AUTO and FAN_1..FAN_3, so the
FAN_2/FAN_3/FAN_4 mapping used for other protocols made Low send Medium,
Medium send High and High fall back to Auto. Use FAN_1..FAN_3 for this
protocol.

Fixes #20429
@esphome

esphome Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

To use the changes from this PR as an external component, add the following to your ESPHome configuration YAML file:

external_components:
  - source: github://pr#20460
    components: [heatpumpir]
    refresh: 1h

(Added by the PR bot)

@esphome

esphome Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

👋 Hi there! This PR modifies 1 file(s) with codeowners.

Rob Deutsch (@rob-deutsch) - As codeowner(s) of the affected files, your review would be appreciated! 🙏

Note: Automatic review request may have failed, but you're still welcome to review.

@codecov

codecov Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.24%. Comparing base (a4a0904) to head (69eeb51).
⚠️ Report is 1 commits behind head on dev.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##              dev   #20460   +/-   ##
=======================================
  Coverage   93.24%   93.24%           
=======================================
  Files          90       90           
  Lines       19643    19643           
  Branches     3026     3026           
=======================================
  Hits        18316    18316           
  Misses       1024     1024           
  Partials      303      303           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Memory Impact Analysis

Components: heatpumpir
Platform: esp8266-ard

Metric Target Branch This PR Change
RAM 30,304 bytes 30,304 bytes ➡️ +0 bytes (0.00%)
Flash 319,191 bytes 319,223 bytes 📈 🔸 +32 bytes (+0.01%)
📊 Component Memory Breakdown
Component Target Flash PR Flash Change
[esphome]heatpumpir 3,948 bytes 3,973 bytes 📈 🔸 +25 bytes (+0.63%)
🔍 Symbol-Level Changes (click to expand)

Changed Symbols

Symbol Target Size PR Size Change
esphome::heatpumpir::HeatpumpIRClimate::transmit_state() 468 bytes 493 bytes 📈 +25 bytes (+5.34%)

Note: This analysis measures static RAM and Flash usage only (compile-time allocation).
Dynamic memory (heap) cannot be measured automatically.
⚠️ You must test this PR on a real device to measure free heap and ensure no runtime memory issues.

This analysis runs automatically when components change. Memory usage is measured from a representative test configuration.

@swoboda1337

Copy link
Copy Markdown
Member

ESPHome Bot (@esphbot) review

@esphbot

Copy link
Copy Markdown
Contributor

PR Review — [heatpumpir] Fix fan speeds for mitsubishi_msc protocol

Merge-ready. This is a small, well-scoped fix for the mitsubishi_msc fan-speed offset, and other protocols keep their current behavior.

What the PR does well:

  • The fix is limited to PROTOCOL_MITSUBISHI_MSC (heatpumpir.cpp:192), so every other protocol still gets FAN_2/FAN_3/FAN_4.
  • Auto still maps to FAN_AUTO.
  • The two-line comment explains why this protocol is different, so a later reader won't "normalize" it back.
  • The description includes a host-side differential test against the real HeatpumpIR 1.0.42 sources. It decodes the actual frame values (dev gives 0x03/0x05/0x00; this PR gives 0x02/0x03/0x05, matching the reporter's remote capture). That is solid evidence for a library-mapping bug.
  • The cost is small: +25 B flash in transmit_state() on esp8266 and no RAM change, per the memory-impact report.

Notes (non-blocking, no findings filed):

  • I could not check the claim about the MitsubishiMSCHeatpumpIR::send() switch myself, because the HeatpumpIR library source is not in this checkout. I am relying on the author's host test for it.
  • Nobody has tested this on real hardware, as the author says. Users who had worked around the old offset (for example, picking High to get Medium) will see a behavior change. That is the intended fix and is not a breaking change.
  • If more protocols turn out to use a 3-speed FAN_1..FAN_3 layout, a small per-protocol fan-offset table would scale better than adding more booleans to this switch. That isn't needed for a single protocol.


Checklist

  • Correctness of fan-speed mapping for the targeted protocol
  • No behavior change for other protocols
  • No hardcoded secrets / security concerns
  • Follows repo C++ conventions (this->, naming, comments)
  • PR description matches diff

Automated review by Kōan (Claude) HEAD=69eeb51 33s

@esphbot ESPHome Bot (esphbot) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tip

No blocking issues found — ready to merge.

@bdraco J. Nick Koston (bdraco) added this to the 2026.10.0 milestone Oct 10, 2026
@swoboda1337
Jonathan Swoboda (swoboda1337) merged commit 6b03d68 into esphome:dev Oct 10, 2026
52 checks passed
@jaylyon

Copy link
Copy Markdown

Confirmed on real hardware! I reported the original issue (#20429) and tested this on the same unit, a Mitsubishi MS09TW on an ESP32-S3, with the fan set from Home Assistant, and it works perfectly. Thanks for the quick fix!

@github-actions github-actions Bot locked and limited conversation to collaborators Oct 12, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[heatpumpir] mitsubishi_msc fan speeds are shifted (Low sends Medium, Medium sends High, High falls back to Auto)

6 participants