esphome / feature-requests

ESPHome Feature Request Tracker
https://esphome.io/
417 stars 26 forks source link

Support for Fujitsu ARDB1 remote #1797

Open tommybutts01 opened 2 years ago

tommybutts01 commented 2 years ago

Describe the problem you have/What new integration you would like Please add support for older Fujitsu, Model: AR-DB1 remote (ARDB1)

Please describe your use case for this integration and alternatives you've tried: Have tried current supported remotes to no avail, tested ARDB1 with IRremoteESP8266 project as working from https://github.com/crankyoldgit/IRremoteESP8266

Additional context Love this project :D just super keen to be able to use it with our older heatpump

tommybutts01 commented 1 year ago

Ive still been digging into this and it looks like it is loading the right library, which ive tested as working as a standalone

if CORE.is_esp8266 or CORE.is_esp32: cg.add_library("crankyoldgit/IRremoteESP8266", "2.7.12")

Which has: case fujitsu_ac_remote_model_t::ARDB1:

and parameters for sending the right code, not sure how to get the heatpumpir module to be able to call from that library correctly

tommybutts01 commented 1 year ago

Still plugging away, have managed to get this far, but still seems the signals are wrong

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

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

class FujitsuAC : public Component, public Climate { public: void setup() override {
    // Setup pins etc
    ac.begin();
    delay(200);
    ac.on();
    // 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(ARDB1);
    delay(200);
    // Setting up base conditions, so that the system doesn't send garbage to begin with
    ac.setTemp(24);
    ac.setFanSpeed(kFujitsuAcFanAuto);
    ac.on();
    // 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_COOL,
      climate::CLIMATE_MODE_DRY,
      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(kFujitsuAcModeHeat);
      } else if (mode == CLIMATE_MODE_DRY) {
        ac.on();
        ac.setMode(kFujitsuAcModeDry);
      } else if (mode == CLIMATE_MODE_COOL) {
        ac.on();
        ac.setMode(kFujitsuAcModeCool);
      } else if (mode == CLIMATE_MODE_FAN_ONLY) {
        ac.on();
        ac.setMode(kFujitsuAcModeFan);
      }

      // 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.setFanSpeed(kFujitsuAcFanAuto);
      } else if (fan_mode == CLIMATE_FAN_LOW) {
        ac.setFanSpeed(kFujitsuAcFanLow);
      } else if (fan_mode == CLIMATE_FAN_MEDIUM) {
        ac.setFanSpeed(kFujitsuAcFanMed);
      } else if (fan_mode == CLIMATE_FAN_HIGH) {
        ac.setFanSpeed(kFujitsuAcFanHigh);
      }

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

    //Code for what to do when the swing mode is changed on the dashboard
    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.setSwing(false);
      } else if (swing_mode == CLIMATE_SWING_VERTICAL) {
        ac.setSwing(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
  }
};

and yaml

climate:
- platform: custom
  lambda: |-
    auto fujitsuac = new FujitsuAC();
    App.register_component(fujitsuac);
    return {fujitsuac};
  climates:
    - name: "Lounge Heatpump"