Automated heat pump!

I have a heat pump, but two factors has made me want to let HA get control of it:

  • The heat pump thermostat is really quite poor, and will result in wildly varying indoor temperatures.
  • Partly due to this, my wife handles the remote a lot, and tends to overcorrect somewhat… (Hello Antarctica!)

So I did a bit of research and found this library:

His libraries work with ESPEasy, and since I had a NodeMCU lying about, I managed to get that working with HA, connected a BME280 temp/humidity/pressure sensor, and a transistor-activated IR LED.

To go with HA’s newfound control of my heatpump, I made a manual control panel for it, and an automation that adjusts the heatpump settings to attain the desired living room temperature.

PS: Sorry for the norwegian everywhere, I couldn’t be bothered to translate it, but I think the automations should explain it if you are trying to do something similar:)

The results aren’t perfect, but it’s a lot better than I’m used to:)

image

(It’s been running since about 14:00 in this graph.)

One of the main reasons it fluctuates a bit is that I’m only letting it change settings every 5 minutes, mostly to prevent the heat pump from being too annyoing as it goes beep every time it receives a command.

My config looks like this:

input_select:
  varmepumpe_mode:
    name: Modus
    options:
      - "Auto"
      - "Varme"
      - "Kjøling"
      - "Avfukting"
      - "Vifte"
    icon: mdi:air-conditioner

input_slider:
  varmepumpe_temp:
    name: Temperatur
    initial: 21
    min: 16
    max: 30
    step: 1
    icon: mdi:thermometer

  varmepumpe_vifte:
    name: Viftehastighet (0=Auto)
    initial: 0
    min: 0
    max: 5
    step: 1
    icon: mdi:fan

  varmepumpe_retning:
    name: Luftretning (0=Auto)
    initial: 0
    min: 0
    max: 5
    step: 1
    icon: mdi:weather-windy

  stue_temperatur:
    name: Ønsket temperatur stue
    initial: 25
    min: 16
    max: 30
    step: 1
    icon: mdi:thermometer

automation old varmepumpe_send:
  alias: Varmepumpe Send
  trigger:
    platform: state
    entity_id: input_boolean.varmepumpe_send
    from: 'off'
    to: 'on'
  action:
    - service: mqtt.publish
      data:
        topic: "/espeasy01/cmd"
        payload_template: "heatpumpir,panasonic_dke,{% if states.input_boolean.varmepumpe_onoff.state == 'on' %}1{% elif states.input_boolean.varmepumpe_onoff.state == 'off' %}0{% endif %},{% if states.input_select.varmepumpe_mode.state == 'Auto' %}1{% elif states.input_select.varmepumpe_mode.state == 'Varme' %}2{% elif states.input_select.varmepumpe_mode.state == 'Kjøling' %}3{% elif states.input_select.varmepumpe_mode.state == 'Avfukting' %}4{% elif states.input_select.varmepumpe_mode.state == 'Vifte' %}5{% endif %},{{states.input_slider.varmepumpe_vifte.state|int}},{{states.input_slider.varmepumpe_temp.state|int}},{{states.input_slider.varmepumpe_retning.state|int}},0"
    - service: homeassistant.turn_off
      entity_id: input_boolean.varmepumpe_send

automation old stue_termostat_opp:
  alias: Varmepumpetemperatur opp
  trigger:
    platform: time
    minutes: '/10'
    seconds: 00
  condition:
    condition: template
    value_template: '{{ states.sensor.temperature.state | float - states.input_slider.stue_temperatur.state | float < 0.5 }}'
  action:
    - service: input_slider.select_value
      data_template:
        entity_id: input_slider.varmepumpe_temp
        value: '{{ states.input_slider.varmepumpe_temp.state | float + 1 }}'
    - service: mqtt.publish
      data:
        topic: "/espeasy01/cmd"
        payload_template: "heatpumpir,panasonic_dke,{% if states.input_boolean.varmepumpe_onoff.state == 'on' %}1{% elif states.input_boolean.varmepumpe_onoff.state == 'off' %}0{% endif %},{% if states.input_select.varmepumpe_mode.state == 'Auto' %}1{% elif states.input_select.varmepumpe_mode.state == 'Varme' %}2{% elif states.input_select.varmepumpe_mode.state == 'Kjøling' %}3{% elif states.input_select.varmepumpe_mode.state == 'Avfukting' %}4{% elif states.input_select.varmepumpe_mode.state == 'Vifte' %}5{% endif %},{{states.input_slider.varmepumpe_vifte.state|int}},{{states.input_slider.varmepumpe_temp.state|int}},{{states.input_slider.varmepumpe_retning.state|int}},0"

automation old stue_termostat_ned:
  alias: Varmepumpetemperatur ned
  trigger:
    platform: time
    minutes: '/10'
    seconds: 00
  condition:
    condition: template
    value_template: '{{ states.sensor.temperature.state | float - states.input_slider.stue_temperatur.state | float > 0.5 }}'
  action:
    - service: input_slider.select_value
      data_template:
        entity_id: input_slider.varmepumpe_temp
        value: '{{ states.input_slider.varmepumpe_temp.state | float - 1 }}'
    - service: mqtt.publish
      data:
        topic: "/espeasy01/cmd"
        payload_template: "heatpumpir,panasonic_dke,{% if states.input_boolean.varmepumpe_onoff.state == 'on' %}1{% elif states.input_boolean.varmepumpe_onoff.state == 'off' %}0{% endif %},{% if states.input_select.varmepumpe_mode.state == 'Auto' %}1{% elif states.input_select.varmepumpe_mode.state == 'Varme' %}2{% elif states.input_select.varmepumpe_mode.state == 'Kjøling' %}3{% elif states.input_select.varmepumpe_mode.state == 'Avfukting' %}4{% elif states.input_select.varmepumpe_mode.state == 'Vifte' %}5{% endif %},{{states.input_slider.varmepumpe_vifte.state|int}},{{states.input_slider.varmepumpe_temp.state|int}},{{states.input_slider.varmepumpe_retning.state|int}},0"
3 Likes

I stole your idea and changed it a bit. I just trigger the automation on change of any value and post it with curl.

It might be the longest shell_command ever.

# input
input_select:
  ac_mode:
    name: Airco Mode
    icon: mdi:fan
    options:
      - "Off"
      - "Auto"
      - "Cool"
      - "Dry"
      - "Heat"
      - "Fan"
  ac_hdir:
    name: Airco hDir
    icon: mdi:thermometer
    options:
      - "Auto"
      - "Swing"
      - "Lefter"
      - "Left"
      - "Center"
      - "Right"
      - "Righter"
  ac_vdir:
    name: Airco vDir
    icon: mdi:thermometer
    options:
      - "Auto"
      - "Swing"
      - "Upper"
      - "Up"
      - "Center"
      - "Down"
      - "Downer"
  ac_fanspeed:
    name: Airco FanSpeed
    icon: mdi:thermometer
    options:
      - "Auto"
      - "Low"
      - "Normal"
      - "High"
      - "Higher"
      - "Turbo"
input_slider:
  ac_temp:
    name: Temperature
    initial: 21
    min: 16
    max: 30
    step: 1
    icon: mdi:thermometer
automation:
- alias: Airco Control
  trigger:
    - platform: state
      entity_id: input_select.ac_mode
    - platform: state
      entity_id: input_select.ac_temp
    - platform: state
      entity_id: input_select.ac_vdir
    - platform: state
      entity_id: input_select.ac_hdir
    - platform: state
      entity_id: input_select.ac_fanspeed
  action:
    - service: shell_command.set_ac

shell_command: 
  set_ac: "curl http://666.666.6.66/control?cmd=heatpumpir,panasonic_jke,{% if states.input_select.ac_mode.state == 'Off' %}0{% else %}1{% endif %},{% if states.input_select.ac_mode.state == 'Auto' %}1{% elif states.input_select.ac_mode.state == 'Heat' %}2{% elif states.input_select.ac_mode.state == 'Cool' %}3{% elif states.input_select.ac_mode.state == 'Dry' %}4{% elif states.input_select.ac_mode.state == 'Fan' %}5{% endif %},{% if states.input_select.ac_fanspeed.state == 'Auto' %}0{% elif states.input_select.ac_fanspeed.state == 'Low' %}1{% elif states.input_select.ac_fanspeed.state == 'Normal' %}2{% elif states.input_select.ac_fanspeed.state == 'High' %}3{% elif states.input_select.ac_fanspeed.state == 'Higher' %}4{% elif states.input_select.ac_fanspeed.state == 'Turbo' %}5{% endif %},{{states.input_slider.ac_temp.state|int}},{% if states.input_select.ac_vdir.state == 'Auto' %}0{% elif states.input_select.ac_vdir.state == 'Swing' %}1{% elif states.input_select.ac_vdir.state == 'Upper' %}2{% elif states.input_select.ac_vdir.state == 'Up' %}3{% elif states.input_select.ac_vdir.state == 'Center' %}4{% elif states.input_select.ac_vdir.state == 'Down' %}5{% elif states.input_select.ac_vdir.state == 'Downer' %}6{% endif %},{% if states.input_select.ac_hdir.state == 'Auto' %}0{% elif states.input_select.ac_hdir.state == 'Swing' %}1{% elif states.input_select.ac_hdir.state == 'Lefter' %}2{% elif states.input_select.ac_hdir.state == 'Left' %}3{% elif states.input_select.ac_hdir.state == 'Center' %}4{% elif states.input_select.ac_hdir.state == 'Right' %}5{% elif states.input_select.ac_hdir.state == 'Righter' %}6{% endif %}"

1 Like

Hi!
Your idea looks great. I have done it like this.

3 Likes

Cool:) How did you do the indicator line with current temperature setting and current temperature?

(The one with Heat 22C / Currently 22.1C)

Here is my code:

  • alias: ‘skru AC på’
    trigger:
    platform: state
    entity_id: input_boolean.turn_on_ac
    to: ‘on’
    action:

    • service: climate.set_aux_heat
      data:
      entity_id: climate.ac
      aux_heat: true
  • alias: ‘skru AC av’
    trigger:
    platform: state
    entity_id: input_boolean.turn_on_ac
    to: ‘off’
    action:

    • service: climate.set_aux_heat
      data:
      entity_id: climate.ac
      aux_heat: false
  • alias: air condition
    trigger:

    • platform: state
      entity_id: input_select.operation
      action:
    • service: climate.set_operation_mode
      data_template:
      entity_id: climate.ac
      operation_mode: >
      {% if is_state(“input_select.operation”, “Heat”) %}
      heat
      {%-elif is_state(“input_select.operation”, “Auto”) %}
      auto
      {% elif is_state(“input_select.operation”, “Dry”) %}
      dry
      {% elif is_state(“input_select.operation”, “Cool”) %}
      cool
      {% else %}
      auto
      {% endif %}
  • alias: air condition fan
    trigger:

    • platform: state
      entity_id: input_select.fan
      action:
    • service: climate.set_operation_mode
      data_template:
      entity_id: climate.ac
      operation_mode: >
      {% if is_state(“input_select.operation”, “Auto”) %}
      auto
      {%-elif is_state(“input_select.operation”, “Quiet”) %}
      quiet
      {% elif is_state(“input_select.operation”, “Low”) %}
      low
      {% elif is_state(“input_select.operation”, “Medium”) %}
      medium
      {% elif is_state(“input_select.operation”, “Med-High”) %}
      med-high
      {% elif is_state(“input_select.operation”, “High”) %}
      high
      {% else %}
      auto
      {% endif %}
  • alias: air condition temperature
    trigger:

    • platform: state
      entity_id: input_slider.air_condition_temp
      action:
    • service: climate.set_temperature
      data_template:
      entity_id: climate.ac
      temperature: ‘{{ states.input_slider.air_condition_temp.state | int }}’
      target_temp_high: 30
      target_temp_low: 10
1 Like

Hey guys how can I integrate this with a sonoff using mqtt…

Nice job guys, I will be inspired by your work to implement my controller.

@badstraw
I use a Wemos D1 but at the end it’s the same thing. The IR led is connected to GPIO 14.
image

For the integration, you simply need to push the HeatPumpIR code into the ESP and set it up with your parameters.

How does the nodemcu communicate with HA?
Via mqtt?

Sorry for the slow delay, I missed the notification… Yes, it communicates via MQTT. There are some guides lying around on the forum to make ESPEasy communicate with HA with little effort:)

Hi @diogos88

Just interested in this project as heat pump controller using D1 Mini.

Have you got this running and working as a controller for your heat pump?
Cheers

Yes, I used espeasy to avoid starting from scratch and then I made a small plugin for my needs. Unfortunately, I don’t know where I put my code.

I use this library for the communication with the heatpump https://github.com/ToniA/arduino-heatpumpir
and the communication between the ESP and HASS is done with mqtt.

Well done. A shame you not sure where the code is. At least you got it running. Nice work
I am keen to try this, however have to learn more first

Hi people. This is jrdan from Italy.
I’m following this post 'cause me too use tonia firmware with espeasy on home assistant 0.94.3.
The only way to send command to heatpump is by a simple curl:
“curl -k http://192.168.0.54/control?cmd=heatpumpir,daikin,1,0,2,24,0,0
and it works.
I tried to use file from devtone but it doesent works. May be someone has managed to make it work?
thanks for reply
P.S. I use espeasy firmware modified on esp12f with mqtt