Hi @dark10
Have no idea what can cause your issue. It looks like there is some problem with libraries. I would recommend to use esp-idf framework instead of Arduino. I have 3 AC working with M5Stamp C3U with latest ESPHome in docker container no issues at all.
Hi, @dark10
I’m facing the same issue as you but with HON protocol only, I could update my AC using SmartAir2 protocol without any issue. I created a ticket on the link below.
@dark10,
I got a reply from randybb to update the framework type to esp-isf, after the reinstallation, it worked as expected.
Hi guys. I would like to share a breakthrough with my latest home automation project. I recently bought a new Haier aircon, thinking I could connect it to Home Assistant like the old one. However, these newer models come with a built-in “esp32-for-haier,” which was a surprise for me.
Inspired by some amazing articles by Michał Góral (thanks for the guide: goral.net.pl/post/replacing-haier-wifi-modules/), I set out to avoid snipping the original wires. But soldering JST connectors to DuPont cables is fiddly. Especially if, like me, you don’t have a background in electronics.
So, I made a leap: I designed my own PCB on JLCPCB, complete with pinholes so my Lolin S2 Mini ESP can be soldered on easily and had the factory pre-solder the JST connector for me.
I am genuinely excited about how this turned out. It fits snugly and works perfectly with Home Assistant.
Like that?
esp32:
board: esp32-s3-devkitc-1
framework:
type: esp-idf
Do I need to change board to:
board: m5stack-atoms3
esp32:
board: esp32-s3-devkitc-1
framework:
type: esp-idf
This is solution for my problem
Hi,
I noticed while using the YAML below i can’t controll the indoor temperature (the value read from the built-in sensor). After some research, I found out that this is possible with a Loxone system.
Is this also possible in ESPHome, or has anyone already implemented this successfully?
YAML
esphome:
name: haier-c3
friendly_name: haier-c3
platformio_options:
board_build.flash_mode: dio
esp32:
board: esp32-c3-devkitm-1
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "very secret!"
services:
- service: turn_on
then:
- climate.haier.power_on: haier_ac
- service: turn_off
then:
- climate.haier.power_off: haier_ac
ota:
- platform: esphome
password: "very secret!"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
output_power: 17db
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Haier-C3 Fallback Hotspot"
password: "very secret!"
uart:
baud_rate: 9600
tx_pin: GPIO21
rx_pin: GPIO20
id: haier_uart
climate:
- platform: haier
id: haier_ac
protocol: hon
name: Haier hOn Climate
uart_id: haier_uart
wifi_signal: true
use_external_sensor: true # dit forceert AC om indoor temp van ons te nemen
visual:
min_temperature: 16 °C
max_temperature: 30 °C
temperature_step:
target_temperature: 1
current_temperature: 0.5
supported_modes:
- 'OFF'
- HEAT_COOL
- COOL
- HEAT
- DRY
- FAN_ONLY
supported_swing_modes:
- 'OFF'
- VERTICAL
- HORIZONTAL
- BOTH
supported_presets:
- BOOST
- SLEEP
on_alarm_start:
then:
- homeassistant.service:
service: logbook.log
data:
domain: climate
name: Haier hOn Climate
data_template:
message: "Alarm activated ({{ alarm_code }}): {{alarm_message}}"
variables:
alarm_message: !lambda "return message;"
alarm_code: !lambda "return code;"
- homeassistant.service:
service: notify.persistent_notification
data:
title: "Haier hOn Climate: alarm activated"
data_template:
message: "Code: {{ alarm_code }}, message: \"{{ alarm_message }}\""
variables:
alarm_message: !lambda "return message;"
alarm_code: !lambda "return code;"
on_alarm_end:
then:
- homeassistant.service:
service: logbook.log
data:
domain: climate
name: Haier hOn Climate
data_template:
message: "Alarm deactivated ({{ alarm_code }}): {{alarm_message}}"
variables:
alarm_message: !lambda "return message;"
alarm_code: !lambda "return code;"
button:
- platform: haier
haier_id: haier_ac
self_cleaning:
name: Haier hOn Climate start self cleaning
steri_cleaning:
name: Haier hOn Climate start 56°C steri-cleaning
text_sensor:
- platform: haier
haier_id: haier_ac
cleaning_status:
name: Haier hOn Climate cleaning status
protocol_version:
name: Haier hOn Climate protocol version
switch:
- platform: haier
beeper:
name: Haier hOn Climate beeper
health_mode:
name: Haier hOn Climate health mode
display:
name: Haier hOn Climate display
quiet_mode:
name: Haier hOn Climate quiet mode
select:
- platform: template
id: haier_ac_vertical_direction
name: Haier hOn Climate airflow vertical
entity_category: config
icon: mdi:arrow-expand-vertical
update_interval: 5s
options:
- Health Up
- Max Up
- Up
- Center
- Down
- Max Down
- Health Down
- Auto
lambda: >-
switch (id(haier_ac).get_vertical_airflow().value_or(esphome::haier::hon_protocol::VerticalSwingMode::CENTER))
{
case esphome::haier::hon_protocol::VerticalSwingMode::HEALTH_UP:
return std::string("Health Up");
case esphome::haier::hon_protocol::VerticalSwingMode::MAX_UP:
return std::string("Max Up");
case esphome::haier::hon_protocol::VerticalSwingMode::UP:
return std::string("Up");
default:
case esphome::haier::hon_protocol::VerticalSwingMode::CENTER:
return std::string("Center");
case esphome::haier::hon_protocol::VerticalSwingMode::DOWN:
return std::string("Down");
case esphome::haier::hon_protocol::VerticalSwingMode::MAX_DOWN:
return std::string("Max Down");
case esphome::haier::hon_protocol::VerticalSwingMode::HEALTH_DOWN:
return std::string("Health Down");
case esphome::haier::hon_protocol::VerticalSwingMode::AUTO:
case esphome::haier::hon_protocol::VerticalSwingMode::AUTO_SPECIAL:
return std::string("Auto");
}
set_action:
- climate.haier.set_vertical_airflow:
id: haier_ac
vertical_airflow: !lambda >-
if (x == "Health Up")
return esphome::haier::hon_protocol::VerticalSwingMode::HEALTH_UP;
else if (x == "Max Up")
return esphome::haier::hon_protocol::VerticalSwingMode::MAX_UP;
else if (x == "Up")
return esphome::haier::hon_protocol::VerticalSwingMode::UP;
else if (x == "Down")
return esphome::haier::hon_protocol::VerticalSwingMode::DOWN;
else if (x == "Max Down")
return esphome::haier::hon_protocol::VerticalSwingMode::MAX_DOWN;
else if (x == "Health Down")
return esphome::haier::hon_protocol::VerticalSwingMode::HEALTH_DOWN;
else if (x == "Auto")
return esphome::haier::hon_protocol::VerticalSwingMode::AUTO;
else
return esphome::haier::hon_protocol::VerticalSwingMode::CENTER;
- platform: template
id: haier_ac_horizontal_direction
name: Haier hOn Climate airflow horizontal
entity_category: config
icon: mdi:arrow-expand-horizontal
update_interval: 5s
options:
- Max Left
- Left
- Center
- Right
- Max Right
- Auto
lambda: >-
switch (id(haier_ac).get_horizontal_airflow().value_or(esphome::haier::hon_protocol::HorizontalSwingMode::CENTER))
{
case esphome::haier::hon_protocol::HorizontalSwingMode::MAX_LEFT:
return std::string("Max Left");
case esphome::haier::hon_protocol::HorizontalSwingMode::LEFT:
return std::string("Left");
default:
case esphome::haier::hon_protocol::HorizontalSwingMode::CENTER:
return std::string("Center");
case esphome::haier::hon_protocol::HorizontalSwingMode::RIGHT:
return std::string("Right");
case esphome::haier::hon_protocol::HorizontalSwingMode::MAX_RIGHT:
return std::string("Max Right");
case esphome::haier::hon_protocol::HorizontalSwingMode::AUTO:
return std::string("Auto");
}
set_action:
- climate.haier.set_horizontal_airflow:
id: haier_ac
horizontal_airflow: !lambda >-
if (x == "Max Left")
return esphome::haier::hon_protocol::HorizontalSwingMode::MAX_LEFT;
else if (x == "Left")
return esphome::haier::hon_protocol::HorizontalSwingMode::LEFT;
else if (x == "Right")
return esphome::haier::hon_protocol::HorizontalSwingMode::RIGHT;
else if (x == "Max Right")
return esphome::haier::hon_protocol::HorizontalSwingMode::MAX_RIGHT;
else if (x == "Auto")
return esphome::haier::hon_protocol::HorizontalSwingMode::AUTO;
else
return esphome::haier::hon_protocol::HorizontalSwingMode::CENTER;
sensor:
- platform: haier
haier_id: haier_ac
compressor_current:
name: Haier hOn Climate Compressor Current
compressor_frequency:
name: Haier hOn Climate Compressor Frequency
expansion_valve_open_degree:
name: Haier hOn Climate Expansion Valve Open Degree
humidity:
name: Haier hOn Climate Indoor Humidity
indoor_coil_temperature:
name: Haier hOn Climate Indoor Coil Temperature
outdoor_coil_temperature:
name: Haier hOn Climate Outdoor Coil Temperature
outdoor_defrost_temperature:
name: Haier hOn Climate Outdoor Defrost Temperature
outdoor_in_air_temperature:
name: Haier hOn Climate Outdoor In Air Temperature
outdoor_out_air_temperature:
name: Haier hOn Climate Outdoor Out Air Temperature
outdoor_temperature:
name: Haier hOn Climate outdoor temperature
power:
name: Haier hOn Climate Power
binary_sensor:
- platform: haier
haier_id: haier_ac
compressor_status:
name: Haier hOn Climate Compressor Status
defrost_status:
name: Haier hOn Climate Defrost Status
four_way_valve_status:
name: Haier hOn Climate Four-way Valve Status
indoor_electric_heating_status:
name: Haier hOn Climate Indoor Electric Heating Status
indoor_fan_status:
name: Haier hOn Climate Indoor Fan Status
outdoor_fan_status:
name: Haier hOn Climate Outdoor Fan Status
captive_portal:
Loxone Template:
https://library.loxone.com/detail/haier-air-condition-ycj-a002-928/overview
I managed to find some time to assemble the connector and test this integration with my TUNDRA AS18TD2HRA and it works well.
The only annoying thing is the beep at each change from home assistant that can’t be disabled with smartair2 protocol.
I was also trying to find a way to lock settings to avoid inappropriate use while not disconnecting the IR remote as it is a bit a radical solution. But it seems challenging.
I’m having another issue. My esp32 seems to reboot many times but without an apparent regular pattern.
The main problem is that at each reboot the AC split emits a beep sound which is very annoying.
I think the wifi is not very stable near the AC but I’ve already tried to disable reboot_timeout with 0s value but it seems to happen the same.
I’ve configured it to work via mqtt broker and a ble tracker for another sensor in the same room.
I think i will disable haier debug logs as it spams constantly these types of logs and it is difficult to understand if there’s some other problem.
Maybe should I play with keepalive and reboot_timeout for mqtt settings too? Because i’m having also:
e[0;33m[W][component:424]: Components should block for at most 30 mse[0m
Could share your project for PCB on JLCPCB, please.
Warnings after updating today… ![]()
Warning: DEPRECATED: 'esptool.py' is deprecated. Please use 'esptool' instead. The '.py' suffix will be removed in a future major release.
Creating ESP32S3 image...
Successfully created ESP32S3 image.
Linking .pioenvs/esphome-web-f7c8bf/firmware.elf
usage: esp_idf_size [-h] [--format {table,text,tree,csv,json2,raw,dot}]
[--archives] [--archive-dependencies] [--dep-symbols]
[--dep-reverse] [--archive-details ARCHIVE_NAME] [--files]
[--diff MAP_FILE] [--no-abbrev] [--unify] [--show-unused]
[--show-unchanged] [--use-flash-size] [--lto] [-d]
[-o OUTPUT_FILE] [-s COLUMN] [-F PATTERN] [--sort-diff]
[--sort-reverse] [-q] [--no-color] [--force-terminal]
[--doc]
MAP_FILE
esp_idf_size: error: unrecognized arguments: --ng
Warning: esp-idf-size exited with code 2
RAM: [= ] 12.9% (used 42388 bytes from 327680 bytes)
Flash: [===== ] 47.4% (used 870050 bytes from 1835008 bytes)
Building .pioenvs/esphome-web-f7c8bf/firmware.bin
Warning: DEPRECATED: 'esptool.py' is deprecated. Please use 'esptool' instead. The '.py' suffix will be removed in a future major release.
I would like to share how finally I was able to make it work with below project from : paveldn → GitHub - paveldn/haier-esphome: Haier ac integration for ESPHome · GitHub
and Haier AC’s (2 different types).
Initially I was using cheap esp8266 board from aliexpress. I had some old board: WeMos D1 Mini Pro V3.0 NodeMcu 4MB
and I was trying to upload soft there.
For this board i used below yaml config:
esphome:
name: ac-sypialnia
name_add_mac_suffix: true # optional, adds MAC to device name
friendly_name: AC_SYPIALNIA
esp8266:
board: d1_mini
Wi-Fi with fallback AP
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: “ESP8266_Fallback”
password: “fallbackpassword”
Enable UART logging for debug
logger:
baud_rate: 0
level: DEBUG
OTA for future updates
ota:
- platform: esphome
API for Home Assistant
api:
Web server for testing
web_server:
UART for Haier AC communication
uart:
- id: ac_port
tx_pin: 1 # GPIO1 (hardware TX)
rx_pin: 3 # GPIO3 (hardware RX)
baud_rate: 9600
climate:
- platform: haier
id: haier_ac
protocol: hOn
name: Haier AC
uart_id: ac_port
wifi_signal: true
display: true
visual:
min_temperature: 16 °C
max_temperature: 30 °C
temperature_step: 1 °C
supported_modes:- ‘OFF’
- HEAT_COOL
- COOL
- HEAT
- DRY
- FAN_ONLY
supported_swing_modes: - ‘OFF’
- VERTICAL
- HORIZONTAL
- BOTH
supported_presets: - AWAY
- BOOST
- SLEEP
on_alarm_start:
then:- logger.log:
level: WARN
format: “Alarm activated. Code: %d. Message: "%s"”
args: [ code, message ]
on_alarm_end:
then: - logger.log:
level: INFO
format: “Alarm deactivated. Code: %d. Message: "%s"”
args: [ code, message ]
on_status_message:
then: - logger.log:
level: INFO
format: “New status message received, size=%d, subcmd=%02X%02X”
args: [ ‘data_size’, ‘data[0]’, ‘data[1]’ ]
- logger.log:
Include local Haier component
packages:
local_haier: !include configs/external_components/local_haier.yaml
it worked like charm. When I was excited that it worked, I decided to equip the remaining air conditioning units with similar ESPs. However, for some reason, I bought slightly different ones this time — a newer model, version 4: WEMOS D1 Mini V4.0.0 TYPE-C.
…and that’s where the problems began. I couldn’t get any response from the AC at all.
[14:36:49.146][I][haier.climate:096]: Answer timeout for command 61, phase SENDING_INIT_1
[14:36:53.578][I][haier.climate:096]: Answer timeout for command 01, phase SENDING_FIRST_STATUS_REQUEST
It’s worth noting here that at that time, my pin configuration in the YAML file was identical to the previous board — I was trying to use RX/TX.
I spent a lot of time experimenting, trying different pins, e.g. tx_pin: 15 and rx_pin: 13.
Sometimes it would start working, but only in certain situations. I had to perform a kind of “startup procedure.”
When I connected only the ESP board to the computer via USB (without any AC wires), it powered up and connected to the router.
Only then could I connect the green and white wires from the air conditioner to pins 15 and 13. In that case, everything worked fine, and two-way communication was possible.
The problem appeared when I turned off the main power (circuit breakers), and the AC lost power. After turning it back on, the board wouldn’t start in that configuration — it couldn’t connect to the home network. I didn’t understand why.
When I disconnected the wires from pins 13/15 and restarted it, it connected to Wi-Fi without any issue.
That’s when I came across this article:
https://wolles-elektronikkiste.de/en/wemos-d1-mini-boards
Restrictions for the use of some pins
Some pins have special functions, so there are certain restrictions for them:
- D0 (GPIO 16): Needed to wake up from DeepSleep. It also outputs a short HIGH signal on boot.
- D3 (GPIO 0): If pulled LOW during boot, the ESP8266 enters firmware programming mode.
- D4 (GPIO 2): Must not be pulled LOW during boot.
- D8 (GPIO 15): Must not be pulled HIGH during boot.
And that turned out to be the reason why the board wouldn’t start after power cycling when everything was connected.
So I reassigned the UART pins to D1 (GPIO5) and D2 (GPIO4):
# UART for Haier AC communication
uart:
- id: ac_port
tx_pin: 4
rx_pin: 5
baud_rate: 9600
…and it started working 100% perfectly.
Morning,
Since last week I get this error with updating Esp8266 for my 4 Haier AC’s with smartair2 protocol.
Can anyone sent me in the right direction?
I’m a little confused and don’t know where to look for…
INFO ESPHome 2025.11.0
INFO Reading configuration /config/esphome/airco-ashley.yaml…
INFO Updating https://github.com/robertklep/esphome-custom-component@None
INFO Updating https://github.com/esphome/esphome.git@pull/11388/head
ERROR Unexpected exception while reading configuration:
Traceback (most recent call last):
File “/usr/local/bin/esphome”, line 10, in
sys.exit(main())
^^^^^^
File “/esphome/esphome/main.py”, line 1490, in main
return run_esphome(sys.argv)
^^^^^^^^^^^^^^^^^^^^^
File “/esphome/esphome/main.py”, line 1465, in run_esphome
config = read_config(
^^^^^^^^^^^^
File “/esphome/esphome/config.py”, line 1302, in read_config
res = load_config(command_line_substitutions, skip_external_update)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/esphome/esphome/config.py”, line 1159, in load_config
return _load_config(command_line_substitutions, skip_external_update)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/esphome/esphome/config.py”, line 1147, in _load_config
return validate_config(config, command_line_substitutions, skip_external_update)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/esphome/esphome/config.py”, line 1038, in validate_config
target_platform = core_config.preload_core_config(config, result)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/esphome/esphome/core/config.py”, line 347, in preload_core_config
if _is_target_platform(domain):
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/esphome/esphome/core/config.py”, line 297, in _is_target_platform
return get_component(name, True).is_target_platform
^^^^^^^^^^^^^^^^^^^^^^^^^
File “/esphome/esphome/loader.py”, line 223, in get_component
return _lookup_module(domain, exception)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/esphome/esphome/loader.py”, line 199, in _lookup_module
module = importlib.import_module(f"esphome.components.{domain}")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/usr/local/lib/python3.12/importlib/init.py”, line 90, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “”, line 1387, in _gcd_import
File “”, line 1360, in _find_and_load
File “”, line 1331, in _find_and_load_unlocked
File “”, line 935, in _load_unlocked
File “”, line 999, in exec_module
File “”, line 488, in _call_with_frames_removed
File “/data/external_components/a879a32c/esphome/components/climate/init.py”, line 275, in
CLIMATE_SCHEMA.add_extra(cv.deprecated_schema_constant(“climate”))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: module ‘esphome.config_validation’ has no attribute ‘deprecated_schema_constant’
If you don’t want to mess with the ac board, you can use my guide to extract DeviceId & LocalKey
#https://github.com/paveldn/haier-esphome/
substitutions:
device_name: Airco Joost Izaura
device_id: joost_izaura_climate
uart_id: ac_joost_izaura
send_wifi: "true"
esphome:
name: airco-joost-izaura
#ota:
# - platform: esphome
esp8266:
board: d1_mini
wifi:
ssid: "***************"
password: "***********"
fast_connect: true
uart:
baud_rate: 9600
tx_pin: 1
rx_pin: 3
id: ${uart_id}
logger:
level: DEBUG
hardware_uart: uart1
# baud_rate: 0
web_server:
packages:
local_haier: !include configs/external_components/local_haier.yaml
haier_base: !include .haier-smartair2-base.yaml
button:
- platform: safe_mode
name: "Airco Joost Izaura Restart (Safe Mode)"
Hello everybody. This was a working yaml but is not updatable anymore.
I changed it to the following
substitutions:
device_name: Airco Joost Izaura
device_id: joost_izaura_climate
uart_id: ac_joost_izaura
send_wifi: "true"
esphome:
name: airco-joost-izaura
friendly_name: ${device_name}
esp8266:
board: d1_mini
wifi:
ssid: "***********"
password: "*************"
fast_connect: true
min_auth_mode: WPA2
api:
ota:
- platform: esphome
web_server:
uart:
id: ${uart_id}
baud_rate: 9600
tx_pin: 1 # GPIO1 (TX)
rx_pin: 3 # GPIO3 (RX)
debug:
direction: BOTH
dummy_receiver: true
logger:
level: DEBUG
hardware_uart: uart1
climate:
- platform: haier
id: ${device_id}
name: ${device_name}
protocol: smartair2
uart_id: ${uart_id}
wifi_signal: true
display: true
visual:
min_temperature: 16 °C
max_temperature: 30 °C
temperature_step: 1 °C
supported_modes:
- "OFF"
- HEAT_COOL
- COOL
- HEAT
- DRY
- FAN_ONLY
supported_swing_modes:
- "OFF"
- VERTICAL
- HORIZONTAL
- BOTH
supported_presets:
- AWAY
- BOOST
- COMFORT
button:
- platform: safe_mode
name: "Airco Joost Izaura Restart (Safe Mode)"
The yaml is valid and I uploaded it to the ESP.
The unit is not responding on any command.
Who can help me?
Thanks!
substitutions:
device_name: Airco Joost Izaura
device_id: joost_izaura_climate
uart_id: ac_joost_izaura
send_wifi: "true"
esphome:
name: airco-joost-izaura
friendly_name: ${device_name}
esp8266:
board: d1_mini
wifi:
ssid: "*************"
password: "**********"
fast_connect: true
min_auth_mode: WPA2
uart:
id: ${uart_id}
baud_rate: 9600
tx_pin: 1
rx_pin: 3
logger:
level: DEBUG
hardware_uart: uart1
baud_rate: 0 # belangrijk bij ESP8266 + UART op GPIO1/3
api:
ota:
- platform: esphome
web_server:
climate:
- platform: haier
id: ${device_id}
name: ${device_name}
wifi_signal: ${send_wifi}
display: true
visual:
min_temperature: 16 °C
max_temperature: 30 °C
temperature_step: 1 °C
supported_modes:
- "OFF"
- HEAT_COOL
- COOL
- HEAT
- DRY
- FAN_ONLY
supported_swing_modes:
- "OFF"
- VERTICAL
- HORIZONTAL
- BOTH
supported_presets:
- AWAY
- BOOST
button:
- platform: safe_mode
name: "Airco Joost Izaura Restart (Safe Mode)"
This is working!
Hi all,
I’m trying to integrate my Haier AC with ESPHome using the haier component, but I’m stuck at the UART communication stage and would really appreciate some guidance from people who already worked with similar hardware.
AC model:
AS15NS1HRA-WF (Nebula series)
Original Wi-Fi module:
Label on the module:
V98533 Y1
1.0.09
0011800292B GB20150105
Inside this module there is a board based on WN4616A.
On the PCB there are clearly labeled pads:
- TXD / RXD
- UART_TXD / UART_RXD
- GND / 5V
I will attach photos of the board and the pin labels.
What works
If I plug the original Wi-Fi module back into the AC and pair it with the SmartAir2 app, everything works perfectly. So the communication between the module and the AC is confirmed to be OK.
What I tried
I’m using an M5 AtomS3 Lite (ESP32-S3) with ESPHome.
1) Direct connection to the AC connector (module removed)
I disconnected the Wi-Fi module completely and connected the Atom directly to the 4-pin connector going to the AC:
- 5V and GND from the AC power the Atom correctly
- the two data lines connected to RX/TX (also swapping them)
Using ESPHome with:
climate:
- platform: haier
protocol: smartair2
I always get:
Answer timeout for command 61, phase SENDING_INIT_1
ESPHome clearly sends valid frames, but the AC never answers.
I also tried:
- swapping RX/TX
- adding resistor divider on RX
- adding series resistor on TX
- very short wires
- no breadboard
No change.
2) Sniffing the bus while original module is connected
I reconnected the original module and used the Atom only as UART sniffer (RX only, UART debug enabled).
Result:
- I can see activity on the lines
- but the data does not look like valid Haier frames (mostly zeros / noise depending on baud)
- touching the lines in parallel often destabilizes the Wi-Fi module
This made me suspect that the bus is not simple push-pull TTL.
3) Connecting to the UART pads on the WN4616A board
I left the Wi-Fi module connected to the AC and connected the Atom to:
- GND
- UART_TXD
- UART_RXD
With UART debug enabled I still cannot see clean, structured frames when using the app to change temperature / power state.
This makes me think that:
- either these pads are not the actual UART used toward the AC MCU,
- or there is level shifting / open-collector / transistor stage between these pads and the AC bus.
Questions
- Has anyone worked with this specific module (V98533 / WN4616A) before?
- Are the pads labeled
UART_TXD / UART_RXDreally the UART toward the AC MCU, or just a debug/programming port? - Does this module use an open-collector / open-drain interface toward the AC that requires a transistor instead of direct ESP32 connection?
- Is there any known schematic or confirmed wiring for this specific board?
I’ll attach detailed photos of:
- the module
- the PCB
- the pin labels
- the connector toward the AC
Thanks a lot for any hint — I feel I’m very close, but clearly missing something about how this module electrically interfaces with the AC.








