Modbus component is slamming my modbus server

Hello

I have just implemented modbus (removed the nodered).
Simple config -

    
####MODBUS###############

# Example configuration.yaml entry
modbus:
  - name: HVAC
    type: tcp
    host: 192.168.39.14
    port: 502
    delay: 5
    retry_on_empty: true
    retries: 10

    sensors:
#      - name: Pump_1
#        slave: 2
#        address: 48
#        input_type: input
#      - name: Pump_2
#        slave: 2
#        address: 49
#        input_type: input
      - name: RunState
        data_type : string
        slave: 1
        address: 0
        count : 4

      - name: Alarm
        data_type : string
        slave: 1
        address: 5
        count: 4

      - name: Total_Cap
        slave: 1
        address: 9
        unit_of_measurement: "%"

      - name: SetPoint
        unit_of_measurement: "°C"
        slave: 1
        address: 12
        scale : 0.001
        precision: 3
        device_class: temperature

      - name: CTRL_PNT 
        unit_of_measurement: "°C"
        slave: 1
        address: 14
        scale : 0.001
        precision: 3
        device_class: temperature

      - name: CTRL_WT
        unit_of_measurement: "°C"
        slave: 1
        address: 16
        scale : 0.001
        precision: 3
        device_class: temperature

      - name: OAT
        unit_of_measurement: "°C"
        slave: 1
        address: 18
        scale : 0.01
        precision: 3
        device_class: temperature

      - name: CircuitA
        slave: 1
        address: 19
        unit_of_measurement: "%"

      - name: CircuitA_Total
        slave: 1
        address: 20 
        unit_of_measurement: "%"

      - name: DischargeP_A
        slave: 1
        address: 21
        unit_of_measurement: "kPa"
        device_class: pressure

      - name: SuctionP_A
        slave: 1
        address: 22
        unit_of_measurement: "kPa"
        device_class: pressure

      - name: DischargeT_A
        slave: 1
        address: 24
        unit_of_measurement: "°C"
        scale : 0.01
        precision: 3
        device_class: temperature

      - name: SuctionT_A
        slave: 1
        address: 26
        unit_of_measurement: "°C"
        scale : 0.01
        precision: 3

      - name: FAN_A
        data_type : string
        slave: 1
        address: 27
        count : 4

      - name: CircuitB
        slave: 1
        address: 31
        unit_of_measurement: "%"

      - name: CircuitB_Total
        slave: 1
        address: 32 
        unit_of_measurement: "%"

      - name: DischargeP_B
        slave: 1
        address: 33
        unit_of_measurement: "kPa"
        device_class: pressure

      - name: SuctionP_B
        slave: 1
        address: 34
        unit_of_measurement: "kPa"
        device_class: pressure

      - name: DischargeT_B
        slave: 1
        address: 36
        unit_of_measurement: "°C"
        scale : 0.01
        precision: 3
        device_class: temperature

      - name: SuctionT_B
        slave: 1
        address: 38
        unit_of_measurement: "°C"
        scale : 0.01
        precision: 3
        device_class: temperature

      - name: FAN_B
        data_type : string
        slave: 1
        address: 39
        count : 4

      - name: EWT
        slave: 1
        address: 44
        unit_of_measurement: "°C"
        scale : 0.001
        precision: 3
        device_class: temperature

      - name: LWT
        slave: 1
        address: 46
        unit_of_measurement: "°C"
        scale : 0.001
        precision: 3
        device_class: temperature

      - name: reset
        slave: 1
        address: 47
        unit_of_measurement: "°C"
        scale : 0.001
        precision: 3
        device_class: temperature
        
    switches:
    - name: Pump_1

      slave: 1
      address: 48
      verify:
            input_type: holding
            address: 48
            state_on: 1
            state_off: 0
    - name: Pump_2
      slave: 1
      address: 49
      verify:
            input_type: holding
            address: 49
            state_on: 1
            state_off: 0

I find that this config slams my modbus box hard. It is unable to keep up and sensors go unavailable all the time (they become available every few seconds).
I have tried MANY MANY ways - I have tried scan rate in each sensor. Tried scan rate in general, but absolutely nothing works.

What is wrong in HA modbus implementation? Why I cannot group all read commands in one go?
What seems to be wrong in above?

PS - This is custom box(Modbus box) in which i can select what goes in what register. All are read registers. I couldnt read the binary sensor - so I had to make a switch out of it.

Hello
I found the problem - Modbus is half baked and cannot read the registers together. So, I need to read ALL the registers in one go and then fragment it into usable data.
Since I dont know anything about yaml, and the syntax has changed a lot over time, can somebody help me by giving example(using my yaml above) after reading this (How to read multiple registers)
https://community.home-assistant.io/t/modbus-how-to-read-multiple-registers-how-to-use-data-type-and-structure/234655

      - name: CircuitA
        slave: 1
        address: 19
        unit_of_measurement: "%"

      - name: CircuitA_Total
        slave: 1
        address: 20 
        unit_of_measurement: "%"

Into

      - name: ad19ad20
        slave: 1
        address: 19
        count:  2
        slave_count: 1 #  0 and 1 = 2
        unit_of_measurement: "%"

Then will be created:

  • sensor.ad19ad20
  • sensor.ad19ad20_1

If it still works that way.

My lastest test/demo

# multi read (slave_count)

modbus:

  - name: edpbox9
    type: rtuovertcp
    host: 10.1.0.37
    port: 9502
    delay: 1
    timeout: 3
    retries: 3
    retry_on_empty: true
    message_wait_milliseconds: 750

    sensors:

### ### ###

      - name: "EB9 reg38 c3" # 0x0026
        slave: 1
        address: 38
        input_type: input
        count: 3
        slave_count: 2
        data_type: uint32
        precision: 3
        scale: 0.001
        unit_of_measurement: kWh
        device_class: energy
        state_class: total_increasing
        scan_interval: 15

# EOF

I was thinking that I will let sensor names be the same (too many other dependencies)
I was more like - create temp names and put the values in.

Can you help me in rewriting this part

- platform: template
  sensors:
    outside_temperature:
        friendly_name: "Temperature"
        value_template: "{{ states('sensor.xy_md02_01').split(',')[0] }}"
    outside_humidity:
        friendly_name: "Humidity"
        value_template: "{{ states('sensor.xy_md02_01').split(',')[1] }}"

Please find mistake in this -

    sensors:
      - name: RunStateAlarm
        data_type: custom
        structure: ">2h"
        slave: 1
        address: 0
        count : 8

      - platform: template
        sensors:
          Runstate:
            value_template: "{{ states('sensor.RunStateAlarm').split(',')[0] }}"
          Alarm:
            value_template: "{{ states('sensor.RunStateAlarm').split(',')[1] }}"
         

This file below is making check config hang.

    
####MODBUS###############

# Example configuration.yaml entry
modbus:
  - name: HVAC
    type: tcp
    host: 192.168.39.14
    port: 502
    delay: 5
    retry_on_empty: true
    retries: 10

    sensors:
      - name: RunStateAlarm
        data_type: custom
        structure: ">2h"
        slave: 1
        address: 0
        count : 8

      - platform: template
        sensors:
          Runstate:
           value_template: "{{ states('sensor.RunStateAlarm').split(',')[0] }}"
          Alarm:
           value_template: "{{ states('sensor.RunStateAlarm').split(',')[1] }}"
         
modbus:

# ...

  sensors:

      - name: "EB3 0x006C" # V/A
        slave: 1
        address: 108
        input_type: input
        count: 7
        data_type: custom
        structure: ">7H"
        scan_interval: 8

### ### ###

# template sensor (new style)

template:

  - sensor:

    - name: "EB3 Import"
      state: >-
        {% set x = states('sensor.eb3_0x0016').split(',')[0] | float(0) %}
        {% if x > 0 %}
          {{ (x / 1000) | round(1) }}
        {% endif %}
      unit_of_measurement: "kWh"
      device_class: energy
      state_class: total_increasing

###

## ### ###

# eb3 sensor templates (old style)

sensor:

  - platform: template
    sensors:


# 6C

      eb3_voltage_l1:
        friendly_name: "EB3 Voltage L1"
        value_template: >-
            {% set x = states('sensor.eb3_0x006c').split(',')[0] | float(0) %}
            {% if x > 0 %}
              {{ x / 10 }}
            {% endif %}
        unit_of_measurement: "V"
        device_class: voltage

      eb3_current_l1:
        friendly_name: "EB3 Current L1"
        value_template: >-
            {% set x = states('sensor.eb3_0x006c').split(',')[1] | float(0) %}
            {% if x %}
              {{ x / 10 }}
            {% endif %}
        unit_of_measurement: "A"
        device_class: current

Thank you for writing it in new format (i just dont understand why they keep on chaning - all old forum posts become null)

Still I am unable to get the data to sesnor.
In the below example, I can get data into table1 fine.
Its the template which is giving me pain(Invalid config for [template]: expected dictionary for dictionary value @ data[‘sensors’]. Got [OrderedDict([(‘name’, ‘Total_Cap’), (‘state’, “{{ states(‘sensor.table1’).split(’,’)[0] | float(0)}}”), (‘unit_of_measurement’, ‘%’)])]. (See /config/Packages/sensors.yaml, line 212)._

My relevant lines -

      - name: "Table1" 
        slave: 1
        address: 9
        input_type: input
        count: 10
        data_type: custom
        structure: ">10H"
        scan_interval: 8
template:
  - sensors:
    - name: Total_Cap
      state: "{{ states('sensor.table1').split(',')[0] | float(0)}}"
      unit_of_measurement: "%"
#    - name: SetPoint
#      state: >-
#        "{{ states('sensor.table1').split(',')[1] | float / 1000 }}"
#      unit_of_measurement: "C"

Sorted out - yaml bit me again.
no - in sensoe

1 Like