ESP Haier: Haier Air Conditioner + ESP Home + Wemos D1 mini

I have tried, well, trying the cleaner just now, it did start, also I dunno if health mode switch was also added, but that also works.

I have set mode to off when AC was in clean mode, and it seems to also works as intended, cleaning continues and after that it shuts down.

I think we now have pretty much everything that AC can do? Only thing I think are still missing are 10C mode and most top and most bottom (“health airflow”) vertical airflow settings to have absolutely everything Haier AC units sold in EU can do.

Thanks for testing. Glad everything works.

According to documentation normal self-cleaning should take up to 21 min and AC should beep twice at the end. There is also 56°C Steri-Clean function (which should take 80 minutes) I will add support a little bit later.

Yes, I have plans to add a 10C function. There are much more things in the protocol but I am not sure if it is implemented in any real AC or just reserved for the future. There is power consumption, a pm2.5 sensor, etc (which is always 0 for me), and there is a firmware update protocol for AC which is useless without real firmware. Also, it is not really clear what to do when AC reports an error. According to documentation, it will send an error message until it will be acknowledged by the ESP module. so it should be acknowledged, but when? When it is received or when the problem is fixed or after some time? That is why I made some kind of simulator, to see how the original module behaves when AC is doing something that I can’t get from real AC. Just need some time for experiments.

1 Like

I did take the unit apart and there was no PM2.5 sensor, I don’t think there are units with that sold in EU, the protocol I shared months ago is somewhat universal provided from haier mostly for supporting custom ACs in their ecosystem. Luckily they use the same one.

I do not think haier AC can update firmware, maybe the haier wifi module can. AC uses R5F100LEA SOC, which does not seem like something that can be updated.

Hi guys,

I have a Bergen AC, which seems to be Haier with a different brand name for SEE market.
It uses the same remote as Haier (v12843 HJ), and has a USB port for wireless module, so I thought to give this controller a try.
I uploaded code to esp8266, connected to my AC, and it works… sort of.
Turning on AC from HA works with no problem, even updating the state when turned on from remote, however, I can’t turn it off from HA. It sends OFF command, and then i hear two beeps, and it turns it back on to whatever mode was in previously.
Log shows that it sends off command, but it seems to me that the AC doesn’t recognize it.
It also doesn’t have fan only

If I press off 2 times in fast succession, it goes off. Same when I use the climate.turn_off service.
I suppose I need to adjust something in the off command in the Haier.h file.
Can someone point me in the right direction?

This is log when I’m turning it on from HA:

[23:06:07][D][climate:387]: 'Haier' - Sending state:
[23:06:07][D][climate:390]:   Mode: OFF
[23:06:07][D][climate:395]:   Fan Mode: AUTO
[23:06:07][D][climate:401]:   Preset: NONE
[23:06:07][D][climate:410]:   Current Temperature: 20.00°C
[23:06:07][D][climate:416]:   Target Temperature: 20.00°C
[23:06:07][D][Haier:131]: POLL: 
0-255
1-255
2-10
3-0
4-0
5-0
6-0
7-0
8-1
9-1
10-77
11-1
12-90 
[23:06:08][D][Haier:186]: Readed message: 
0-255
1-255
2-34
3-0
4-0
5-0
6-0
7-0
8-1
9-2
10-109
11-1
12-0
13-20
14-0
15-0
16-0
17-127
18-0
19-0
20-0
21-0
22-0
23-2
24-0
25-3
26-0
27-0
28-0
29-1
30-0
31-0
32-0
33-0
34-0
35-4
36-48 
[23:06:08][D][climate:387]: 'Haier' - Sending state:
[23:06:08][D][climate:390]:   Mode: HEAT
[23:06:08][D][climate:395]:   Fan Mode: AUTO
[23:06:08][D][climate:401]:   Preset: NONE
[23:06:08][D][climate:410]:   Current Temperature: 20.00°C
[23:06:08][D][climate:416]:   Target Temperature: 20.00°C
[23:06:08][D][Haier:186]: Readed message: 
0-255
1-255
2-34
3-0
4-0
5-0
6-0
7-0
8-1
9-2
10-109
11-1
12-0
13-20
14-0
15-0
16-0
17-127
18-0
19-0
20-0
21-0
22-0
23-2
24-0
25-3
26-0
27-0
28-0
29-1
30-0
31-0
32-0
33-0
34-0
35-4
36-48 

And this is when I turn off from remote:

[23:49:07][D][climate:387]: 'Haier' - Sending state:
[23:49:07][D][climate:390]:   Mode: OFF
[23:49:07][D][climate:395]:   Fan Mode: AUTO
[23:49:07][D][climate:401]:   Preset: NONE
[23:49:07][D][climate:410]:   Current Temperature: 24.00°C
[23:49:08][D][climate:416]:   Target Temperature: 26.00°C
[23:49:07][D][Haier:131]: POLL: 
0-255
1-255
2-10
3-0
4-0
5-0
6-0
7-0
8-1
9-1
10-77
11-1
12-90 
[23:49:07][D][Haier:186]: Readed message: 
0-255
1-255
2-34
3-0
4-0
5-0
6-0
7-0
8-1
9-2
10-109
11-1
12-0
13-24
14-0
15-0
16-0
17-127
18-0
19-0
20-0
21-0
22-0
23-0
24-0
25-3
26-0
27-0
28-0
29-16
30-0
31-0
32-0
33-0
34-0
35-10
36-71

Hi nikolaos,
I didn’t do any tests just a quick glance at Miguel’s code but I think I found the issue: find the line:

sendData(off, sizeof(off));

line 287, and replace break; in next line with return;
it should help.
And to remove fan only mode you need to remove it from traits.set_supported_modes, remove line climate::CLIMATE_MODE_FAN_ONLY (line 144)
Good luck

Yes, I also got the feeling that protocol is kind of universal with a lot of commands just reserved for the future. But what surprises me the most, a lot of commands that are marked in the document you shared as “Required” is not supported by their own AC. It is a strange approach from my point of view.

1 Like

That fixed it. It turns off normally now. Thank you.

It looks like a new generation of Haier ESP32 modules has encryption (secure boot) enabled which makes it impossible to flash them with any firmware that is not encrypted and signed with a private key. So it means that it is impossible to flash these modules with ESPHome and if you will try to do so without making a backup of the original flash you will brick the device. Just a warning for everyone willing to try: First, make a backup!

Good day everybody.

I started working on this component because all other implementations were based on the Arduino framework. The original ESP32 haier module has a single-core CPU so there was no way to build ESPHome with Arduino framework for it, only with esp-idf. That is why I named the repository ESP32-S0WD-Haier, by the original name of ESP32 haier module CPU.
But now it is much more. My component supports both frameworks Arduino and esp-idf and both protocols smartAir2 and hOn. That is why I decided to rename the repository to haier-esphome I think this name better describes the purpose of the component.
So if you using it in your yaml config file, please change it to the correct one. Sorry for the inconvenience.
Also, I removed the experimental and smartair2_test branches and merged the dev and the master branch. So now the master branch has all the latest changes.

2 Likes

Hey,

I used https://github.com/paveldn/ESP32-S0WD-Haier/tree/experimental
Now I changed to the new dev version.
Adapted the “esp32-haier-module.yaml”.
Adapted the components/haier files.
Adapted the .haier-hon-base.yaml.
It’s not working anymore. When installing it returns:

INFO Reading configuration /config/esphome/airco-denn.yaml...
INFO Detected log level for Haier protocol: DEBUG
INFO Generating C++ source...
INFO Compiling app...
Processing airco-denn (board: esp32dev; framework: espidf; platform: platformio/espressif32 @ 5.3.0)
--------------------------------------------------------------------------------
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
 - framework-espidf @ 3.40404.0 (4.4.4) 
 - tool-cmake @ 3.16.4 
 - tool-ninja @ 1.7.1 
 - toolchain-esp32ulp @ 2.35.0-20220830 
 - toolchain-xtensa-esp32 @ 8.4.0+2021r2-patch5
Reading CMake configuration...
Dependency Graph
|-- HaierProtocol @ 0.9.18
Compiling /data/airco-denn/.pioenvs/airco-denn/src/main.o
Linking /data/airco-denn/.pioenvs/airco-denn/firmware.elf
/data/cache/platformio/packages/[email protected]+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /data/airco-denn/.pioenvs/airco-denn/src/esphome/components/api/api_connection.o:(.literal._ZN7esphome3api13APIConnection14button_commandERKNS0_20ButtonCommandRequestE+0x0): undefined reference to `esphome::button::Button::press()'
/data/cache/platformio/packages/[email protected]+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /data/airco-denn/.pioenvs/airco-denn/src/esphome/components/api/api_connection.o:(.literal._ZN7esphome3api13APIConnection22send_text_sensor_stateEPNS_11text_sensor10TextSensorENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+0x4): undefined reference to `esphome::text_sensor::TextSensor::has_state()'
/data/cache/platformio/packages/[email protected]+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /data/airco-denn/.pioenvs/airco-denn/src/esphome/components/api/api_connection.o:(.literal._ZN7esphome3api13APIConnection16send_button_infoEPNS_6button6ButtonE+0x4): undefined reference to `esphome::button::Button::get_device_class[abi:cxx11]()'
/data/cache/platformio/packages/[email protected]+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /data/airco-denn/.pioenvs/airco-denn/src/esphome/components/api/api_connection.o: in function `esphome::api::APIConnection::button_command(esphome::api::ButtonCommandRequest const&)':
/config/esphome/.esphome/build/airco-denn/src/esphome/components/api/api_connection.cpp:709: undefined reference to `esphome::button::Button::press()'
/data/cache/platformio/packages/[email protected]+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /data/airco-denn/.pioenvs/airco-denn/src/esphome/components/api/api_connection.o: in function `esphome::api::APIConnection::send_text_sensor_state(esphome::text_sensor::TextSensor*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
/config/esphome/.esphome/build/airco-denn/src/esphome/components/api/api_connection.cpp:490: undefined reference to `esphome::text_sensor::TextSensor::has_state()'
/data/cache/platformio/packages/[email protected]+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /data/airco-denn/.pioenvs/airco-denn/src/esphome/components/api/api_connection.o: in function `esphome::api::APIConnection::send_button_info(esphome::button::Button*)':
/config/esphome/.esphome/build/airco-denn/src/esphome/components/api/api_connection.cpp:698: undefined reference to `esphome::button::Button::get_device_class[abi:cxx11]()'
/data/cache/platformio/packages/[email protected]+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /data/airco-denn/.pioenvs/airco-denn/src/main.o:(.literal._ZN7esphome6button18ButtonPressTriggerC5EPNS0_6ButtonE[esphome::button::ButtonPressTrigger::ButtonPressTrigger(esphome::button::Button*)]+0x8): undefined reference to `esphome::button::Button::add_on_press_callback(std::function<void ()>&&)'
/data/cache/platformio/packages/[email protected]+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /data/airco-denn/.pioenvs/airco-denn/src/main.o:(.literal._Z5setupv+0x1d4): undefined reference to `vtable for esphome::text_sensor::TextSensor'
/data/cache/platformio/packages/[email protected]+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /data/airco-denn/.pioenvs/airco-denn/src/main.o:(.literal._Z5setupv+0x1d8): undefined reference to `vtable for esphome::template_::TemplateTextSensor'
/data/cache/platformio/packages/[email protected]+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /data/airco-denn/.pioenvs/airco-denn/src/main.o:(.literal._Z5setupv+0x1dc): undefined reference to `vtable for esphome::template_::TemplateTextSensor'
/data/cache/platformio/packages/[email protected]+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /data/airco-denn/.pioenvs/airco-denn/src/main.o:(.literal._Z5setupv+0x244): undefined reference to `esphome::template_::TemplateTextSensor::set_template(std::function<esphome::optional<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > ()>&&)'
/data/cache/platformio/packages/[email protected]+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /data/airco-denn/.pioenvs/airco-denn/src/main.o: in function `esphome::button::ButtonPressTrigger::ButtonPressTrigger(esphome::button::Button*)':
/config/esphome/.esphome/build/airco-denn/src/esphome/components/button/automation.h:23: undefined reference to `esphome::button::Button::add_on_press_callback(std::function<void ()>&&)'
/data/cache/platformio/packages/[email protected]+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /data/airco-denn/.pioenvs/airco-denn/src/main.o: in function `std::function<esphome::haier::AirflowVerticalDirection (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int)>::~function()':
/data/cache/platformio/packages/[email protected]+2021r2-patch5/xtensa-esp32-elf/include/c++/8.4.0/bits/std_function.h:370: undefined reference to `esphome::template_::TemplateTextSensor::set_template(std::function<esphome::optional<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > ()>&&)'
/data/cache/platformio/packages/[email protected]+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /data/airco-denn/.pioenvs/airco-denn/src/esphome/core/controller.o:(.literal._ZN7esphome10Controller16setup_controllerEb+0x28): undefined reference to `esphome::text_sensor::TextSensor::add_on_state_callback(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)>)'
/data/cache/platformio/packages/[email protected]+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /data/airco-denn/.pioenvs/airco-denn/src/esphome/core/controller.o: in function `esphome::Controller::setup_controller(bool)':
/config/esphome/.esphome/build/airco-denn/src/esphome/core/controller.cpp:47: undefined reference to `esphome::text_sensor::TextSensor::add_on_state_callback(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)>)'
collect2: error: ld returned 1 exit status
*** [/data/airco-denn/.pioenvs/airco-denn/firmware.elf] Error 1
========================= [FAILED] Took 65.63 seconds =========================

I have 1 unit haier-smartair2-base that one is working with the new dev version.
the other 3 units with haier-hon-base not,

Hi, I checked. It is working fine for me with the latest ESPHome. To reproduce your situation I need your full configuration including all changes that you made to all files. No need for passwords, MACs or IPs :smiley:
Looks like you have some button that is not working anymore because I changed some interfaces.

substitutions:
  device_name: Airco Denn
  uart_id: ac_denn
  device_id: denn_climate
  send_wifi: "true"

esphome:
  name: airco-denn

esp32:
  board: esp32dev
  framework:
    type: esp-idf
    sdkconfig_options:
      CONFIG_FREERTOS_UNICORE: y

wifi:
  ssid: xxx
  password: xxx

uart:
  baud_rate: 9600
  tx_pin: 17
  rx_pin: 16
  id: ${uart_id}  

logger:
  level: DEBUG

<<: !include .haier-hon-base.yaml

This is al, the rest are your files from the dev branch.

If you didn’t change other files this should work. I have seen a problem with cleaning old sources from previous build a couple of times. Try to delete “.esphome” folder and build again.

1 Like

Thanks it’s working!

Can some one advice please.
Used previosly for my smartAir2 aircon this repo

and for hOn Flexis aircon

Now, as I understand - Haier climate is included in ESPhome as well and I receive “deprecated” in log’s when updating my d1_mini dongles.

Should I copy the new repo to my ESPhome folder to use “native” implementation?

Or it’s just enogh to change my .yaml for all havacs? Like this? because with this yaml i still get “deprecated” in logs…

esphome:
  name: haier-guestroom
esp8266:
    board: d1_mini

logger:
  level: DEBUG
  baud_rate: 0 #Important. You can't use serial port
  
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  #important, otherwise the IP could change and then the entity is unavailable from home assistant.
  manual_ip:
    static_ip: 10.10.20.10
    gateway: 10.10.20.1
    subnet: 255.255.255.0

# Enable Home Assistant API
api:

ota:

uart:
  baud_rate: 9600
  tx_pin: 1
  rx_pin: 3
  id: ac_port

climate:
  - platform: haier
    id: haier_guestroom
    name: Haier Guestroom
    uart_id: ac_port
    visual:                     # Optional, you can use it to limit min and max temperatures in UI (not working for remote!)
      min_temperature: 16 °C
      max_temperature: 30 °C
      temperature_step: 0.5 °C

Let me go step by step.
If I am not mistaken you get deprecated logs because of using away in climate implementation. It starts happening in new ESPhome versions and should be fixed in climate implementation. So switching to another component will not help you to get rid of these warnings.
Now about the component: first of all my implementation of Haier climate is not an official ESPhome Haier implementation. I am working on this but it looks like it will not happen soon. Official Haier component supports only smartAir2 ACs so for your hOn you will need a separate component. Or you can use my component (which supports both hOn and smartAir2)

1 Like

Thank you, seems you answered my question even I didn’t knew i had to ask )
Seems just like you described, yes.

@paveldn , just installed your repository and it worked fantastic. I was using a fork of Miguel’s code to work with my Mabe branded (Mexico division of Haier) using smartair2. My only issue is that under ESPHome, it always shows as offline. I can click logs and it will connect and show me that the ESP8266 and the AC are talking to each other, and the thermostat card in HA works and my google integration sees it and I can turn it off and on by voice, so not sure why it shows as offline.

Edit: I have gone into the ESPHome configuration and changed it to “Use Ping for status” and it sees it now, but I guess something changed to keep mDNS from working on it.

external_components:
  - source:
      type: git
      url: https://github.com/paveldn/haier-esphome
    components: [haier]

substitutions:
  device_name: master-ac
  device_id: haier_climate
  uart_id: ac_port 
  send_wifi: "true"

esphome:
  name: master-ac
  name_add_mac_suffix: true

esp8266:
  board: d1_mini


# Enable Home Assistant API
api:
  

ota:
  password: "xxxxxxxxxxxxxxxxxxx"

wifi:
  ssid: wifi_network
  password: password
  manual_ip:
    static_ip: 192.168.xxx.xxx
    gateway: 192.168.xxx.xxx
    subnet: 255.255.255.0

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Master-Ac Fallback Hotspot"
    password: "xxxxxxx"

uart:
  baud_rate: 9600
  tx_pin: 1
  rx_pin: 3
  id: ${uart_id} 

logger:
  level: DEBUG
  baud_rate: 0

<<: !include .haier-smartair2-base.yaml

Hi. Thanks for the review nice to hear that it works for your case.

Yes, usually it is DNS problem. But in case you have static IP in the config file it should work (at least it is worked for me)

1 Like