Modbus Sensors: Allow custom format of sensor raw value

I am implementing a Modbus Connection with my Siemens LOGO within HomeAssistant.
Now, I am on a point, where I want to read some variables the LOGO is using internally to do the automation - for example, the time from a specific block which does trigger a light to be turned on or off.

LOGO does send this information in Decimal (time sunrise, time sunset)

This is the information I’m getting from the LOGO with this configuration

      - name: Sonnenaufgang (t1)
        unique_id: "t1_sunrise"
        address: 0
        input_type: holding
        #device_class: timestamp
        scan_interval: 10
        swap: word

      - name: Sonnenuntergang (t1)
        unique_id: "t1_sunset"
        address: 1
        input_type: holding
        #device_class: timestamp
        scan_interval: 10
        swap: word

It would be really great, if it would be possible to specify a “value format” within the Modbus Plattform, rather than creating an additional template Sensor for converting the Decimal value into a string like (07:07) - and then, maybe create a timestamp from this.

I could imagine something like

value_format: {{ your code to format the raw value }}

directly within the configuration of the sensor…

Please advise, if such an option already exists :wink:

the solution I would like to see for the Modbus Plattform “sensors:” would be similar to this:

  - sensor:
      - name: Sonnenuntergang
        unique_id: "t1_sunset_timestamp"
        device_class: timestamp
        state: >
          {% set x = ('%04x' % states('sensor.sonnenuntergang_t1')|int(0)) %}
          {{ today_at('%s:%s' % (x[:2],x[-2:])) }}

the “state” should be defined within the sensors configuration directly, rather than creating a sensor - and on top of that another templated sensor to transform the output.

Nice template :wink: .

I think you’d want a solution like this, with value_template directly in the modbus config:

      - name: Sonnenuntergang (t1)
        unique_id: "t1_sunset"
        address: 1
        input_type: holding
        device_class: timestamp
        scan_interval: 10
        swap: word
        value_template: >
          {% set x = ('%04x' % value|int(0)) %}
          {{ today_at('%s:%s' % (x[:2],x[-2:])) }}

The example you supplied was for a template sensor reading the modbus sensor — which is the current workaround.

1 Like

yes, thanks … I don’t know where I have this template from - just found it on the Net somewhere :wink:

1 Like

Just my two cents here.

In the past weeks I learned the following: while it might be very convenient to define individual sensors (or even have them auto-generated) by the Modbus integration, working with them individually (e.g. reading/writing) becomes inefficient very quickly and this approach practically doesn’t scale. It is only viable for very small configurations like yours - just 2 sensors. As soon as you have 10 or more registers, and/or you would like to scan them more frequently than every 10 seconds, doing this sequentially (e.g. one by one) quickly saturates the link.

A better solution is to always read all of them in a single command (provided they are laid out sequentially which is usually the case for most devices). The current integration has just the right tools for that with its structure functionality. The following example reads all 12 words with a single command and tells the integration how to parse them (at Modbus level):

    - name: H56C registers input
      slave: 0x01
      input_type: input # 0x04
      address: 0x0000
      data_type: custom
      structure: ">Hh2H3I2H"
      count: 12
      scan_interval: 2

The result is the sensor state similar to the following one:

99.00,0.00,2650.00,980.00,2597.00,20022.00,472535.00,0.00,1.00

From here on, one needs to split this into an array and format individual (template) sensors to one’s liking. E.g. template sensors would be required anyway in this case.