Selecting values and updating via modbus

I successfully read values from my boiler by adding this code to my modbus.config:

  - name: modbus_kwb
    type: tcp
    host: 192.168.11.21
    port: 502
    sensors:
    - name: Heizkreis_Programm
      slave: 1
      address: 24589
      input_type: holding
      state_class: measurement
      data_type: int16
      precision: 1
      scale: 1

i successfully managed to show text intstead of integers with a template named select.heizkreis.

it presents the current state correctly with:

{{ [ 'Automatik',
     'Frostschutz',
     'Aus',
     'Komfort',
     'Absenk'][states('sensor.heizkreis_programm')|int] }}

it prepares the options of the selection correctly with:

{{ [ 'Automatik',
     'Frostschutz',
     'Aus',
     'Komfort',
     'Absenk'] }}

what kind of actions do i need to add to write the selected value (an integer from 0 to 4) into the corresponding modbus register?

You’ll be using the modbus write_register actions. You can make a template select entity that does all the work for you.

Not sure if this may help in your case, perhaps you can use it as a starting point.

I integrated my heatpump using Modbus, and I set up buttons on a card to increase / reduce the setpoint, invoking a script, like this:

alias: "Heat Pump: Setpoint +1"
mode: single
sequence:
  - action: timer.start
    target:
      entity_id: timer.heat_pump_setpoint_disable
  - variables:
      curr: "{{ states('sensor.heat_pump_water_temp_zone_1')|int }}"
      new: "{{ curr + 1 }}"
  - action: modbus.write_register
    data:
      hub: waveshare_heat_pump
      slave: 1
      address: 11
      value: "{{ new }}"

In my specific implementation I use a timer to disable the button(s) while Modbus updates since I want to avoid multiple commands being sent too fast:

timer:
  # Timer to Disable Setpoint Buttons between Modbus Updates
  heat_pump_setpoint_disable:
    name: "Heat Pump Setpoint Disable"
    duration: "00:00:10"

I have a similar script for reducing the setpoint.

This is what it looks like on the dashboard. I have added logic to disable the +/- buttons, make them dim, and display an icon while the timer is active, so it is not possible to press a button more than once for each timer period… I can share the bubble card code I am using should you be interested.

Thank you for your answer. It helped me to find a solution, which is not totally satisfying, but works. As described, I define a sensor in my modbus configuration file modbus.yaml:

- name: modbus_kwb
  type: tcp
  host: 192.168.11.21
  port: 502
  sensors:
    - name: Heizkreis_Programm
      unique_id: heizkreis_programm
      slave: 1
      address: 24589
      input_type: holding
      state_class: measurement
      data_type: int16

This creates sensor.heizkreis_programm and holds integers, which I do not like to handle with.

Following your advice I define a template, which translates the integers to text and creates select.heizkreis_programm_select:

- select:
  - name: Heizkreis Programm
    unique_id: heizkreis_programm_select
    state: "{{ [ 
     'Automatik',
     'Frostschutz',
     'Aus',
     'Komfort',
     'Absenk'] [states('sensor.heizkreis_programm')|int] }}"
    options: "{{ ['Automatik',
     'Frostschutz',
     'Aus',
     'Komfort',
     'Absenk'] }}"
    select_option:
      action: modbus.write_register
      data:
        hub: modbus_kwb 
        address: 24589
        value: >
          {% if option == 'Automatik' %}
            0
          {% elif option  == 'Frostschutz' %}
            1
          {% elif option  == 'Aus' %}
            2
          {% elif option  == 'Komfort' %}
            3
          {% else %}
            4
          {% endif %}

Then I make sensor.heizkreis_programm unvisible, because I do not like to see numbers.

What I do not like in this solution:

  • The code is splitted up into two parts, one in the modbus configuration, the other in the templates configuration.
  • I code the translations two times, one time from number to text and a second time from text to numbers.
  • It needs two entities, where a single select would do the job.

I would prefer, if there was an entity select in the modbus integration, which allows to do all this in the modbus config file.

- select:
  - name: Heizkreis Programm
    unique_id: heizkreis_programm_select
    variables:
      options:
      - Automatik
      - Frostschutz
      - Aus
      - Komfort
      - Absenk
        
    state: "{{ options[states('sensor.heizkreis_programm')|int] }}"
    options: "{{ options }}"
    select_option:
      action: modbus.write_register
      data:
        hub: modbus_kwb 
        address: 24589
        value: "{{ options.index(option) }}"

thanks, this helps for more clarity.