Adding custom climate component for an AC unit working with the RAR-2P2 remote

Hello people.

I am trying to make my AC to work by adding a custom component as Hitachi ac264 is not officially supported by ESPhome. I am using the IRremoteESP8266 library for this v.2.8.6 which adds ac264 support.

The issue I am facing is that the device does not seem to work as a climate device. There are a couple switches in the code you will see that call for raw commands, and these work fine but if I try to control it as climate nothing is happening. By nothing I mean the remote sends a command but the AC unit does not respond at all. The custom climate component that you will see was not written by me but from a developer that I spoke to and of course he’s facing the same issues. I have limited experience in coding but by looking at the custom component and the corresponding library (ir_Hitachi.h) it should have been working. I was hoping someone more experienced than me would help me. Thank you!

This is the yaml

esphome:
  name: "bedroom-ac"
  friendly_name: Bedroom AC
  libraries:
    - crankyoldgit/IRremoteESP8266@^2.8.2
  includes:
    - custom_bedroom-ac.h

esp8266:
  board: esp01_1m

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "+v6LdieqhWu8x5fSd49j+32PXD8Nkj0CA+xnDf58Ew4="

ota:


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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esphome-Web-Be5584"
    password: "nphO0dE4bupx"

captive_portal:

# Configure the IR receiver. Handy to pickup confirmation messages
# from your AC (or capture commands from the actual remote)
remote_receiver:
  id: rcvr
  pin: 
    number: GPIO2 #checked
    inverted: True
  dump: all

# Configure the IR LED: this one sends commands to other devices
remote_transmitter:
  pin: GPIO0 #checked
  carrier_duty_percent: 50%

switch:
  - platform: template
    name: Turn On A/C
    turn_on_action:
      - remote_transmitter.transmit_raw:
          carrier_frequency: 38kHz
          # Hitachi AC 24C FanLow SwingOff
          code: [3442, -1657, 440, -1260, 440, -410, 439, -410, 464, -386, 440, -409, 440, -412, 438, -410, 440, -409, 467, -383, 444, -406, 466, -383, 441, -409, 465, -1235, 439, -410, 464, -386, 440, -410, 463, -387, 463, -385, 465, -385, 465, -385, 443, -407, 440, -410, 439, -410, 465, -384, 465, -385, 440, -410, 440, -410, 439, -411, 439, -410, 440, -410, 440, -1259, 441, -409, 440, -1259, 441, -1258, 443, -1257, 439, -1261, 443, -1255, 441, -1259, 466, -383, 440, -1260, 440, -1259, 440, -1259, 445, -1255, 440, -1260, 438, -1260, 440, -1259, 440, -1260, 465, -1235, 444, -405, 465, -385, 440, -409, 465, -385, 439, -411, 439, -410, 440, -410, 465, -384, 465, -385, 441, -412, 437, -1262, 438, -1259, 440, -410, 439, -410, 464, -1235, 440, -1259, 440, -1260, 441, -1258, 441, -409, 463, -386, 466, -1234, 463, -1237, 440, -409, 441, -408, 440, -414, 460, -1236, 439, -410, 441, -410, 439, -1259, 442, -408, 466, -384, 466, -1233, 441, -1259, 440, -411, 463, -1235, 441, -1257, 442, -408, 465, -1235, 441, -1258, 464, -385, 441, -1259, 440, -1260, 442, -407, 441, -409, 440, -1259, 440, -410, 464, -385, 466, -384, 468, -382, 466, -383, 465, -1235, 466, -1232, 466, -385, 442, -1257, 466, -1233, 466, -1234, 439, -411, 439, -410, 464, -386, 467, -385, 463, -384, 465, -1235, 440, -1259, 439, -411, 464, -1235, 439, -1260, 440, -1260, 466, -1236, 440, -1257, 440, -409, 464, -385, 441, -1259, 441, -409, 440, -410, 439, -412, 439, -409, 440, -409, 465, -385, 466, -388, 436, -410, 439, -1259, 441, -1259, 465, -1235, 439, -1260, 441, -1258, 465, -1235, 439, -1260, 440, -1259, 442, -408, 468, -381, 441, -409, 465, -385, 439, -411, 440, -409, 440, -410, 444, -406, 441, -1262, 436, -1261, 440, -1258, 439, -1260, 441, -1258, 442, -1258, 440, -1260, 439, -1259, 440, -410, 440, -410, 440, -410, 439, -410, 466, -383, 440, -411, 441, -408, 440, -411, 439, -1259, 466, -1233, 465, -1235, 440, -1262, 438, -1258, 487, -1212, 467, -1233, 440, -1260, 440, -409, 440, -410, 440, -409, 441, -409, 465, -385, 464, -385, 442, -410, 464, -383, 442, -1258, 465, -1234, 442, -1257, 465, -1235, 440, -1259, 441, -1258, 466, -1234, 444, -1255, 465, -386, 438, -411, 464, -387, 463, -385, 464, -386, 465, -385, 440, -410, 465, -385, 439, -1259, 441, -1259, 440, -1259, 464, -1235, 440, -1260, 438, -1261, 466, -1233, 440, -1260, 439, -1260, 441, -1258, 440, -410, 464, -386, 464, -1235, 465, -384, 465, -385, 442, -408, 441, -409, 439, -411, 439, -1260, 464, -1235, 465, -384, 441, -1259, 440, -1260, 440, -1258, 466, -1238, 437, -408, 467, -383, 465, -385, 443, -1256, 465, -384, 465, -1235, 443, -1256, 465, -385, 464, -1236, 442, -1258, 438, -1261, 438, -411, 465, -1234, 466, -388, 462, -383, 466, -1234, 443, -407, 445, -1254, 465, -384, 442, -409, 438, -410, 466, -385, 441, -409, 440, -409, 464, -1235, 440, -410, 440, -1259, 440, -1260, 441, -1258, 440, -1260, 439, -1260, 469, -1230, 440, -410, 465, -385, 440, -1258, 442, -409, 440, -411, 438, -410, 440, -409, 441, -410, 440, -1258, 465, -1235, 465, -385, 440, -1258, 441, -1259, 466, -1237, 437, -1259, 465]


  - platform: template
    name: Turn Off A/C
    turn_on_action:
      - remote_transmitter.transmit_raw:
          carrier_frequency: 38kHz
          # Hitachi AC TurnOff: 
          code: [3438, -1658, 442, -1259, 439, -410, 465, -385, 440, -409, 466, -384, 440, -410, 440, -409, 465, -384, 467, -383, 466, -384, 441, -409, 441, -409, 439, -1260, 465, -384, 466, -384, 465, -384, 441, -410, 440, -409, 440, -410, 466, -384, 441, -408, 441, -409, 465, -384, 447, -403, 441, -409, 440, -409, 454, -400, 462, -385, 465, -383, 466, -384, 439, -1261, 463, -386, 465, -1234, 441, -1259, 448, -1251, 440, -1261, 439, -1259, 440, -1260, 440, -410, 463, -1236, 439, -1260, 465, -1234, 465, -1234, 441, -1260, 439, -1259, 440, -1260, 464, -1235, 441, -1258, 465, -386, 440, -408, 466, -385, 439, -410, 466, -384, 440, -410, 439, -409, 466, -385, 464, -385, 440, -409, 441, -1259, 440, -1259, 439, -412, 465, -384, 466, -1233, 465, -1234, 465, -1235, 466, -1233, 440, -410, 466, -383, 442, -1258, 441, -1259, 464, -385, 466, -384, 464, -386, 440, -1259, 440, -410, 440, -410, 464, -1234, 467, -383, 440, -410, 465, -1234, 466, -1234, 439, -411, 464, -1235, 439, -1260, 465, -385, 443, -1256, 465, -1234, 464, -386, 439, -1261, 470, -1230, 439, -410, 440, -409, 466, -1233, 466, -384, 440, -410, 465, -385, 440, -409, 466, -389, 436, -1258, 466, -1233, 440, -410, 440, -1261, 439, -1260, 439, -1260, 440, -409, 441, -409, 464, -385, 441, -409, 440, -410, 439, -1260, 464, -1235, 465, -385, 464, -1236, 458, -1241, 441, -1259, 440, -1259, 440, -1259, 441, -409, 442, -407, 466, -1234, 439, -411, 466, -383, 466, -384, 465, -384, 442, -408, 440, -410, 464, -386, 465, -384, 442, -1258, 465, -1234, 440, -1259, 465, -1234, 440, -1260, 441, -1259, 440, -1259, 441, -1258, 440, -410, 465, -384, 441, -409, 440, -410, 467, -384, 463, -385, 441, -410, 439, -410, 440, -1259, 441, -1259, 465, -1234, 441, -1262, 440, -1255, 466, -1233, 466, -1234, 440, -1260, 440, -412, 462, -385, 440, -409, 464, -386, 442, -408, 465, -385, 464, -385, 440, -411, 439, -1259, 465, -1235, 440, -1259, 468, -1231, 440, -1261, 439, -1260, 442, -1256, 440, -1259, 441, -410, 445, -406, 464, -384, 464, -385, 466, -384, 441, -409, 440, -409, 440, -411, 463, -1235, 441, -1263, 461, -1234, 465, -1235, 440, -1260, 439, -1260, 440, -1259, 464, -1235, 466, -384, 465, -385, 441, -408, 466, -384, 440, -410, 464, -385, 441, -413, 435, -411, 440, -1259, 440, -1260, 440, -1259, 440, -1262, 436, -1261, 440, -1258, 441, -1259, 440, -1259, 464, -1235, 456, -1249, 439, -406, 465, -385, 464, -1235, 440, -410, 440, -410, 439, -411, 441, -408, 465, -384, 440, -1260, 465, -1234, 464, -386, 466, -1233, 440, -1260, 464, -1234, 442, -1258, 465, -385, 440, -410, 439, -410, 439, -411, 439, -410, 441, -1260, 467, -1231, 468, -382, 440, -1259, 440, -1260, 464, -1235, 466, -1233, 468, -1231, 442, -409, 464, -385, 465, -1234, 441, -410, 464, -1235, 440, -410, 441, -408, 466, -383, 441, -410, 465, -385, 440, -409, 464, -1235, 465, -385, 440, -1259, 440, -1259, 465, -1235, 441, -1258, 440, -1260, 440, -1259, 440, -409, 463, -388, 438, -1260, 466, -384, 469, -381, 466, -383, 467, -383, 465, -385, 453, -1246, 465, -1235, 441, -408, 440, -1259, 466, -1234, 465, -1234, 441, -1259, 440]
climate:
  - platform: custom
    lambda: |-
      auto my_hitachiac = new HitachiAC();
      App.register_component(my_hitachiac);
      return {my_hitachiac};

    climates:
      - name: "Hitachi AC"

and this is the custom component (custom_bedroom-ac.h)

#include "esphome.h"
#include "IRremoteESP8266.h"
#include "IRsend.h"
#include "ir_Hitachi.h"

///This code is relevant for cases where the IR control for an AC is available in IRremoteESP8266, but isn't supported yet in Esphome

const uint16_t kIrLed = 0;  // ESP8266 GPIO pin to use. Recommended: 0 (D3).
const bool inverted = false;
const bool use_modulation = true;
IRHitachiAc264 ac(kIrLed, inverted, use_modulation);



// Setup files. This is the equivalent of the code written in the setup loop of Arduino
class HitachiAC : public Component, public Climate { public: void setup() override {
    // Setup pins etc
    ac.begin();
    // AC model. This is only relevant in cases where the ir_company.h requires a model (i.e. the signals change by model)
    // ac.setModel(R_LT0541_HTA_A);
    delay(200);
    // Setting up base conditions, so that the system doesn't send garbage to begin with
    ac.setTemp(24);
    ac.setFan(kHitachiAc264FanAuto);
    // ac.setSwingV(true);
    ac.off();
    // Setting up base conditions transferred to Home Assistant, so that there's no garbage at initialization
    this->mode = mode;
    this->fan_mode = CLIMATE_FAN_AUTO;
    this->swing_mode = CLIMATE_SWING_VERTICAL;
    this->target_temperature = 24;
    this->publish_state();
  }

  // Traits: This tells home assistant what "traits" are supported by AC in terms of heating/cooling/fan speeds/swing modes. These are used by Home Assistant to customize the AC card on your dashboard
  climate::ClimateTraits traits() {
    auto traits = climate::ClimateTraits();
    traits.set_supports_current_temperature(false);
    traits.set_supports_two_point_target_temperature(false);

    traits.set_supported_modes({
      climate::CLIMATE_MODE_OFF,
      climate::CLIMATE_MODE_HEAT,
      climate::CLIMATE_MODE_DRY,
      climate::CLIMATE_MODE_COOL,
      climate::CLIMATE_MODE_FAN_ONLY,
      //Adding this leads to esphome data not showing on Home Assistant somehow, hence skipping. Others please try and let me know
    });

    traits.set_supported_fan_modes({
      climate::CLIMATE_FAN_AUTO,
      climate::CLIMATE_FAN_LOW,
      climate::CLIMATE_FAN_MEDIUM,
      climate::CLIMATE_FAN_HIGH,
      });

    traits.set_supported_swing_modes({
      climate::CLIMATE_SWING_OFF,
      climate::CLIMATE_SWING_VERTICAL,
    });

    traits.set_visual_min_temperature(16);
    traits.set_visual_max_temperature(30);
    traits.set_visual_temperature_step(1);
    return traits;
  }

  //Code for what to do when the mode of the AC is changed on the dashboard
  void control(const ClimateCall &call) override {
    if (call.get_mode().has_value()) {
      // User requested mode change
      ClimateMode mode = *call.get_mode();
      // Send mode to hardware
      //You need an condition of each of the supported modes mentioned in the traits section above
      //For each mode, you need to find the relevant mode from the list of constants. This list can be found in the relevant .h library from IRremoteESP8266 library. In this case the file is "ir_Hitachi.h". Typically the function should be the same - .setMode. However, best check the relevant .h library. 

      if (mode == CLIMATE_MODE_OFF) {
        ac.off();
      } else if (mode == CLIMATE_MODE_HEAT) {
        ac.on();
        ac.setMode(kHitachiAc264Heat);
      } else if (mode == CLIMATE_MODE_DRY) {
        ac.on();
        ac.setMode(kHitachiAc264Dry);
      } else if (mode == CLIMATE_MODE_COOL) {
        ac.on();
        ac.setMode(kHitachiAc264Cool);
      } else if (mode == CLIMATE_MODE_FAN_ONLY) {
        ac.on();
        ac.setMode(kHitachiAc264Fan);
      }

      // Publish updated state
      this->mode = mode;
      this->publish_state();
    }

    //Code for what to do when the fan speed / mode is changed on the dashboard
    if (call.get_fan_mode().has_value()) {
      // User requested fan mode change
      ClimateFanMode fan_mode = *call.get_fan_mode();
      // Send fan mode to hardware
      if (fan_mode == CLIMATE_FAN_AUTO) {
        ac.setFan(kHitachiAc264FanAuto);
      } else if (fan_mode == CLIMATE_FAN_LOW) {
        ac.setFan(kHitachiAc264FanMin);
      } else if (fan_mode == CLIMATE_FAN_MEDIUM) {
        ac.setFan(kHitachiAc264FanMedium);
      } else if (fan_mode == CLIMATE_FAN_HIGH) {
        ac.setFan(kHitachiAc264FanHigh);
      }

      this->fan_mode = fan_mode;
      this->publish_state();
    }

    //Code for what to do when the swing mode is changed on the dashboard
    //Check what function is available in the relevant .h file. For example, .setSwingV is the relevant function in ir_Hitachi.h, but it is .setSwingVertical in some others
    if (call.get_swing_mode().has_value()) {
      // User requested fan mode change
      ClimateSwingMode swing_mode = *call.get_swing_mode();
      // Send fan mode to hardware
      if (swing_mode == CLIMATE_SWING_OFF) {
        ac.setSwingVToggle(false);
      } else if (swing_mode == CLIMATE_SWING_VERTICAL) {
        ac.setSwingVToggle(true);
      }

      this->swing_mode = swing_mode;
      this->publish_state();
    }

    //Code for what to do when the temperature is changed on the dashboard
    if (call.get_target_temperature().has_value()) {
      // User requested target temperature change
      float temp = *call.get_target_temperature();
      // Send target temp to climate
      ac.setTemp(temp);

      this->target_temperature = temp;
      this->publish_state();
    }

  //Send the IR code you've built basis all the above data
  ac.send();
  #if DEBUG_AC
  ESP_LOGD("DEBUG", "Home A/C remote is in the following state:");
  ESP_LOGD("DEBUG", "%s\n", ac.toString().c_str());
  #endif // DEBUG_AC
  }
};

Have you tried to use the Hitachi support in ESPHome ? because even if it’s not exact model it’s often similar codes and so it might work :wink:
Also what ESP module are you using for sending the IR codes ?

Yes, I’ve tried both hitachi_ac344 and hitachi_ac424, they are not working. There is also nothing wrong with the device itself as when using the daikin profile it can control my daikin without issues.

I am using a Lolin D1 mini with its official IR shield.

1 Like

Hi, none of the daikin esphome climate works for my daikin ac. Tasmota-ir does list the daikin64 protocol which works when using with irhvac

I was wondering if I could just use custom_bedroom-ac file and how do I edit it with daikin64 protocol?