echavet/MitsubishiCN105ESPHome

GitHub: echavet/MitsubishiCN105ESPHome

基于 ESPHome 框架的三菱空调 CN105 接口自定义固件,实现完全本地化的空调控制与 Home Assistant 集成。

Stars: 967 | Forks: 171

# Mitsubishi CN105 ESPHome This project is a firmware for ESP32 microcontrollers supporting UART communication via the CN105 Mitsubishi connector. Its purpose is to enable complete control of a compatible Mitsubishi heat pump through Home Assistant, a web interface, or any MQTT client. It uses the ESPHome framework and is compatible with the Arduino framework and ESP-IDF. This component version is an adaptation of [geoffdavis's esphome-mitsubishiheatpump](https://github.com/geoffdavis/esphome-mitsubishiheatpump). Its purpose is to integrate the Mitsubishi heat pump protocol (enabled by the [SwiCago library](https://github.com/SwiCago/HeatPump)) directly into the ESPHome component classes for a more seamless integration. The intended use case is for owners of a Mitsubishi Electric heat pump or air conditioner that includes a CN105 communication port to directly control their air handler or indoor unit using local communication through a web browser, or most commonly, the [HomeAssistant](https://www.home-assistant.io/) home automation platform. Installation requires the use of a WiFi capable ESP32 or ESP8266 device, modified to include a 5 pin plug to connect to the heat pump indoor unit. ESPHome is used to load the custom firmware onto the device, and the web browser or HomeAssistant software is used to send temperature setpoints, external temperature references, and settings to the heat pump. Installation requires basic soldering skills, and basic skills in flashing a firmware to a microcontroller (though ESPHome makes this as painless as possible). The benefits include fully local control over your heat pump system, without reliance on a vendor network. Additional visibility, finer control, and even improved energy efficiency and comfort are possible when utilizing the remote temperature features. ### New Features - Support Fahrenheit users better by mapping unit conversions to Mitsubishi's "creative" math, ensuring that HomeAssistant and external thermostats stay in sync. Thanks [@ams2990](https://github.com/ams2990) and [@dsstewa](https://github.com/dsstewa)! - Additional components for supported units: vane orientation (fully supporting the Swicago map), compressor frequency for energy monitoring, and i-see sensor. - Additional diagnostic sensors for understanding the behavior of the indoor units while in AUTO mode. - Additional sensors for power usage and outdoor temperature (not supported by all units). - Code is divided into distinct concerns for better readability. - Extensive logging for easier troubleshooting and development. - Ongoing refactoring to further improve the code quality. - Enhanced UART communication with the Heatpump to eliminate delays in the ESPHome loop(), which was a limitation of the original [SwiCago library](https://github.com/SwiCago/HeatPump). - Byte-by-byte reading within the loop() function ensures no data loss or lag, as the component continuously reads without blocking ESPHome. - UART writes are followed by non-blocking reads. The responses are accumulated byte-by-byte in the loop() method and processed when complete, allowing command stacking without delays for a more responsive UI. ### Retained Features This project maintains all functionalities of the original [geoffdavis](https://github.com/geoffdavis/esphome-mitsubishiheatpump) project, including: - Wireless Mitsubishi Comfort HVAC equipment control via ESP8266 or ESP32, using the [ESPHome](https://esphome.io) framework. - Instant feedback of command changes via RF Remote to HomeAssistant or MQTT. - Direct control independent of the remote. - A slightly modified version of the [SwiCago/HeatPump](https://github.com/SwiCago/HeatPump) Arduino library for direct communication via the internal `CN105` connector. - Full mode and vane orientation support (added as an extra component within the Core Climate Component). - Thermostat in HomeAssistant with compressor frequency monitoring (an extra component within the Core Climate Component). ## Requirements - [ESPHome](https://esphome.io/) - Minimum version 1.18.0, installed independently or as an add-on in HomeAssistant ## Supported Microcontrollers - Generic ESP32 Dev Kit (ESP32): tested - M5Stack ATOM Lite : tested - M5Stack ATOM S3 Lite: tested w/ [modifications](https://github.com/echavet/MitsubishiCN105ESPHome/discussions/83) - M5Stack NanoC6: [tested over both wifi and thread](https://github.com/echavet/MitsubishiCN105ESPHome/discussions/340) - M5Stack StampS3 - Seeed Studios Xiao ESP32S3: tested - WeMos D1 Mini Pro (ESP8266): tested (but not currently recommended, see above) ## Supported Mitsubishi Climate Units Generally, indoor units with a `CN105` header are compatible. Refer to the [HeatPump wiki](https://github.com/SwiCago/HeatPump/wiki/Supported-models) for a comprehensive list. Additionally, Mitsubishi units listed as compatible with the [Mitsubishi PAC-USWHS002-WF-2 Kumo Cloud interface](https://mylinkdrive.com/USA/Controls/kumo_cloud/kumo_cloud_Devices/PAC_USWHS002_WF_2?product) will _likely_ be compatible with this project, as they use the same CN105 connector and serial protocol. Units tested by project contributors include: - `MFZ-KA09NA` - `MLZ-KP12NA` - `MSXY-FN10VE` (https://github.com/echavet/MitsubishiCN105ESPHome/discussions/368) - 'MSXY-FN10VE R2', 'MSXY-FN13VE R2','MSXY-FN24VE R2' - `MSZ-AP20VGK`, `MSZ-AP25VGK`, `MSZ-AP35VGK`, `MSZ-AP42VGK`, `MSZ-AP50VGK` - `MSZ-AP35VGD2` (https://github.com/echavet/MitsubishiCN105ESPHome/discussions/254) - `MSZ-AY` series (e.g. `MSZ-AY20`, `MSZ-AY25`, `MSZ-AY35`, `MSZ-AY42`, `MSZ-AY50`) - `MSZ-EF` series (e.g. `MSZ-EF09NA`, `MSZ-EF15NA`, `MSZ-EF42VE`, `MSZ-EF50VE`) - `MSZ-FHxxNA` - `MSZ-FSxxNA` - `MSZ-FT50VG2` - `MSZ-GE24NA` - `MSZ-GL` series (e.g. `MSZ-GL06NA`, `MSZ-GL09NA`, `MSZ-GL12NA`, `MSZ-GL15NA`, `MSZ-GL18NA`, `MSZ-GL24NA`) - `MSZ-GS12NA` - `MSZ-HR` series (e.g. `MSZ-HR25VF`, `MSZ-HR35VF`, `MSZ-HR45VF`, `MSZ-HR50VF`) - `MSZ-LN35VGW` - `MSZ-SF35VE3`, `MSZ-SF50VE3` - `PEFY-P32VMA-E2` - `SEZ-KD25VAQ` - `SEZ-M50DAL` ## Usage ### Step 1: Building the Control Circuit Follow the [SwiCago/HeatPump README](https://github.com/SwiCago/HeatPump/blob/master/README.md#demo-circuit) for building a control circuit using either an ESP8266 or ESP32. ### Step 2: Using ESPHome Add a new device in your ESPHome dashboard. Create a yaml configuration file for the new device using the templates below, and flash to your device. Refer to the ESPHome documentation for guides on how to install ESPHome, add new devices, and flash the initial firmware. - [Getting Started with ESPHome and HomeAssistant](https://esphome.io/guides/getting_started_hassio) - [Installing ESPHome Locally](https://esphome.io/guides/installing_esphome) ### Step 3: Configure the board and UART settings Your ESPHome device configuration file starts with common defaults for ESPHome. To these defaults, add these minimum sections: #### For ESP32-based Devices esp32: board: esp32doit-devkit-v1 #or esp32-s3-devkitc-1 framework: type: esp-idf uart: id: HP_UART baud_rate: 2400 tx_pin: GPIO17 rx_pin: GPIO16 #### For ESP8266-based Devices esp8266: board: d1_mini uart: id: HP_UART baud_rate: 2400 tx_pin: 1 rx_pin: 3 ### Step 4: Configure the climate component Add these sections to load the external component, setup logging, and enable the climate entity. # External component reference external_components: - source: github://echavet/MitsubishiCN105ESPHome # Climate entity configuration climate: - platform: cn105 id: hp name: "My Heat Pump" update_interval: 2s # update interval can be adjusted after a first run and logs monitoring # Default logging level logger: # hardware_uart: UART1 # Uncomment on ESP8266 devices level: INFO #### Adjusting the `update_interval` An ESPHome firmware implements the esphome::Component interface to be integrated into the Inversion Of Control mechanism of the ESPHome framework. The main method of this process is the `loop()` method. MitsubishiCN105ESPHome performs a series of exchanges with the heat pump through a cycle. This cycle is timed, and its duration is displayed in the logs, provided the `CYCLE` logger is set to at least `INFO`. If this is the case, you will see logs in the form: [09:48:36][I][CYCLE:052]: 6: Cycle ended in 1.2 seconds (with timeout?: NO) This will give you a good idea of your microcontroller's performance in completing an entire cycle. It is unnecessary to set the `update_interval` below this value. In this example, setting an `update_interval` to 1500ms could be a fine tuned value. ### Step 5: Optional components and variables These optional additional configurations add customization and additional capabilities. The examples below assume you have added a substitutions component to your configuration file to allow for easy renaming, and that you have added a `secrets.yaml` file to your ESPHome configuration to hide private variables like your random API keys, OTA passwords, and Wifi passwords. substitutions: name: heatpump-1 # Do not use underscores, which are not fully compatible with mDNS friendly_name: My Heatpump 1 #### Climate component full example This example adds support for configuring the temperature steps, adding an icon, and the optional climate sensors supported by SwiCago (but not supported by all indoor units), `compressor_frequency_sensor`, `vertical_vane_select`, `horizontal_vane_select` and `isee_sensor`. Supports many of the other features of the [ESPHome climate component](https://esphome.io/components/climate/index.html) as well for additional customization. The `remote_temperature_timeout` setting allows the unit to revert back to the internal temperature measurement if it does not receive an update in the specified time range (highly recommended if using remote temperature updates). `remote_temperature_keepalive_interval` configures the automatic keep-alive that periodically re-sends the external temperature to the heat pump (similar to Kumo Cloud behavior). Default is `20s`. Set to `0s` to disable. See [Methods for updating external temperature](#methods-for-updating-external-temperature) for details. `debounce_delay` adds a small delay to the command processing to account for some HomeAssistant buttons that may send repeat commands too quickly. A shorter value creates a more responsive UI, a longer value protects against repeat commands. (See https://github.com/echavet/MitsubishiCN105ESPHome/issues/21) `connection_bootstrap_delay` delays the initial CN105 UART connection sequence (UART init + CONNECT handshake) **after boot**, to ensure the OTA log stream has time to attach. This is useful when troubleshooting cold-boot issues remotely: without a delay, the very first connection logs can be missed because the log client connects a few seconds after reboot. While this delay is active, the component will **not start communication cycles** until the heatpump replies with the connection success packet. Recommended: start with `10s` and increase (e.g., `30s`) if you still miss early logs. A safety fallback starts anyway after 120s. `installer_mode` enables an extended CN105 connection handshake (CONNECT command `0x5B`) instead of the standard handshake (`0x5A`). Some indoor units (notably some ducted SEZ variants) may require this to unlock installer/service privileges so that Function Settings (ISU / `hardware_settings`) return real values instead of `0`. Default is `false` for maximum compatibility. `fahrenheit_compatibility` improves compatibility with HomeAssistant installations using Fahrenheit units. Mitsubishi uses a custom lookup table to convert F to C which doesn't correspond to the actual math in all cases. This can result in external thermostats and HomeAssistant "disagreeing" on what the current setpoint is. Setting this value to `standard` (or `alt` for alternative conversion tables) forces the component to use the same lookup tables, resulting in more consistent display of setpoints. Recommended for Fahrenheit users. (See https://github.com/echavet/MitsubishiCN105ESPHome/pull/298.) `use_as_operating_fallback` in the `stage_sensor` enables a fallback mechanism for the activity indicator (idle/heating/cooling/etc.). By default, the activity status is based on the compressor running state. When this option is enabled, the system uses an OR logic: it shows active status if the compressor is running OR if the stage sensor indicates activity (not IDLE). This is particularly useful for 2-stage heating systems where the second stage (e.g., gas heating) may be active while the compressor is off. (See https://github.com/echavet/MitsubishiCN105ESPHome/issues/277 and https://github.com/echavet/MitsubishiCN105ESPHome/issues/469) climate: - platform: cn105 id: hp name: "${friendly_name}" icon: mdi:heat-pump visual: min_temperature: 10 # Adjust to your unit's min temp. SmartSet units can go to 10C for heating max_temperature: 31 temperature_step: target_temperature: 1 current_temperature: 0.5 # Fahrenheit compatibility mode - uses Mitsubishi's "custom" unit conversions, set to # "standard" (or "alt") for better support of Fahrenheit units in HomeAssistant. # Options: "disabled" (default), "standard", "alt" fahrenheit_compatibility: "disabled" # Timeout and communication settings remote_temperature_timeout: 30min remote_temperature_keepalive_interval: 20s # Auto re-send external temp (like Kumo) update_interval: 2s debounce_delay: 100ms # Delay the initial UART/CONNECT bootstrap to avoid missing early OTA logs connection_bootstrap_delay: 30s # Optional: use extended CONNECT handshake (0x5B) for installer/service privileges installer_mode: false # Various optional sensors, not all sensors are supported by all heatpumps compressor_frequency_sensor: name: Compressor Frequency entity_category: diagnostic disabled_by_default: true outside_air_temperature_sensor: name: Outside Air Temp disabled_by_default: true vertical_vane_select: name: Vertical Vane disabled_by_default: false horizontal_vane_select: name: Horizontal Vane disabled_by_default: true isee_sensor: name: ISEE Sensor disabled_by_default: true stage_sensor: name: Stage # use_as_operating_fallback: false # set to true for 2-stage systems or if activity indicator is unreliable entity_category: diagnostic disabled_by_default: true sub_mode_sensor: name: Sub Mode entity_category: diagnostic disabled_by_default: true auto_sub_mode_sensor: name: Auto Sub Mode entity_category: diagnostic disabled_by_default: true input_power_sensor: name: Input Power disabled_by_default: true kwh_sensor: name: Energy Usage disabled_by_default: true runtime_hours_sensor: name: Runtime Hours entity_category: diagnostic disabled_by_default: true air_purifier_switch: name: Air purifier disabled_by_default: true night_mode_switch: name: Night mode disabled_by_default: true circulator_switch: name: Circulator disabled_by_default: true airflow_control_select: name: Airflow Control disabled_by_default: true supports: # Explicitly control dual setpoint support in the UI/traits # Defaults to false when omitted dual_setpoint: true # You can still specify supported modes as before mode: [AUTO, COOL, HEAT, DRY, FAN_ONLY] fan_mode: [AUTO, QUIET, LOW, MEDIUM, HIGH] swing_mode: ["OFF", VERTICAL] # Specify which options to display in horizontal_vane_select dropdown # Defaults to all options: ["←←", "←", "|", "→", "→→", "←→", "SWING", "AIRFLOW CONTROL"] # Example to hide "←→" and "AIRFLOW CONTROL" if not supported by your unit: horizontal_vane_mode: ["←←", "←", "|", "→", "→→", SWING] #### Logger granularity This firmware supports detailed log granularity for troubleshooting. Below is the full list of logger components and recommended defaults. logger: # hardware_uart: UART1 # Uncomment on ESP8266 devices level: INFO logs: EVT_SETS: INFO WIFI: INFO MQTT: INFO WRITE_SETTINGS: INFO SETTINGS: INFO STATUS: INFO # CN105 connection/bootstrap diagnostics (UART init + CONNECT handshake) CN105_CONN: INFO CN105Climate: WARN CN105: INFO climate: WARN sensor: WARN chkSum: INFO WRITE: WARN READ: WARN Header: INFO Decoder: INFO CONTROL_WANTED_SETTINGS: INFO # Swap the above settings with these debug settings for development or troubleshooting # level: DEBUG # logs: # EVT_SETS : DEBUG # WIFI : INFO # MQTT : INFO # WRITE_SETTINGS : DEBUG # SETTINGS : DEBUG # STATUS : INFO # CN105Climate: WARN # CN105: DEBUG # climate: WARN # sensor: WARN # chkSum : INFO # WRITE : WARN # READ : WARN # Header: INFO # Decoder : DEBUG # CONTROL_WANTED_SETTINGS: DEBUG ### Step 6: Build the project and install Build the project in ESPHome and install to your device. Install the device in your indoor unit connected to the CN105 port, and confirm that it powers up and connects to the Wifi. Visit the local IP address of the device, and confirm that you can change modes and temperature setpoints. HomeAssistant should now include a climate entity for your heatpump. ### Step 7: (Optional) Install Mitsubishi Climate Proxy via HACS This repository also contains a Home Assistant Custom Component that solves the "Auto vs Heat/Cool" UI issue by wrapping your ESPHome entity. It enables a dynamic UI that shows a single temperature slider for HEAT/COOL/AUTO modes and dual sliders only for HEAT_COOL mode. 1. Open **HACS** > **Integrations**. 2. Click the three dots in the top right > **Custom repositories**. 3. Add `echavet/MitsubishiCN105ESPHome` as category **Integration**. 4. Adding the repository will allow you to find "Mitsubishi Climate Proxy" in the list. 5. Install **Mitsubishi Climate Proxy** and restart Home Assistant. #### Configuration (UI Method - Recommended) 1. Navigate to **Settings** > **Devices & Services**. 2. Click the **+ ADD INTEGRATION** button at the bottom right. 3. Search for **Mitsubishi Climate Proxy**. 4. Follow the on-screen instructions: - Select the source ESPHome entity (e.g., `climate.living_room_esphome`). - Give your new proxy entity a name (e.g., `Living Room Climate`). 5. Click **Submit**. Your new entity (e.g., `climate.living_room_climate`) is created immediately and can be used in your dashboard. #### Configuration (YAML Method - Legacy) If you prefer configuration via YAML, add this to your `configuration.yaml`: climate: - platform: mitsubishi_climate_proxy source_entity: climate.my_esphome_entity # Replace with your actual ESPHome entity ID name: "Bedroom Hybrid" # Name for the new wrapper entity ## Example Configuration - Minimal This minimal configuration includes the basic components necessary for the firmware to operate. Note that you need to choose between the ESP32 and the ESP8266 sections to get the correct UART configuration. Utilizes a `secrets.yaml` file to store your credentials.
Minimal Configuration esphome: name: heatpump-1 friendly_name: My Heatpump 1 # For ESP8266 Devices #esp8266: # board: d1_mini #uart: # id: HP_UART # baud_rate: 2400 # tx_pin: 1 # rx_pin: 3 # For ESP32 Devices esp32: board: esp32doit-devkit-v1 framework: type: esp-idf uart: id: HP_UART baud_rate: 2400 tx_pin: GPIO17 rx_pin: GPIO16 external_components: - source: github://echavet/MitsubishiCN105ESPHome # Climate entity configuration climate: - platform: cn105 name: "My Heat Pump" update_interval: 2s # Default logging level logger: # hardware_uart: UART1 # Uncomment on ESP8266 devices level: INFO # Enable Home Assistant API api: encryption: key: !secret api_key ota: platform: esphome # Required for ESPhome 2024.6.0 and greater 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: "Heatpump Fallback Hotspot" password: !secret fallback_password captive_portal:
## Example Configuration - Complete This example includes all the bells and whistles, optional components, remote temperature sensing, reboot button, and additional sensors in HomeAssistant including uptime, the current wifi SSID, and signal strength. Note that you need to choose between the ESP32 and the ESP8266 sections to get the correct UART configuration. Utilizes a `secrets.yaml` file to store your credentials. Comment out or remote features your unit doesn't support (such as the isee sensor or horizontal vane). It doesn't hurt to try them, but if your unit doesn't support that feature then it will be inactive.
Complete Configuration substitutions: name: heatpump-1 friendly_name: My Heatpump 1 remote_temp_sensor: sensor.my_room_temperature # Homeassistant sensor providing remote temperature esphome: name: ${name} friendly_name: ${friendly_name} # For ESP8266 Devices #esp8266: # board: d1_mini # #uart: # id: HP_UART # baud_rate: 2400 # tx_pin: 1 # rx_pin: 3 # For ESP32 Devices esp32: board: esp32doit-devkit-v1 framework: type: esp-idf uart: id: HP_UART baud_rate: 2400 tx_pin: GPIO17 rx_pin: GPIO16 external_components: - source: github://echavet/MitsubishiCN105ESPHome # refresh: 0s wifi: ssid: !secret ssid password: !secret password domain: !secret domain # Enable fallback hotspot (captive portal) in case wifi connection fails ap: ssid: "${friendly_name} ESP" password: !secret fallback_password captive_portal: # Enable logging logger: # hardware_uart: UART1 # Uncomment on ESP8266 devices level: INFO logs: EVT_SETS: INFO WIFI: INFO MQTT: INFO WRITE_SETTINGS: INFO SETTINGS: INFO STATUS: INFO CN105Climate: WARN CN105: INFO climate: WARN sensor: WARN chkSum: INFO WRITE: WARN READ: WARN Header: INFO Decoder: INFO CONTROL_WANTED_SETTINGS: INFO # level: DEBUG # logs: # EVT_SETS : DEBUG # WIFI : INFO # MQTT : INFO # WRITE_SETTINGS : DEBUG # SETTINGS : DEBUG # STATUS : INFO # CN105Climate: WARN # CN105: DEBUG # climate: WARN # sensor: WARN # chkSum : INFO # WRITE : WARN # READ : WARN # Header: INFO # Decoder : DEBUG # CONTROL_WANTED_SETTINGS: DEBUG # Enable Home Assistant API api: encryption: key: !secret api_key sensor: # Uptime sensor. - platform: uptime name: Uptime # WiFi Signal sensor. - platform: wifi_signal name: WiFi Signal update_interval: 120s - platform: homeassistant name: "Remote Temperature Sensor" entity_id: ${remote_temp_sensor} # Replace with your HomeAssistant remote sensor entity id, or include in substitutions internal: false disabled_by_default: true device_class: temperature state_class: measurement unit_of_measurement: "°C" filters: # Uncomment the lambda line to convert F to C on incoming temperature # - lambda: return (x - 32) * (5.0/9.0); - clamp: # Limits values to range accepted by Mitsubishi units min_value: 1 max_value: 40 ignore_out_of_range: true - throttle: 30s on_value: then: - logger.log: level: INFO format: "Remote temperature received from HA: %.1f C" args: ["x"] - lambda: "id(hp).set_remote_temperature(x);" ota: platform: esphome # Required for ESPhome 2024.6.0 and greater # Enable Web server. web_server: port: 80 # Sync time with Home Assistant. time: - platform: homeassistant id: homeassistant_time # Text sensors with general information. text_sensor: # Expose ESPHome version as sensor. - platform: version name: ESPHome Version # Expose WiFi information as sensors. - platform: wifi_info ip_address: name: IP ssid: name: SSID bssid: name: BSSID # Create a button to restart the unit from HomeAssistant. Rarely needed, but can be handy. button: - platform: restart name: "Restart ${friendly_name}" # Creates the sensor used to receive the remote temperature from Home Assistant # Uses sensor selected in substitutions area at top of config # Customize the filters to your application: # Uncomment the first line to convert F to C when remote temps are sent # If you have a fast or noisy sensor, consider some of the other filter # options such as throttle_average. climate: - platform: cn105 id: hp name: "${friendly_name}" icon: mdi:heat-pump visual: min_temperature: 10 # Adjust to your unit's min temp. SmartSet units can go to 10C for heating max_temperature: 31 temperature_step: target_temperature: 1 current_temperature: 0.5 # Fahrenheit compatibility mode - uses Mitsubishi's "custom" unit conversions, set to # "standard" (or "alt") for better support of Fahrenheit units in HomeAssistant. # Options: "disabled" (default), "standard", "alt" fahrenheit_compatibility: "disabled" # Timeout and communication settings remote_temperature_timeout: 30min remote_temperature_keepalive_interval: 20s # Auto re-send external temp (like Kumo) update_interval: 2s debounce_delay: 100ms # Various optional sensors, not all sensors are supported by all heatpumps compressor_frequency_sensor: name: Compressor Frequency entity_category: diagnostic disabled_by_default: true outside_air_temperature_sensor: name: Outside Air Temp disabled_by_default: true vertical_vane_select: name: Vertical Vane disabled_by_default: false horizontal_vane_select: name: Horizontal Vane disabled_by_default: true isee_sensor: name: ISEE Sensor disabled_by_default: true stage_sensor: name: Stage entity_category: diagnostic disabled_by_default: true sub_mode_sensor: name: Sub Mode entity_category: diagnostic disabled_by_default: true auto_sub_mode_sensor: name: Auto Sub Mode entity_category: diagnostic disabled_by_default: true input_power_sensor: name: Input Power disabled_by_default: true kwh_sensor: name: Energy Usage disabled_by_default: true runtime_hours_sensor: name: Runtime Hours entity_category: diagnostic disabled_by_default: true
## Methods for updating external temperature There are several methods for updating the unit with an remote temperature value. This replaces the heat pump's internal temperature measurement with an external temperature measurement as the Mitsubishi wireless thermostats do, allowing you to more precisely control room comfort and improve energy efficiency by increasing cycle length. ### Automatic Keep-Alive and Configuration Options When using an external temperature sensor, the heat pump requires periodic updates to maintain the external temperature reference. Without regular updates, the unit may fall back to its internal sensor. This component includes a **built-in keep-alive mechanism** (similar to how Mitsubishi's Kumo Cloud module works) that automatically re-sends the external temperature at regular intervals. This eliminates the need for manual heartbeat automations in your YAML configuration. **Configuration options:** | Option | Default | Description | | --------------------------------------- | ------- | ------------------------------------------------------------------------------------------- | | `remote_temperature_timeout` | `never` | Time without updates before falling back to internal sensor. Recommended: `5min` to `30min` | | `remote_temperature_keepalive_interval` | `20s` | Interval for automatic re-sending of temperature to the heat pump. Set to `0s` to disable | **Example configuration:** climate: - platform: cn105 id: hp # ... other options ... remote_temperature_timeout: 5min # Fallback to internal sensor after 5 min without HA updates remote_temperature_keepalive_interval: 20s # Re-send temperature every 20s (like Kumo does) **How it works:** 1. When Home Assistant sends a temperature value via `set_remote_temperature()`, the value is sent to the heat pump immediately 2. The keep-alive timer starts automatically and re-sends the same value every 20 seconds (configurable) 3. A debounce mechanism prevents flooding the bus if you have existing automations that send updates too frequently 4. If Home Assistant stops sending updates (sensor offline, network issue), the `remote_temperature_timeout` triggers a fallback to the internal sensor ### Recommended — Native `remote_temperature_source` binding (no lambda needed) Since PR [#624](https://github.com/echavet/MitsubishiCN105ESPHome/pull/624), the component supports a **native sensor binding** that eliminates the need for lambda code. Simply declare a Home Assistant sensor and reference it directly in your climate config. The component automatically subscribes to sensor updates and forwards the temperature to the heat pump. **Step 1:** Declare the Home Assistant sensor (in your sensor section): sensor: - platform: homeassistant id: ha_remote_temp entity_id: sensor.my_room_temperature # Your HA temperature sensor internal: true # Uncomment the filter and lambda lines to convert F to C on incoming temperature # filters: # - lambda: return (x - 32) * (5.0/9.0); **Step 2:** Reference it in the climate config: climate: - platform: cn105 id: hp # ... other options ... remote_temperature_source: sensor_id: ha_remote_temp # References the sensor declared above info: # Optional: exposes a text sensor showing the source name name: "Remote Temp Source" remote_temperature_timeout: 30min remote_temperature_keepalive_interval: 20s That's it — no lambda, no `on_value` block, no manual `set_remote_temperature()` call. The component handles everything internally. ### Alternate — Lambda with a [HomeAssistant Sensor](https://esphome.io/components/sensor/homeassistant.html) through the HomeAssistant API Creates the sensor used to receive the remote temperature from Home Assistant. Uses sensor selected in substitutions area at top of config or manually entered into the sensor configuration. When the HomeAssistant sensor updates, it will send the new value to the ESP device, which will update the heatpump's remote temperature value. Customize the filters to your application: - Uncomment the first line to convert F to C when remote temps are sent. - If you have a fast or noisy sensor, consider some of the other filter options such as throttle_average. sensor: - platform: homeassistant name: "Remote Temperature Sensor" entity_id: ${remote_temp_sensor} # Replace with your HomeAssistant remote sensor entity id, or include in substitutions internal: false disabled_by_default: true device_class: temperature state_class: measurement unit_of_measurement: "°C" filters: # Uncomment the lambda line to convert F to C on incoming temperature # - lambda: return (x - 32) * (5.0/9.0); - clamp: # Limits values to range accepted by Mitsubishi units min_value: 1 max_value: 40 ignore_out_of_range: true - throttle: 30s on_value: then: - logger.log: level: INFO format: "Remote temperature received from HA: %.1f C" args: ["x"] - lambda: "id(hp).set_remote_temperature(x);" ### Alternate - Get external temperature from a networked sensor with a throttle filter sensor: - platform: pvvx_mithermometer mac_address: "A4:C1:38:XX:XX:XX" temperature: name: Thermometer id: temperature device_class: temperature state_class: measurement filters: throttle_average: 90s on_value: then: - lambda: "id(hp).set_remote_temperature(x);" ### Alternate - HomeAssistant Action This example extends to default `api:` component to add a `set_remote_temperature` action that can be called from within HomeAssistant, allowing you to send a remote temperature value to the heat pump. You will need to include an automation in HomeAssistant to periodically call the action and update the temperature with `set_remote_temperature`, or disable remote temperature with `use_internal_temperature`. No longer recommended as the default method of updating remote temperature. api: encryption: key: !secret api_key services: - service: set_remote_temperature variables: temperature: float then: # Select between the C version and the F version # Uncomment just ONE of the below lines. The top receives the temperature value in C, # the bottom receives the value in F, converting to C here. - lambda: "id(hp).set_remote_temperature(temperature);" # - lambda: 'id(hp).set_remote_temperature((temperature - 32.0) * (5.0 / 9.0));' - service: use_internal_temperature then: - lambda: "id(hp).set_remote_temperature(0);" ## Diagnostic Sensors ### Outside Air Temperature This sensor reads the outdoor unit's air temperature reading, in 1.0 degree C increments. Not all outdoor units support this sensor. Some outdoor units will send an accurate value while the unit is operating, or in heat/cool mode, but will send -63.5C when offline. outside_air_temperature_sensor: name: Outside Air Temperature Compatible units (as reported by users): | Indoor | Outdoor | Temperature | | -------------- | ---------------- | ---------------------------------- | | MSZ-AP25VGD | MXZ-4F80VGD | Works | | MSZ-AP35VGD | MUZ-AP35VG | Works but reports -63.5C when idle | | MSZ-AP60VGD | MUZ-AP60VG | Works | | MSZ-AP71VGD | MUZ-AP71VG | Works but reports -63.5C when idle | | MSZ-AY35VGKP | MUZ-AY35VG | Works | | MSZ-GLxxNA | MXZ-SM42NAMHZ | Works | | | MXZ-3C24NA2 | Not working | | MSZ-RW25VG-SC1 | MUZ-RW25VGHZ-SC1 | Works | | MSZ-FSxxNA | MXZ-4C36NA2 | Works | | | MUZ-FD25NA | Not working | | MSZ-LN35 | MUZ-LN35 | Not working | | MSZ-LN50 | MXZ-2F53VFHZ | Works | | MSZ-KT25 | MXZ-2F53VFHZ | Works | | MSZ-LNxx | MXZ-4F83VFHZ | Works | | MSZ-AP20VGK | MXZ-4F83VF | Works | | MSZ-FT50VG2 | MUZ-FT50VG | Works | ### Auto and Stage Sensors The below sensors were added recently based on the work of others in sorting out other messages and bytes. The names are likely to change as we work to determine exactly what the units are doing. stage_sensor: name: Stage Sensor sub_mode_sensor: name: Sub Mode Sensor auto_sub_mode_sensor: name: Auto Sub Mode Sensor - `stage_sensor` is the actual fan speed of the indoor unit. This is called stage in some documentation. Reported speeds include `IDLE`, `LOW`, `GENTLE`, `MEDIUM`, `MODERATE`, `HIGH` and `DIFFUSE`, named using Mitsubishi documentation conventions. - `auto_sub_mode_sensor` indicates what actual mode the unit is in when in AUTO. Modes are `AUTO_OFF`, meaning AUTO is disabled, `AUTO_COOL`, meaning AUTO and cooling, `AUTO_HEAT`, meaning AUTO and heating and `AUTO_LEADER`, meaning this unit is the leader in a multi-head unit and selects the heat/cool mode that the others follow. - `sub_mode_sensor` indicates additional detail on the current behavior of the unit. The Sub Modes are: - `NORMAL` - the unit is in an active mode (heat, cool, dry, etc.) and is either running, or waiting to run - `PREHEAT` - a cold-climate feature that electrically preheats the compressor windings prior to start of operation - `DEFROST` - a cold climate behavior that runs a short AC cycle during heating mode to melt ice from the coils - `STANDBY` - unit is off, or has been put into a "sleep" state through AUTO operation on another indoor unit Some examples of how these all fit together: Unit 1 is in AUTO set to 20C and Unit 2 is in AUTO and set to 20C. Unit 1 senses that the room is 24C and tries to enter `AUTO_COOL`. If Unit 2 wants to heat the room it is in, it will enter `STANDBY` (and in the case of a few units tested, this mean it will go to "sleep" as if it is off, but not really be off) making Unit 1 enter `AUTO_LEADER` sub mode. In future releases, it is planned to make the ACTION in HA match these modes. But at this time this is not implemented. It is also important to note that the Kumo adapter has many more settings that impact the behaviour above (such as thermal fan behaviour) and if you have set these the exact actions the untis take in these modes/submodes/stages is determined by those. Some of these can also be set by remotes and other devices. The setup you have will dictate the exact actions you see. If you have permutations, please share! ### UART Diagnostic Sensors The following ESPHome sensors will not be needed by most users, but can be helpful in diagnosting problems with UART connectivity. Only implement if you are currently troubleshooting or developing new functionality. sensor: - platform: template name: "dg_uart_connected" entity_category: DIAGNOSTIC lambda: |- return (bool) id(hp).isUARTReady_(); update_interval: 30s - platform: template name: "dg_complete_cycles" entity_category: DIAGNOSTIC accuracy_decimals: 0 lambda: |- return (unsigned long) id(hp).nbCompleteCycles_; update_interval: 60s - platform: template name: "dg_total_cycles" accuracy_decimals: 0 entity_category: DIAGNOSTIC lambda: |- return (unsigned long) id(hp).nbCycles_; update_interval: 60s - platform: template name: "dg_nb_hp_connections" accuracy_decimals: 0 entity_category: DIAGNOSTIC lambda: |- return (unsigned int) id(hp).nbHeatpumpConnections_; update_interval: 60s - platform: template name: "dg_complete_cycles_percent" unit_of_measurement: "%" accuracy_decimals: 1 entity_category: DIAGNOSTIC lambda: |- unsigned long nbCompleteCycles = id(hp).nbCompleteCycles_; unsigned long nbCycles = id(hp).nbCycles_; if (nbCycles == 0) { return 0.0; } return (float) nbCompleteCycles / nbCycles * 100.0; update_interval: 60s ## Hardware Settings (Function Settings) This advanced feature allows you to read and modify the internal "Function Settings" (ISU) of your Mitsubishi unit directly from Home Assistant. These settings control hardware behaviors like auto-restart, temperature sensing location, or static pressure. ### Reference Documentation These Mitsubishi resources document the function setting codes for various equipment: - [Function Settings List (PDF)](https://www.mitsubishitechinfo.ca/sites/default/files/Function%20Settings%20List.pdf) - covers a wide range of Mitsubishi equipment models - [MHK2 Installation Manual (PDF)](https://mylinkdrive.com/viewPdf?srcUrl=http://s3.amazonaws.com/enter.mehvac.com/DAMRoot/Original/10007%5CMHK2_Installation_Manual_2025_Update.pdf) - detailed function code reference - [MyLinkDrive](https://www.mylinkdrive.com/usa) - Mitsubishi's portal for additional reference materials and documentation ### Configuration Add the `hardware_settings` block to your configuration. You can choose which codes to expose and customize the labels. climate: - platform: cn105 # ... your existing config ... # Configure the update interval for reading settings (default: 24h) # These settings rarely change, so a long interval is recommended. hardware_settings: update_interval: 20s list: # Code 101: Auto Restart - code: 101 name: "Auto Restart after Power Failure" icon: "mdi:restart" options: 1: "ON (Default)" 2: "OFF" # Code 102: Temperature Sensing Source # Important for remote temperature control! - code: 102 name: "Temperature Source" icon: "mdi:thermometer-check" options: 1: "Indoor Unit (Default)" 2: "Remote Controller" 3: "External (CN105/WiFi)" # Code 103: Ventilation / Lossnay interaction - code: 103 name: "Ventilation Link" options: 1: "None (Default)" 2: "With Lossnay" 3: "Forced" # Code 105: Auto Energy Saving - code: 105 name: "Auto Energy Saving" options: 1: "ON (Default)" 2: "OFF" # Code 107: Filter Sign Interval - code: 107 name: "Filter Sign Interval" icon: "mdi:air-filter" options: 1: "100 Hours (Default)" 2: "2500 Hours" 3: "No Indication" # Code 108: Ceiling Height / Static Pressure - code: 108 name: "Ceiling Height Mode" icon: "mdi:arrow-expand-vertical" options: 1: "Standard (Default)" 2: "High Ceiling" 3: "Low Ceiling" # Code 109: Number of Air Outlets (Cassette models only) - code: 109 name: "Air Outlets" options: 1: "4 Directions (Default)" 2: "3 Directions" 3: "2 Directions" # Code 110: Auto Mode Switching Logic - code: 110 name: "Auto Mode Logic" icon: "mdi:sync" options: 1: "Energy Saving (Default)" 2: "Comfort / Performance" # Code 111: Vane Setting (for specific models) - code: 111 name: "Vane Geometry" options: 1: "Standard (Default)" 2: "Type 1" 3: "Type 2" # Code 117: Defrost Control - code: 117 name: "Defrost Logic" icon: "mdi:snowflake-melt" options: 1: "Standard (Default)" 2: "High Humidity / Frequent" # Code 124: Heating Temperature Offset - code: 124 name: "Heating Offset (+2°C)" options: 1: "ON (Default)" 2: "OFF" # Code 125: Fan behavior during Thermo-OFF (Heating) - code: 125 name: "Fan during Thermo-OFF (Heat)" icon: "mdi:fan-off" options: 1: "Extra Low (Default)" 2: "Stop" 3: "Set Speed" # Code 127: Fan behavior during Thermo-OFF (Cooling) - code: 127 name: "Fan during Thermo-OFF (Cool)" icon: "mdi:fan-off" options: 1: "Set Speed (Default)" 2: "Stop" # Code 128: System Error Display - code: 128 name: "Error Display on Remote" options: 1: "ON (Default)" 2: "OFF" ## Experimental Features The following features are considered experimental. They rely on protocol bytes or behaviors that are not officially documented by Mitsubishi and may not work on all unit models. Community feedback is essential to validate and improve them. ### Target Humidity Sensor Some premium Mitsubishi models (e.g. MSZ-LN series) expose a target humidity value in byte 12 of the `0x02` settings response packet. This value changes automatically when the operating mode is switched via the IR remote (e.g. COOL→70%, DRY→50%, HEAT→40%). This read-only diagnostic sensor allows you to monitor this value in Home Assistant. climate: - platform: cn105 # ... your existing config ... target_humidity_sensor: name: Target Humidity The sensor appears in Home Assistant with: - **Unit**: `%` - **Icon**: `mdi:water-percent` - **Category**: Diagnostic - **Precision**: 0 decimals ### Split Vane (Dual Motor) Support Some Mitsubishi wall-mount units feature split vanes with two independent motors. This component supports controlling both motors together via the `vane_type` option in the `supports` block. There are two split-vane configurations depending on your unit's hardware: | `vane_type` | Description | Tested on | |------------|-------------|-----------| | `standard` (default) | Single motor per vane axis — standard behavior | Most units | | `split_horizontal` | Dual horizontal (wide) vane motors — both left/right wide-vane motors are synchronized | MSZ-GE24NA (confirmed by [@polskikrol](https://github.com/polskikrol)) | | `split_vertical` | Dual vertical vane motors — experimental, awaiting community validation | MSZ-FH series (pending) | #### Example: Split Horizontal Vane Configuration For units with two independent horizontal (wide) vane motors (e.g. MSZ-GE24NA): climate: - platform: cn105 name: "My Heat Pump" # ... your existing config ... horizontal_vane_select: name: Horizontal Vane vertical_vane_select: name: Vertical Vane supports: mode: [HEAT_COOL, COOL, HEAT, DRY, FAN_ONLY] fan_mode: [AUTO, QUIET, LOW, MEDIUM, HIGH] swing_mode: ["OFF", HORIZONTAL, VERTICAL] vane_type: split_horizontal # ← Synchronizes both horizontal vane motors #### Example: Split Vertical Vane Configuration (Experimental) For units with two independent vertical vane motors (e.g. MSZ-FH series): climate: - platform: cn105 name: "My Heat Pump" # ... your existing config ... vertical_vane_select: name: Vertical Vane supports: swing_mode: ["OFF", VERTICAL] vane_type: split_vertical # ← Experimental: synchronizes both vertical vane motors ## Comparison with ESPHome Native `mitsubishi_cn105` Since ESPHome 2026.4.0, a native `mitsubishi_cn105` component (by [@crnjan](https://github.com/crnjan)) is available directly in the ESPHome core. Both projects implement the same CN105 serial protocol originally reverse-engineered by [SwiCago](https://github.com/SwiCago/HeatPump). This section helps you decide which one fits your needs. ### Feature Comparison | Feature | This Project (echavet) | Native ESPHome (crnjan) | |---------|:---------------------:|:----------------------:| | **Basic HVAC control** (power, mode, fan, temp) | ✅ | ✅ | | **Half-degree setpoint** (0.5°C steps) | ✅ | ✅ (PR [#15919](https://github.com/esphome/esphome/pull/15919)) | | **HEAT_COOL / AUTO mode** | ✅ Hybrid dual setpoint | ✅ HEAT_COOL mapping (PR [#15748](https://github.com/esphome/esphome/pull/15748)) | | **Dual setpoint support** | ✅ Native via `supports: dual_setpoint: true` | ❌ Single setpoint only | | **Vertical vane (swing) select** | ✅ 5 positions + SWING | ⏳ Draft PR [#15653](https://github.com/esphome/esphome/pull/15653) | | **Horizontal vane (wide vane) select** | ✅ All 8 positions + SWING | ⏳ Draft PR [#15653](https://github.com/esphome/esphome/pull/15653) | | **Dual/split vane support** | ✅ `vane_type: split_horizontal / split_vertical` | ❌ Not planned | | **Remote temperature sensor** | ✅ Built-in keep-alive + debounce + native binding | ⏳ Open PR [#15558](https://github.com/esphome/esphome/pull/15558) (lambda-only) | | **Remote temperature timeout / fallback** | ✅ Configurable auto-revert to internal sensor | ❌ Manual only | | **Fahrenheit compatibility** | ✅ Standard + Alt lookup tables | ⏳ Draft PR [#15488](https://github.com/esphome/esphome/pull/15488) | | **Compressor frequency sensor** | ✅ | ❌ Not planned | | **Input power sensor** | ✅ | ❌ Not planned | | **Energy (kWh) sensor** | ✅ | ❌ Not planned | | **Outside air temperature** | ✅ | ❌ Not planned | | **Operating status / hvac_action** | ✅ Based on compressor state | ❌ | | **Stage / Sub Mode / Auto Sub Mode** | ✅ Diagnostic sensors | ❌ | | **Runtime hours sensor** | ✅ | ❌ | | **iSee sensor** | ✅ | ❌ | | **Hardware settings (ISU / Function codes)** | ✅ Read & Write (0x20/0x22 packets) | ❌ Not planned | | **Installer mode (0x5B handshake)** | ✅ | ❌ | | **Air purifier / Night mode / Circulator** | ✅ Switches (0x08 packets) | ❌ | | **Airflow control select** | ✅ | ❌ | | **HACS integration (Climate Proxy)** | ✅ Dynamic single/dual slider UI | N/A (native HA integration) | | **ESP8266 support** | ✅ | ✅ | | **ESP32 (Arduino + IDF)** | ✅ | ✅ | | **RP2040 / BK72xx** | ❌ | ✅ | ### Architecture & Reliability Comparison | Aspect | This Project | Native ESPHome | |--------|:----------:|:------------:| | **Installation** | `external_components` reference | Zero-config, built into ESPHome core | | **UART communication** | Non-blocking, byte-by-byte in `loop()` with debounce and retry. Battle-tested across 100+ real units | Non-blocking FSM with `FrameParser`. Clean design but field-tested on fewer configurations | | **Connection recovery** | Multi-layer: UART reinit fallback for ESP-IDF 5.4.x regressions, auto-reconnect, pending packet queue | State machine with `READ_TIMEOUT` state for retry | | **Request orchestration** | `RequestScheduler` — prioritized, round-robin multi-packet cycling (settings, room temp, status, timers, HVAC options, standby) | Simple sequential poll: settings → room temp only | | **Concurrency protection** | Mutex (ESP32) / emulated mutex (ESP8266) on settings writes | Single-threaded state machine (no contention risk) | | **State management** | Distributed booleans (pragmatic, field-proven) | Formal `enum class State` FSM with validated transitions | | **Frame parsing** | Inline in main class, overflow-protected (64-byte buffer) | Encapsulated `FrameParser` class, template callback-based (32-byte buffer) | | **Type safety** | `const char*` parallel arrays (legacy SwiCago pattern) | `enum class` + `std::optional` + `constexpr` lookup | | **Temperature encoding** | Dual A/B encoding, auto-detect | Dual A/B encoding, auto-detect | | **Unit test suite** | ❌ (community-validated) | ✅ Full C++ test coverage | | **ESPHome API stability** | ⚠️ May require updates on ESPHome major releases | ✅ Maintained by core team, no breaking changes | | **Binary size** | ~5900 lines C++ (all features included) | ~700 lines C++ (minimal feature set) | | **Codebase maturity** | 2+ years, 600+ issues/PRs, active community | Released April 2026, rapidly evolving | ### When to Use Which? **Choose this project** if you need: - 🔧 **Full diagnostic visibility** — compressor frequency, power consumption, energy tracking, operating stages - 🌡️ **Advanced remote temperature** — built-in keep-alive, auto-timeout fallback, native sensor binding - 🎛️ **Complete vane control** — all positions, dual/split vane support for multi-motor units - ⚙️ **Hardware settings (ISU)** — read/write Mitsubishi function codes directly - 🔄 **Dual setpoint** — independent heat/cool targets with the Climate Proxy HACS integration - 📊 **Energy monitoring** — kWh tracking, input power sensor - 🛡️ **Proven reliability** — battle-tested firmware running on hundreds of units for 2+ years **Choose the native ESPHome component** if you need: - 🚀 **Simplest setup** — 5-line YAML, no `external_components` reference - 🔒 **Core team maintenance** — guaranteed API compatibility with ESPHome updates - ✅ **Unit-tested codebase** — formal state machine, clean architecture - 💾 **Minimal binary footprint** — ideal for constrained ESP8266 devices - 🖥️ **RP2040 / BK72xx** — platform support beyond ESP32/ESP8266 ## Other Implementations - [esphome-mitsubishiheatpump](https://github.com/geoffdavis/esphome-mitsubishiheatpump) - The original ESPHome project from which this one is forked. - [gysmo38/mitsubishi2MQTT](https://github.com/gysmo38/mitsubishi2MQTT) - Direct MQTT controls, robust but with a less stable WiFi stack. - ESPHome's built-in [Mitsubishi](https://github.com/esphome/esphome/blob/dev/esphome/components/mitsubishi/mitsubishi.h) climate component — Uses IR Remote commands, lacks bi-directional communication. - ESPHome's native [`mitsubishi_cn105`](https://github.com/esphome/esphome/tree/dev/esphome/components/mitsubishi_cn105) component — CN105 UART support built into ESPHome core since 2026.4.0. See comparison above. ## Reference Documentation Refer to these for further understanding: - [ESPHome Custom Sensors](https://esphome.io/components/sensor/custom.html) - [ESPHome Custom Climate Components](https://esphome.io/components/climate/custom.html) - [ESPHome External Components](https://esphome.io/components/external_components.html) - [ESPHome's Climate Component Source](https://github.com/esphome/esphome/tree/master/esphome/components/climate) ## Disclaimer This project is not affiliated with, endorsed by, or associated with Mitsubishi Electric Corporation. "Mitsubishi Electric" and the three-diamond logo are registered trademarks of Mitsubishi Electric Corporation. The use of these trademarks in this project is for identification purposes only, to indicate compatibility with their products.
标签:ESP32, ESPHome, Home Assistant, 固件, 智能家居, 暖通空调控制, 物联网