Aircon International / Hisense Mini Split Control

First let me mention that while I have put Hisense in the title of this post, I make no guarantees that this will work with any Hisense unit without modifying the code. In fact, I strongly suspect that the reply message structure would need to be modified to work with a Hisense unit. Luckily there are several examples of the Hisense compatible message structure in the references included in the readme file.

Backstory:

I purchased a AirCon International 18000BTU mini split for my garage in July of 2022. When I purchased it on amazon it said it was Wi-Fi compatible. After receiving the unit I found out that the only officially supported method of interfacing with the unit was a glorified IR blaster (yuck!) I had a lot of projects come up so I didn’t try and hack this thing until just a few weeks ago.

I’ve been successful at interfacing with the AC (mostly) and I’ve got it integrated in my HA setup now through ESPHome. This integration is still a little rough around the edges, but it works fully for controlling the AC and displays status info with only the occasional error. Most of those errors are related to less important things like outdoor unit temps, compressor speed, etc. It seems like some of the display errors may come from the unit itself reporting bad info.

As I mentioned, my unit is branded and distributed by Air-Con International I found when integrating with this AC that the protocol differs slightly from what others have posted about Hisense units. Notably there are extra bytes in the header of received messages, and the bit endianness is different for status items in the messages.

Hardware:

I’m using an ESP-12F (8266) with a serial to 485 adapter board and a generic adjustable DC-DC converter. I’ll assume that if you’re even thinking of replicating my results you’re well capable of finding the necessary components on Amazon. Given how cheap PCBs are these days I may just spin a ESP-12F carrier board that can plug directly into the AC connector.

The pinout of the connector is:

  1. (Black wire) GND

  2. B-

  3. A+

  4. (Red wire) +5V

YAML config to-do / needs improvement:

  • The way I’ve integrated several of the extraneous parameters as sensors is probably not the preferred method (though it does work).

  • The filtering I’ve put on several of the sensor values is a hack to try and get rid of erroneous values. It doesn’t work. A bgetter solution would be to get rid of the erroneous values in the first place.

C++ code to-do / needs improvement:

  • Generate command messages rather than storing each command as an array.

  • Improve reply handling to process all types of messages. The header tells what kind of reply message has been sent, and how long it is (supposedly).

  • Make reply processing asynchronous? A lot of time is spent spin waiting. Replies come a long time after the request is sent (~150ms ) right now the code waits before even checking for a reply.

  • Handle power usage message. It would be interesting to see the power draw from the unit in real time. That said, I’m not sure the Hisense unit even supports that feature. Every time I requested the message I got the same reply back.

  • Add configuration item to support switching between Hisense packet mode and “AirCon” packet mode.

I probably forgot some details, so if there are any questions feel free to reply here and I’ll respond when I’m able to.

Hello!
This is great news.
Unfortunately, I was unable to replicate your experience.
I unsubscribed to git
Thanks for your hard work! I hope there will be a simple and affordable solution on ESP for these air conditioning units

I have the same unit (probably, looks the same, anyway) and this seems to be working great so far. Thank you for saving me from IR blaster hell!

No problem. I definitely didn’t want to do the IR blaster myself.

Any chance to make it work with a d1 mini?

I see no reason why it shouldn’t be able to work.

Hello,

I’m not that into programming but what do you mean with reply message structure ?
I would like to have it work on my Hisense airconditioner but i’m not that experienced in programming.

Regards Jan

You will have to modify the code to make it work with a Hisense unit. I linked to sources that include the message structure used by Hisense. I don’t have access to such a unit to do any testing so you’d be on your own.

I’m super keen to try this out. I’m currently researching what hardware to get. I’m in need of a bit of help.

I’d like to get an easy plug-n-play solution such as the M5 Atom Lite. Am I correct in thinking that I could get the ATOM Tail485 - RS485 Converter and then plug some jumper leads from the Tail485 into the AC? I have a Hisense and feel confident enough that I could modify the source code to make it work. It’s just the hardware side of things that I feel I need the most help.

Also has the plug type that the Wifi controllers use been determined? Perhaps I could buy the plug and crimp it in, that way it’s even more polished. It looks like it’s some type of 4 pin JST plug.
This cable looks very similar: 4-pin JST SM Plug + Receptacle Cable Set : ID 578 : Adafruit Industries, Unique & fun DIY electronics and kits
I have a AEH-W4G2 and the 4 pin plug does seem to have a pitch of 2.5mm. So I reckon it is the 4-pin JST SM Plug.

I managed to partially control my Hisense AC. I can confirm the Hisense AC definitely uses 4-pin JST SM plugs. Coincidentially I realised I could just use Dupont cables as they line up perfectly.

I used a multi-meter and the AC Wifi JSM port only outputs 4.8V. I wasn’t able to use it to power my 5V ESP32 device. For now I’ve just plugged it into power via USB-C. Then plugged two leads into RX and TX.

AC port pinout when looking at it straight on. Pins from top to bottom.
1-TX
2-GND
3-RX
4-5V

I can turn it on and off and change modes. The temperature keeps going from C to F. However it doesn’t report its status so it’s not very usable. Sensor values are also way off.

I also found a discussion where someone managed to get it all working with different code. It looks super promising, however the ESPHome .yaml code link expired.
Please help ) How to build your project with my config? · Issue #1 · straga/scrivo_project (github.com)

Below is my current ESPHome yaml.

esphome:
  name: hisense-ac
  friendly_name: Hisense AC
  includes:
    - aircon_climate.h

  project:
    name: esphome.hisense-ac
    version: "Hisense-Model"
  platform: ESP32
  board: m5stack-atom

uart:
  id: uart_bus
  tx_pin: 21
  rx_pin: 25
  baud_rate: 9600
  debug:
    direction: BOTH
    dummy_receiver: false
    sequence:
      - lambda: UARTDebug::log_hex(direction, bytes, ',');

logger:
  level: VERBOSE
  logs:
    aircon_climate: INFO
  # ESP8266 only - disable serial port logging, as the HeatPump component
  # needs the sole hardware UART on the ESP8266
  #baud_rate: 0


# Enable Home Assistant API
api:

ota:

web_server:
  port: 80

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:

captive_portal:

globals:
  - id: compressor_frequency
    type: Sensor*
  - id: compressor_frequency_setting
    type: Sensor*
  - id: compressor_frequency_send
    type: Sensor*
  - id: outdoor_temperature
    type: Sensor*
  - id: outdoor_condenser_temperature
    type: Sensor*
  - id: compressor_exhaust_temperature
    type: Sensor*
  - id: target_exhaust_temperature
    type: Sensor*
  - id: indoor_pipe_temperature
    type: Sensor*
  - id: indoor_humidity_setting
    type: Sensor*
  - id: indoor_humidity_status
    type: Sensor*

button:
  - platform: uart
    name: "UART Bytes Output - Display Off"
    data: [0xF4, 0xF5, 0x00, 0x40, 0x29, 0x00, 0x00, 0x01, 0x01, 0xFE, 0x01,
          0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
          0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
          0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
          0x00, 0x00, 0x02, 0x13, 0xF4, 0xFB]

  - platform: uart
    name: "UART Bytes Output - Display On"
    data: [0xF4, 0xF5, 0x00, 0x40, 0x29, 0x00, 0x00, 0x01, 0x01, 0xFE, 0x01,
          0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
          0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
          0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
          0x00, 0x00, 0x02, 0x93, 0xF4, 0xFB]

climate:
- platform: custom
  id: my_climate
  lambda: |-
    auto aircon_climate = new AirconClimate(id(uart_bus));
    App.register_component(aircon_climate);
    id(compressor_frequency) = &aircon_climate->compressor_frequency;
    id(compressor_frequency_setting) = &aircon_climate->compressor_frequency_setting;
    id(compressor_frequency_send) = &aircon_climate->compressor_frequency_send;
    id(outdoor_temperature) = &aircon_climate->outdoor_temperature;
    id(outdoor_condenser_temperature) = &aircon_climate->outdoor_condenser_temperature;
    id(compressor_exhaust_temperature) = &aircon_climate->compressor_exhaust_temperature;
    id(target_exhaust_temperature) = &aircon_climate->target_exhaust_temperature;
    id(indoor_pipe_temperature) = &aircon_climate->indoor_pipe_temperature;
    id(indoor_humidity_setting) = &aircon_climate->indoor_humidity_setting;
    id(indoor_humidity_status) = &aircon_climate->indoor_humidity_status;
    return {aircon_climate};
  climates:
    - name: "Aircon Climate"

sensor:
- platform: custom
  lambda: |-
    return {
      id(compressor_frequency),
      id(compressor_frequency_setting),
      id(compressor_frequency_send),
      id(outdoor_temperature),
      id(outdoor_condenser_temperature),
      id(compressor_exhaust_temperature),
      id(target_exhaust_temperature),
      id(indoor_pipe_temperature),
      id(indoor_humidity_setting),
      id(indoor_humidity_status)
    };
  sensors:
  - name: "Compressor Frequency"
    unit_of_measurement: "Hz"
    device_class: "frequency"
    state_class: "measurement"
  - name: "Compressor Frequency Setting"
    unit_of_measurement: "Hz"
    device_class: "frequency"
    state_class: "measurement"
  - name: "Compressor Frequency Send"
    unit_of_measurement: "Hz"
    device_class: "frequency"
    state_class: "measurement"
  - name: "Outdoor Temperature"
    unit_of_measurement: "°C"
    icon: "mdi:thermometer"
    device_class: "temperature"
    state_class: "measurement"
  - name: "Outdoor Condenser Temperature"
    unit_of_measurement: "°C"
    icon: "mdi:thermometer"
    device_class: "temperature"
    state_class: "measurement"
  - name: "Compressor Exhaust Temperature"
    unit_of_measurement: "°C"
    icon: "mdi:thermometer"
    device_class: "temperature"
    state_class: "measurement"
  - name: "Target Exhaust Temperature"
    unit_of_measurement: "°C"
    icon: "mdi:thermometer"
    device_class: "temperature"
    state_class: "measurement"
  - name: "Indoor Evaporator Inlet Temperature"
    unit_of_measurement: "°C"
    icon: "mdi:thermometer"
    device_class: "temperature"
    state_class: "measurement"
  - name: "Indoor Humidity setting"
    unit_of_measurement: "%"
    icon: "mdi:water-percent"
    device_class: "humidity"
    state_class: "measurement"
  - name: "Indoor Humidity status"
    unit_of_measurement: "%"
    icon: "mdi:water-percent"
    device_class: "humidity"
    state_class: "measurement"