Heatpump (KEBA) select functioning mode via input selector

Hello,

and happy to join the HA community with my first post :slight_smile: . I am trying to integrate my M-TEC heatpump (it uses KEBA KeEnergy software) to HA using the yaml config files. (infos found here: Keba KeEnergy Heizungssteuerung (M-TEC WP) in Smarthome)

So I succesfully integrated the Heatpump via modbus, but I am struggeling with two points:

  1. I created an input selector Heatpump Mode to select the functioning mode of my heatpump. I am then passing the selected mode to the heatpump using the automation and this works perfectly set_heatpump_mode.
    However, the second part get_heatpump_mode, that updates the input selector when the mode on the heatpump was changed manually, is resisting my beginner skills.
    I keep getting an error message: Invalid config for [automation]: must contain at least one of below, above.. Got OrderedDict. I searched for hours, tried changing the automations.yml without success …

  2. My heatpump, uses a user defined offset (Heatpump_offsetRoomTemp) that ranges from -2.5 to 2.5 that helps to fine tune the temperature. This offset is added to the Heatpump_normalSetTempTest or the Heatpump_reducedSetTemp – depending on the selected mode (Day/Night) – to achieve the final temperature Heatpump_SetpointTemperature.
    My issue is that i tried to integrated it as a HVAC as for the two other but it does not let me input a negative value? Any idea on how to achieve this?

Below my configuration:

input_select:
  heatpump_mode:
    name: Heatpump Mode
    options:
      - "Standby"
      - "Timer"
      - "Day"
      - "Night"
      - "Vacation"
      - "Party"
    icon: mdi:home-thermometer

modbus:
  - name: Heatpump
    type: tcp
    host: 192.168.1.30
    port: 502
    sensors:
      - name: Heatpump_selectedSetTemp
        data_type: uint16
        slave: 1
        address: 2
        scale: 0.1
        precision: 1
        unit_of_measurement: °C
      - name: Heatpump_SetpointTemperature
        data_type: uint16
        slave: 1
        address: 3
        scale: 0.1
        precision: 1
        unit_of_measurement: °C
      - name: Heatpump_offsetRoomTemp
        data_type: uint16
        slave: 1
        address: 6
        scale: 0.1
        precision: 1
        unit_of_measurement: °C
      - name: Heatpump_HotWater_Temperature
        data_type: uint16
        slave: 1
        address: 401
        scale: 0.1
        precision: 1
        unit_of_measurement: °C
      - name: Heatpump_HotWater_SetpointTemperature
        data_type: uint16
        slave: 1
        address: 402
        scale: 0.1
        precision: 1
        unit_of_measurement: °C
      - name: Heatpump_TotalAccumulatedHeatingEnergy
        data_type: uint16
        slave: 1
        address: 701
        scale: 1
        precision: 1
        unit_of_measurement: kWh
      - name: Heatpump_State
        data_type: uint16
        slave: 1
        address: 703
      - name: Heatpump_ActualFlowTemperature
        data_type: uint16
        slave: 1
        address: 705
        scale: 0.1
        precision: 1
        unit_of_measurement: °C
      - name: Heatpump_HeatPower
        data_type: uint16
        slave: 1
        address: 706
        scale: 0.001
        precision: 2
        unit_of_measurement: kW
      - name: Heatpump_RefluxTemperature
        data_type: uint16
        slave: 1
        address: 710
        scale: 0.1
        precision: 1
        unit_of_measurement: °C
      - name: Heatpump_CirculationPump
        data_type: uint16
        slave: 1
        address: 712
        scale: 0.01
        precision: 2
      - name: Heatpump_OutdoorTempValues
        data_type: uint16
        slave: 1
        address: 1502
        scale: 0.1
        precision: 1
      - name: Heatpump_operatingMode
        data_type: uint16
        slave: 1
        address: 7
    climates:
      - name: Heatpump_normalSetTempTest
        data_type: uint16
        slave: 1
        address: 4
        input_type: holding
        count: 1
        max_temp: 30
        min_temp: 10
        offset: 0
        precision: 1
        scale: 0.1
        target_temp_register: 4
        temp_step: 1
        temperature_unit: C
      - name: Heatpump_reducedSetTemp
        data_type: uint16
        slave: 1
        address: 5
        input_type: holding
        count: 1
        max_temp: 30
        min_temp: 10
        offset: 0
        precision: 1
        scale: 0.1
        target_temp_register: 5
        temp_step: 1
        temperature_unit: C

And my automation

- id: '1670278639728'
  alias: set_heatpump_mode
  description: ''
  trigger:
  - platform: state
    entity_id:
    - input_select.heatpump_mode
  condition: []
  action:
  - service: modbus.write_register
    data:
      address: 7
      hub: Heatpump
      value: >
        {% if is_state('input_select.heatpump_mode', 'Standby') %}
           0
        {% elif is_state('input_select.heatpump_mode', 'Timer') %}
           1  
        {% elif is_state('input_select.heatpump_mode', 'Day') %}
           2
        {% elif is_state('input_select.heatpump_mode', 'Night') %}
           3
        {% elif is_state('input_select.heatpump_mode', 'Vacation') %}
           4
        {% elif is_state('input_select.heatpump_mode', 'Party') %}
           5
        {% endif %}
  mode: single
- id: '1670426700029'
  alias: get_heatpump_mode
  description: ''
  trigger:
  - platform: numeric_state
    entity_id:
    - sensor.heatpump_operatingmode
  condition: []
  action:
  - service: input_select.select_option
    target:
      entity_id: input_select.heatpump_mode
    data:
      option: >
        {% if is_state('sensor.heatpump_operatingmode', 0) %}
           'Standby'
        {% elif is_state('sensor.heatpump_operatingmode', 1) %}
           'Timer'  
        {% elif is_state('sensor.heatpump_operatingmode', 2) %}
           'Day'
        {% elif is_state('sensor.heatpump_operatingmode', 3) %}
           'Night'
        {% elif is_state('sensor.heatpump_operatingmode', 4) %}
           'Vacation'
        {% elif is_state('sensor.heatpump_operatingmode', 5) %}
           'Party'
        {% endif %}
  mode: single

Thanks !

In case someone is searching, I did a beginner mistake in the automation by adding unnecessary quotes, I also cast the value of the sensor to an int.
Automation get_heatpump_mode should be written as this:

- id: '1670504791806'
  alias: get_heatpump_mode
  description: ''
  trigger:
  - platform: state
    entity_id:
    - sensor.heatpump_operatingmode
  condition: []
  action:
  - service: input_select.select_option
    target:
      entity_id: input_select.heatpump_mode
    data:
      option: "{% set mode = states('sensor.heatpump_operatingmode') | int(0) %}  {%
        if mode == 0 %}\n   Standby\n{% elif mode == 1 %}\n   Timer  \n{% elif mode
        == 2 %}\n   Day\n{% elif mode == 3 %}\n   Night\n{% elif mode == 4 %}\n   Vacation\n{%
        elif mode == 5 %}\n   Part\n{% endif %}\n"
  mode: single

I am still missing the second part and the negative offset although

I finally solved my issue. I tried to create the manual temperature offset using a climate entity, but this was not possible. Although, it is maybe possible to create a new climate entity in Python to handle this specific use case…

So the easiest solution was for me just to create a new input_number helper called Normal Temp. I then used it again in an automation and write the input state to the modbus register.

So here my M-TEC (KEBA) heatpump dashboard with on top the mode selector and below the manual offset:

And here my configurstion file:

# Helper for the Heatpump automation
input_select:
  heatpump_mode:
    name: Heatpump Mode
    options:
      - "Standby"
      - "Timer"
      - "Day"
      - "Night"
      - "Vacation"
      - "Party"
    icon: mdi:home-thermometer

# KEBA Heatpump
modbus:
  - name: Heatpump
    type: tcp
    host: 192.168.1.30
    port: 502
    sensors:
      - name: Heatpump_selectedSetTemp
        data_type: uint16
        slave: 1
        address: 2
        scale: 0.1
        precision: 1
        unit_of_measurement: °C
      - name: Heatpump_SetpointTemperature
        data_type: uint16
        slave: 1
        address: 3
        scale: 0.1
        precision: 1
        unit_of_measurement: °C
      - name: Heatpump_offsetRoomTemp
        data_type: uint16
        slave: 1
        address: 6
        scale: 0.1
        precision: 1
        unit_of_measurement: °C
      - name: Heatpump_HotWater_Temperature
        data_type: uint16
        slave: 1
        address: 401
        scale: 0.1
        precision: 1
        unit_of_measurement: °C
      - name: Heatpump_HotWater_SetpointTemperature
        data_type: uint16
        slave: 1
        address: 402
        scale: 0.1
        precision: 1
        unit_of_measurement: °C
      - name: Heatpump_TotalAccumulatedHeatingEnergy
        data_type: uint16
        slave: 1
        address: 701
        scale: 1
        precision: 1
        unit_of_measurement: kWh
      - name: Heatpump_State
        data_type: uint16
        slave: 1
        address: 703
      - name: Heatpump_ActualFlowTemperature
        data_type: uint16
        slave: 1
        address: 705
        scale: 0.1
        precision: 1
        unit_of_measurement: °C
      - name: Heatpump_HeatPower
        data_type: uint16
        slave: 1
        address: 706
        scale: 0.001
        precision: 2
        unit_of_measurement: kW
      - name: Heatpump_RefluxTemperature
        data_type: uint16
        slave: 1
        address: 710
        scale: 0.1
        precision: 1
        unit_of_measurement: °C
      - name: Heatpump_CirculationPump
        data_type: uint16
        slave: 1
        address: 712
        scale: 0.01
        precision: 2
      - name: Heatpump_OutdoorTempValues
        data_type: uint16
        slave: 1
        address: 1502
        scale: 0.1
        precision: 1
      - name: Heatpump_operatingMode
        data_type: uint16
        slave: 1
        address: 7
    climates:
      - name: Heatpump_normalSetTempTest
        data_type: uint16
        slave: 1
        address: 4
        input_type: holding
        count: 1
        max_temp: 30
        min_temp: 10
        offset: 0
        precision: 0.1
        scale: 0.1
        target_temp_register: 4
        temp_step: 0.5
        temperature_unit: C
      - name: Heatpump_reducedSetTemp
        data_type: uint16
        slave: 1
        address: 5
        input_type: holding
        count: 1
        max_temp: 30
        min_temp: 10
        offset: 0
        precision: 0.1
        scale: 0.1
        target_temp_register: 5
        temp_step: 0.5
        temperature_unit: C

And the automation file:

- id: "1670278639728"
  alias: set_heatpump_mode
  description: Set the mode of the heatpump
  trigger:
  - platform: state
    entity_id:
    - sensor.heatpump_operatingmode
  condition: []
  action:
  - service: input_select.select_option
    target:
      entity_id: input_select.heatpump_mode
    data:
      option: "{% set mode = states('sensor.heatpump_operatingmode') | int(0) %}  {%
        if mode == 0 %}\n   Standby\n{% elif mode == 1 %}\n   Timer  \n{% elif mode
        == 2 %}\n   Day\n{% elif mode == 3 %}\n   Night\n{% elif mode == 4 %}\n   Vacation\n{%
        elif mode == 5 %}\n   Part\n{% endif %}\n"
  mode: single
- id: '1670963163660'
  alias: set_temp_offset
  description: Set the temperature offset of the heatpump
  trigger:
  - platform: state
    entity_id:
    - input_number.normal_temp
  condition: []
  action:
  - service: modbus.write_register
    data:
      address: 6
      hub: Heatpump
      value: '{{states(''input_number.normal_temp'') | float()  * 10}}'
  mode: single
- id: '1670965913633'
  alias: get_temp_offset
  description: Get the temperature offset of the heatpump
  trigger:
  - platform: state
    entity_id:
    - sensor.heatpump_offsetroomtemp
  condition: []
  action:
  - service: input_number.set_value
    data:
      value: "{{states('sensor.heatpump_offsetroomtemp') | float()}}"
    target:
      entity_id: input_number.normal_temp
  mode: single

I am closing my topic :boom: ! I have still the boiler to do, but should be pretty straight forward.

1 Like

Hi, thanks for you code,
I have one issue, I can change the value of sensor.heatpump_operatingmode but the change is not send to M-TEC (KEBA) heatpump dashboard . Do you know have I can fix this

Oops, I see that I am missing the first lines of the code on the automation.
I am editing it right now, and you can then just copy and paste it again.

Let me know if it is still not working. BTW please note that there is a small delay between sending the command and the update (usually a few seconds).

1 Like

Hi @carmanber
I want to thank you very much for the configuration here! I also got a M-TEC heatpump and I’m new to HA.
I’ve added the configuration and automation. Could you also share the dashboard you created?
Thanks, Jo

Hi @jgrumboe ,

andd welcome to HA, hope you will have fun developping your Smart Home :slight_smile:

Here the yaml of the dashboard (you may have to adapt it to your system).

  - icon: mdi:home-thermometer
    title: Heat Pump
    subview: true
    badges: []
    cards:
      - type: custom:mushroom-chips-card
        chips:
          - type: back
          - type: action
            icon: mdi:information-outline
          - type: conditional
            conditions:
              - entity: input_select.heatpump_mode
                state_not: Standby
            chip:
              type: action
              icon: mdi:power
              hold_action:
                action: call-service
                service: input_select.select_option
                data:
                  option: Standby
                target:
                  entity_id: input_select.heatpump_mode
          - type: conditional
            conditions:
              - entity: input_select.heatpump_mode
                state_not: Timer
            chip:
              type: action
              icon: mdi:clock-time-four-outline
              hold_action:
                action: call-service
                service: input_select.select_option
                data:
                  option: Timer
                target:
                  entity_id: input_select.heatpump_mode
          - type: conditional
            conditions:
              - entity: input_select.heatpump_mode
                state_not: Day
            chip:
              type: action
              icon: mdi:white-balance-sunny
              tap_action:
                action: none
              hold_action:
                action: call-service
                service: input_select.select_option
                data:
                  option: Day
                target:
                  entity_id: input_select.heatpump_mode
          - type: conditional
            conditions:
              - entity: input_select.heatpump_mode
                state_not: Night
            chip:
              type: action
              icon: mdi:moon-waning-crescent
              hold_action:
                action: call-service
                service: input_select.select_option
                data:
                  option: Night
                target:
                  entity_id: input_select.heatpump_mode
      - type: vertical-stack
        cards:
          - type: custom:mushroom-title-card
            title: Temperature
          - type: entities
            entities:
              - entity: input_select.heatpump_mode
                secondary_info: none
          - square: false
            columns: 3
            type: grid
            cards:
              - show_name: false
                show_icon: true
                type: button
                tap_action:
                  action: call-service
                  service: input_number.decrement
                  data: {}
                  target:
                    entity_id: input_number.normal_temp
                icon: mdi:arrow-down-bold
                icon_height: 57px
              - type: custom:mushroom-title-card
                title: '{{ states(''sensor.heatpump_setpointtemperature'') }} °C'
                alignment: center
              - show_name: false
                show_icon: true
                type: button
                tap_action:
                  action: call-service
                  service: input_number.increment
                  data: {}
                  target:
                    entity_id: input_number.normal_temp
                icon: mdi:arrow-up-bold
                icon_height: 58px
          - type: custom:mushroom-climate-card
            entity: climate.heatpump_normalsettemptest
            show_temperature_control: true
            name: Normal
            collapsible_controls: true
            icon: mdi:thermometer-chevron-up
            layout: horizontal
          - type: custom:mushroom-climate-card
            entity: climate.heatpump_reducedsettemp
            name: Reduced
            icon: mdi:thermometer-chevron-down
            show_temperature_control: true
            fill_container: false
            layout: horizontal
      - type: vertical-stack
        cards:
          - type: custom:mushroom-title-card
            title: Hot Water
          - type: custom:mushroom-climate-card
            entity: climate.heatpump_hotwater_setpointtemperature
            show_temperature_control: true
            layout: horizontal
            name: Reglage
          - type: custom:mushroom-entity-card
            entity: sensor.heatpump_hotwater_temperature
            name: Temperature
      - type: vertical-stack
        cards:
          - type: custom:mushroom-title-card
            title: Heatpump
          - type: iframe
            url: http://chaudiere
            aspect_ratio: 50%

Hope it helps, let me know if there is any issue.

Aso, you will see that the interface is a bit slow (the way the automation/modbus works). I am thinking whether to develop smtg specific, I will keep you posted if so.