ESPHome updating AC units after platform deprecation

Hi all,

I noticed my AC’s didn’t update in ESPHome, I checked the error and found this:


I changed the yaml configuration to:

esphome:
  name: badkamer-airco #name: mhi-woonkamer  # Unique name  (only change in small letters)
  platformio_options:
    # Run CPU at 160Mhz to fix mhi_ac_ctrl_core.loop error: -2
    board_build.f_cpu: 160000000L
  includes:
    - mhi_ac_ctrl.h
    - MHI-AC-Ctrl-core.h
    - MHI-AC-Ctrl-core.cpp
esp8266:
  board: d1_mini
  framework:
    version: recommended

But now this is marked red:

climate:
  - platform: custom
    lambda: |-
      auto mhi_ac_ctrl = new MhiAcCtrl();
      App.register_component(mhi_ac_ctrl);
      return {mhi_ac_ctrl};

    climates:
      - name: "${devicename}"
        id: ${deviceid}

Apparently I’m using a custom component named mhi_ac_ctrl and a quick google search turned up some repos for this. one is a pure custom component (no longer supported) while another has an external component I should be able to use, instead: GitHub - ginkage/MHI-AC-Ctrl-ESPHome: ESPHome integration for MHI-AC-Ctrl project

Since the custom climate platform is no longer usable I need to switch to the external components for this. But I rarely use ESPHome besides for my AC units and now I’m not sure how to edit my yaml files. I don’t want to break anything, hence why I’m creating this post.

Here is my complete yaml file for 1 AC:

substitutions:
  # Unique device ID in HA
  deviceid: "badkamer_airco" #deviceid: "mhi_woonkamer"
  # Unique device name in HA (sensor names will be prefixed by this name)
  devicename: "Badkamer airco" #devicename: "MHI-Woonkamer"

esphome:
  name: badkamer-airco #name: mhi-woonkamer  # Unique name  (only change in small letters)
  platform: ESP8266
  board: d1_mini
  platformio_options:
    # Run CPU at 160Mhz to fix mhi_ac_ctrl_core.loop error: -2
    board_build.f_cpu: 160000000L
  includes:
    - mhi_ac_ctrl.h
    - MHI-AC-Ctrl-core.h
    - MHI-AC-Ctrl-core.cpp

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  #ssid: "hierjesidd"
  #password: "hierjeww"
  fast_connect: true  # misschien hier een hekje voor zetten?
  
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "${devicename}"
    password: "configesp"

captive_portal:

logger:
  level: DEBUG
  baud_rate: 0

globals:
  - id: room_temp_api_timeout
    type: int
    restore_value: no
    initial_value: '120'

ota:
- platform: esphome

web_server:
  port: 80

climate:
  - platform: custom
    lambda: |-
      auto mhi_ac_ctrl = new MhiAcCtrl();
      App.register_component(mhi_ac_ctrl);
      return {mhi_ac_ctrl};

    climates:
      - name: "${devicename}"
        id: ${deviceid}

api:
  reboot_timeout: 0s
  services:
    # Call the set_api_room_temperature service from HA to override the room temperature
    # If a new value has not been received after room_temp_api_timeout seconds, it will fall back to internal sensor
    - service: set_api_room_temperature
      variables:
        value: float
      then:
        - lambda: |-
            return ((MhiAcCtrl*)id(${deviceid}))->set_room_temperature(value);
    # Call the set_vanes service from HA to set the vane position
    # Needed because the ESPHome Climate class does not support this natively
    # Possible values: 1-4: static positions, 5: swing, 0: unknown
    - service: set_vanes
      variables:
        value: int
      then:
        - lambda: |-
            return ((MhiAcCtrl*)id(${deviceid}))->set_vanes(value);

sensor:
  - platform: wifi_signal # Reports the WiFi signal strength/RSSI in dB
    name: ${devicename} WiFi Signal db
    id: wifi_signal_db
    update_interval: 60s
    entity_category: diagnostic

  - platform: copy # Reports the WiFi signal strength in %
    source_id: wifi_signal_db
    name: ${devicename} WiFi Signal
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    unit_of_measurement: "%"
    entity_category: diagnostic

  - platform: uptime
    name: ${devicename} Uptime
    unit_of_measurement: days
    update_interval: 3600s
    accuracy_decimals: 1
    filters:
      - multiply: 0.000011574

  - platform: custom
    lambda: |-
      return ((MhiAcCtrl*)id(${deviceid}))->get_sensors();

    # Sensor names in HA, you can change these if you want
    # Don't delete them or change their position in the list
    sensors:
      - name: ${devicename} error code
      - name: ${devicename} outdoor temperature
      - name: ${devicename} return air temperature
      - name: ${devicename} outdoor unit fan speed
      - name: ${devicename} indoor unit fan speed
      - name: ${devicename} current power
      - name: ${devicename} compressor frequency
      - name: ${devicename} indoor unit total run time
      - name: ${devicename} compressor total run time
      - name: ${devicename} vanes
        id: vanes_UD_received
        on_value:
          then:
            - lambda: |-
                float received_value = id(vanes_UD_received).state;
                if (received_value == 1.0) {
                  id(fan_control_ud).publish_state("Up");
                } else if (received_value == 2.0) {
                  id(fan_control_ud).publish_state("Up/Center");
                } else if (received_value == 3.0) {
                  id(fan_control_ud).publish_state("Center/Down");
                } else if (received_value == 4.0) {
                  id(fan_control_ud).publish_state("Down");
                } else if (received_value == 5.0) {
                  id(fan_control_ud).publish_state("Swing");
                }

      - name: ${devicename} energy used
      - name: ${devicename} Indoor (U-bend) HE temp 1
      - name: ${devicename} Indoor (capillary) HE temp 2
      - name: ${devicename} Indoor (suction header) HE temp 3
      - name: ${devicename} Outdoor HE temp
      - name: ${devicename} Outdoor unit exp. valve
      - name: ${devicename} Outdoor unit discharge pipe
      - name: ${devicename} Outdoor unit discharge pipe super heat
      - name: ${devicename} Protection error state
      - name: ${devicename} Vanes Left Right
        id: vanes_LR_received
        on_value:
          then:
            - lambda: |-
                float received_value = id(vanes_LR_received).state;
                if (received_value == 1.0) {
                  id(fan_control_lr).publish_state("Left");
                } else if (received_value == 2.0) {
                  id(fan_control_lr).publish_state("Left/Center");
                } else if (received_value == 3.0) {
                  id(fan_control_lr).publish_state("Center");
                } else if (received_value == 4.0) {
                  id(fan_control_lr).publish_state("Center/Right");
                } else if (received_value == 5.0) {
                  id(fan_control_lr).publish_state("Right");
                } else if (received_value == 6.0) {
                  id(fan_control_lr).publish_state("Wide");
                } else if (received_value == 7.0) {
                  id(fan_control_lr).publish_state("Spot");
                } else if (received_value == 8.0) {
                  id(fan_control_lr).publish_state("Swing");
                }
      - name: ${devicename} 3D Auto
        id: Dauto_received
        on_value:
          then:
            - lambda: |-
                bool received_value = id(Dauto_received).state;
                if (received_value) {
                  ESP_LOGD("main", "received 3DAuto from AC");
                  id(fan_control_3Dauto).publish_state(true);
                }
                else {
                  ESP_LOGD("main", "received 3DAuto off from AC");
                  id(fan_control_3Dauto).publish_state(false);
                }

binary_sensor:
  - platform: custom
    lambda: |-
      return ((MhiAcCtrl*)id(${deviceid}))->get_binary_sensors();

    binary_sensors:
      - name: ${devicename} defrost

text_sensor:
  - platform: version
    name: ${devicename} ESPHome Version
  - platform: wifi_info
    ip_address:
      name: ${devicename} IP
    ssid:
      name: ${devicename} SSID
    bssid:
      name: ${devicename} BSSID
  - platform: custom
    lambda: |-
      return ((MhiAcCtrl*)id(${deviceid}))->get_text_sensors();

    text_sensors:
      - name: ${devicename} Protection error state

select:
  - platform: template
    name: ${devicename} Fan Control Left Right
    id: fan_control_lr
    icon: mdi:arrow-left-right
    optimistic: true
    options:
      # - "3D Auto"
      - "Left"
      - "Left/Center"
      - "Center"
      - "Center/Right"
      - "Right"
      - "Wide"
      - "Spot"
      - "Swing"
    on_value:
      - lambda: |-
          auto state = id(fan_control_lr).state.c_str();
          ESP_LOGD("main", "Option of my select: %s", state);
          uint8_t vanesLR = 0;  // Initialize the vanesLR variable
          if (id(fan_control_lr).state == "3D Auto") {
            id(fan_control_3Dauto).publish_state(true);
          } else if (id(fan_control_lr).state == "Left") {
            vanesLR = 1;
          } else if (id(fan_control_lr).state == "Left/Center") {
            vanesLR = 2;
          } else if (id(fan_control_lr).state == "Center") {
            vanesLR = 3;
          } else if (id(fan_control_lr).state == "Center/Right") {
            vanesLR = 4;
          } else if (id(fan_control_lr).state == "Right") {
            vanesLR = 5;
          } else if (id(fan_control_lr).state == "Wide") {
            vanesLR = 6;
          } else if (id(fan_control_lr).state == "Spot") {
            vanesLR = 7;
          } else if (id(fan_control_lr).state == "Swing") {
            vanesLR = 8;
          }
          if ((vanesLR > 0) & (vanesLR < 9) & (vanesLR != id(vanes_LR_received).state)){
            ESP_LOGD("main", "setting vanesLR to: %i", vanesLR);
            return ((MhiAcCtrl*)id(${deviceid}))->set_vanesLR(vanesLR);
          }
          else {
            ESP_LOGD("main", "Not setting vanesLR: %i", vanesLR);
          }

  - platform: template
    name: ${devicename} Fan Control Up Down
    id: fan_control_ud
    icon: mdi:arrow-up-down
    optimistic: true
    options:
      # - "3D Auto"
      - "Up"
      - "Up/Center"
      - "Center/Down"
      - "Down"
      - "Swing"
    on_value:
      - lambda: |-
          auto state = id(fan_control_lr).state.c_str();
          ESP_LOGD("main", "Option of my select: %s", state);
          uint8_t vanesUD = 0;  // Initialize the vanesUD variable
          if (id(fan_control_ud).state == "3D Auto") {
            id(fan_control_3Dauto).publish_state(true);
          } else if (id(fan_control_ud).state == "Up") {
            vanesUD = 1;
          } else if (id(fan_control_ud).state == "Up/Center") {
            vanesUD = 2;
          } else if (id(fan_control_ud).state == "Center/Down") {
            vanesUD = 3;
          } else if (id(fan_control_ud).state == "Down") {
            vanesUD = 4;
          } else if (id(fan_control_ud).state == "Swing") {
            vanesUD = 5;
          }
          if ((vanesUD > 0) & (vanesUD < 6) & (vanesUD != id(vanes_UD_received).state)){
            ESP_LOGD("main", "setting vanesUD to: %i", vanesUD);
            return ((MhiAcCtrl*)id(${deviceid}))->set_vanes(vanesUD);
          }
          else {
            ESP_LOGD("main", "Not setting vanesUD: %i", vanesUD);
          }

switch:
  - platform: template
    name: ${devicename} 3D Auto
    id: fan_control_3Dauto
    icon: mdi:video-3d
    optimistic: true
    turn_on_action:
      - lambda: |-
          if (id(Dauto_received).state !=1){
            ESP_LOGD("main", "Turn on 3DAuto");
            return ((MhiAcCtrl*)id(${deviceid}))->set_3Dauto(1);
          }
    turn_off_action:
      - lambda: |-
          if (id(Dauto_received).state !=0){
            ESP_LOGD("main", "Turn off 3DAuto");
            return ((MhiAcCtrl*)id(${deviceid}))->set_3Dauto(0);
          }

Please let me know how I can fix my yaml files to I can update my AC’s again. :slight_smile:
Thanks for the help!

You can bring back support for custom components with this external component: GitHub - robertklep/esphome-custom-component: Brings back support for custom ESPHome components

1 Like

Thanks for the link. How do I include this in the yaml file?

Like this?

external_components:
  - source:
      type: git
      url: https://github.com/robertklep/esphome-custom-component
    components: lambda: |-
      auto mhi_ac_ctrl = new MhiAcCtrl();
      App.register_component(mhi_ac_ctrl);
      return {mhi_ac_ctrl};

    climates:
      - name: "${devicename}"
        id: ${deviceid}

Not sure how to include the custom component…
Thanks!

Exactly as documented here: GitHub - robertklep/esphome-custom-component: Brings back support for custom ESPHome components

The rest of your YAML should stay as-is.

Hi,

Sorry for the questions, but should my yaml be like this?

substitutions:
  # Unique device ID in HA
  deviceid: "badkamer_airco" #deviceid: "mhi_woonkamer"
  # Unique device name in HA (sensor names will be prefixed by this name)
  devicename: "Badkamer airco" #devicename: "MHI-Woonkamer"

esphome:
  name: badkamer-airco #name: mhi-woonkamer  # Unique name  (only change in small letters)
  platformio_options:
    # Run CPU at 160Mhz to fix mhi_ac_ctrl_core.loop error: -2
    board_build.f_cpu: 160000000L
  includes:
    - mhi_ac_ctrl.h
    - MHI-AC-Ctrl-core.h
    - MHI-AC-Ctrl-core.cpp
esp8266:
  board: d1_mini
  framework:
    version: recommended

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  #ssid: "hierjesidd"
  #password: "hierjeww"
  fast_connect: true  # misschien hier een hekje voor zetten?
  
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "${devicename}"
    password: "configesp"

captive_portal:

logger:
  level: DEBUG
  baud_rate: 0

globals:
  - id: room_temp_api_timeout
    type: int
    restore_value: no
    initial_value: '120'

ota:
- platform: esphome

web_server:
  port: 80

external_components:
  - source:
      type: git
      url: https://github.com/robertklep/esphome-custom-component
    components: [ custom, custom_component ]

climate:
  - platform: custom
    lambda: |-
      auto mhi_ac_ctrl = new MhiAcCtrl();
      App.register_component(mhi_ac_ctrl);
      return {mhi_ac_ctrl};

    climates:
      - name: "${devicename}"
        id: ${deviceid}

api:
  reboot_timeout: 0s
  services:
    # Call the set_api_room_temperature service from HA to override the room temperature
    # If a new value has not been received after room_temp_api_timeout seconds, it will fall back to internal sensor
    - service: set_api_room_temperature
      variables:
        value: float
      then:
        - lambda: |-
            return ((MhiAcCtrl*)id(${deviceid}))->set_room_temperature(value);
    # Call the set_vanes service from HA to set the vane position
    # Needed because the ESPHome Climate class does not support this natively
    # Possible values: 1-4: static positions, 5: swing, 0: unknown
    - service: set_vanes
      variables:
        value: int
      then:
        - lambda: |-
            return ((MhiAcCtrl*)id(${deviceid}))->set_vanes(value);

sensor:
  - platform: wifi_signal # Reports the WiFi signal strength/RSSI in dB
    name: ${devicename} WiFi Signal db
    id: wifi_signal_db
    update_interval: 60s
    entity_category: diagnostic

  - platform: copy # Reports the WiFi signal strength in %
    source_id: wifi_signal_db
    name: ${devicename} WiFi Signal
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    unit_of_measurement: "%"
    entity_category: diagnostic

  - platform: uptime
    name: ${devicename} Uptime
    unit_of_measurement: days
    update_interval: 3600s
    accuracy_decimals: 1
    filters:
      - multiply: 0.000011574

  - platform: custom
    lambda: |-
      return ((MhiAcCtrl*)id(${deviceid}))->get_sensors();

    # Sensor names in HA, you can change these if you want
    # Don't delete them or change their position in the list
    sensors:
      - name: ${devicename} error code
      - name: ${devicename} outdoor temperature
      - name: ${devicename} return air temperature
      - name: ${devicename} outdoor unit fan speed
      - name: ${devicename} indoor unit fan speed
      - name: ${devicename} current power
      - name: ${devicename} compressor frequency
      - name: ${devicename} indoor unit total run time
      - name: ${devicename} compressor total run time
      - name: ${devicename} vanes
        id: vanes_UD_received
        on_value:
          then:
            - lambda: |-
                float received_value = id(vanes_UD_received).state;
                if (received_value == 1.0) {
                  id(fan_control_ud).publish_state("Up");
                } else if (received_value == 2.0) {
                  id(fan_control_ud).publish_state("Up/Center");
                } else if (received_value == 3.0) {
                  id(fan_control_ud).publish_state("Center/Down");
                } else if (received_value == 4.0) {
                  id(fan_control_ud).publish_state("Down");
                } else if (received_value == 5.0) {
                  id(fan_control_ud).publish_state("Swing");
                }

      - name: ${devicename} energy used
      - name: ${devicename} Indoor (U-bend) HE temp 1
      - name: ${devicename} Indoor (capillary) HE temp 2
      - name: ${devicename} Indoor (suction header) HE temp 3
      - name: ${devicename} Outdoor HE temp
      - name: ${devicename} Outdoor unit exp. valve
      - name: ${devicename} Outdoor unit discharge pipe
      - name: ${devicename} Outdoor unit discharge pipe super heat
      - name: ${devicename} Protection error state
      - name: ${devicename} Vanes Left Right
        id: vanes_LR_received
        on_value:
          then:
            - lambda: |-
                float received_value = id(vanes_LR_received).state;
                if (received_value == 1.0) {
                  id(fan_control_lr).publish_state("Left");
                } else if (received_value == 2.0) {
                  id(fan_control_lr).publish_state("Left/Center");
                } else if (received_value == 3.0) {
                  id(fan_control_lr).publish_state("Center");
                } else if (received_value == 4.0) {
                  id(fan_control_lr).publish_state("Center/Right");
                } else if (received_value == 5.0) {
                  id(fan_control_lr).publish_state("Right");
                } else if (received_value == 6.0) {
                  id(fan_control_lr).publish_state("Wide");
                } else if (received_value == 7.0) {
                  id(fan_control_lr).publish_state("Spot");
                } else if (received_value == 8.0) {
                  id(fan_control_lr).publish_state("Swing");
                }
      - name: ${devicename} 3D Auto
        id: Dauto_received
        on_value:
          then:
            - lambda: |-
                bool received_value = id(Dauto_received).state;
                if (received_value) {
                  ESP_LOGD("main", "received 3DAuto from AC");
                  id(fan_control_3Dauto).publish_state(true);
                }
                else {
                  ESP_LOGD("main", "received 3DAuto off from AC");
                  id(fan_control_3Dauto).publish_state(false);
                }

binary_sensor:
  - platform: custom
    lambda: |-
      return ((MhiAcCtrl*)id(${deviceid}))->get_binary_sensors();

    binary_sensors:
      - name: ${devicename} defrost

text_sensor:
  - platform: version
    name: ${devicename} ESPHome Version
  - platform: wifi_info
    ip_address:
      name: ${devicename} IP
    ssid:
      name: ${devicename} SSID
    bssid:
      name: ${devicename} BSSID
  - platform: custom
    lambda: |-
      return ((MhiAcCtrl*)id(${deviceid}))->get_text_sensors();

    text_sensors:
      - name: ${devicename} Protection error state

select:
  - platform: template
    name: ${devicename} Fan Control Left Right
    id: fan_control_lr
    icon: mdi:arrow-left-right
    optimistic: true
    options:
      # - "3D Auto"
      - "Left"
      - "Left/Center"
      - "Center"
      - "Center/Right"
      - "Right"
      - "Wide"
      - "Spot"
      - "Swing"
    on_value:
      - lambda: |-
          auto state = id(fan_control_lr).state.c_str();
          ESP_LOGD("main", "Option of my select: %s", state);
          uint8_t vanesLR = 0;  // Initialize the vanesLR variable
          if (id(fan_control_lr).state == "3D Auto") {
            id(fan_control_3Dauto).publish_state(true);
          } else if (id(fan_control_lr).state == "Left") {
            vanesLR = 1;
          } else if (id(fan_control_lr).state == "Left/Center") {
            vanesLR = 2;
          } else if (id(fan_control_lr).state == "Center") {
            vanesLR = 3;
          } else if (id(fan_control_lr).state == "Center/Right") {
            vanesLR = 4;
          } else if (id(fan_control_lr).state == "Right") {
            vanesLR = 5;
          } else if (id(fan_control_lr).state == "Wide") {
            vanesLR = 6;
          } else if (id(fan_control_lr).state == "Spot") {
            vanesLR = 7;
          } else if (id(fan_control_lr).state == "Swing") {
            vanesLR = 8;
          }
          if ((vanesLR > 0) & (vanesLR < 9) & (vanesLR != id(vanes_LR_received).state)){
            ESP_LOGD("main", "setting vanesLR to: %i", vanesLR);
            return ((MhiAcCtrl*)id(${deviceid}))->set_vanesLR(vanesLR);
          }
          else {
            ESP_LOGD("main", "Not setting vanesLR: %i", vanesLR);
          }

  - platform: template
    name: ${devicename} Fan Control Up Down
    id: fan_control_ud
    icon: mdi:arrow-up-down
    optimistic: true
    options:
      # - "3D Auto"
      - "Up"
      - "Up/Center"
      - "Center/Down"
      - "Down"
      - "Swing"
    on_value:
      - lambda: |-
          auto state = id(fan_control_lr).state.c_str();
          ESP_LOGD("main", "Option of my select: %s", state);
          uint8_t vanesUD = 0;  // Initialize the vanesUD variable
          if (id(fan_control_ud).state == "3D Auto") {
            id(fan_control_3Dauto).publish_state(true);
          } else if (id(fan_control_ud).state == "Up") {
            vanesUD = 1;
          } else if (id(fan_control_ud).state == "Up/Center") {
            vanesUD = 2;
          } else if (id(fan_control_ud).state == "Center/Down") {
            vanesUD = 3;
          } else if (id(fan_control_ud).state == "Down") {
            vanesUD = 4;
          } else if (id(fan_control_ud).state == "Swing") {
            vanesUD = 5;
          }
          if ((vanesUD > 0) & (vanesUD < 6) & (vanesUD != id(vanes_UD_received).state)){
            ESP_LOGD("main", "setting vanesUD to: %i", vanesUD);
            return ((MhiAcCtrl*)id(${deviceid}))->set_vanes(vanesUD);
          }
          else {
            ESP_LOGD("main", "Not setting vanesUD: %i", vanesUD);
          }

switch:
  - platform: template
    name: ${devicename} 3D Auto
    id: fan_control_3Dauto
    icon: mdi:video-3d
    optimistic: true
    turn_on_action:
      - lambda: |-
          if (id(Dauto_received).state !=1){
            ESP_LOGD("main", "Turn on 3DAuto");
            return ((MhiAcCtrl*)id(${deviceid}))->set_3Dauto(1);
          }
    turn_off_action:
      - lambda: |-
          if (id(Dauto_received).state !=0){
            ESP_LOGD("main", "Turn off 3DAuto");
            return ((MhiAcCtrl*)id(${deviceid}))->set_3Dauto(0);
          }

This is with the new platform and above the custom component I added the external components from your link. But when added the custom components still have red lines underneath them. Is that a problem?

There’s a real easy way to find out: try installing it on your device :man_shrugging:t3:

I’d rather not mess up the yaml files, but I’ll give it a try.
Thanks

I can only provide instructions on how to add support for custom components (which you have done correctly), not on the rest of your YAML file.