Thanks for the help. I will start experimenting.
Well, unless I missed the point entirely, the sensor reports 1909, result of a bogus hex to dec conversion of 775, and the point was to get 775 back
Converting decimal to hex can be done with the format
function. Two ways to do it:
The second way was suggested to the OP in another post (where I also presented a hex to decimal conversion ).
Sheesh, I’m really off my game today. Time to push away from the keyboard!
Thanks for the efforts. I appreciate all the ways and options to try different things.
Hey there!
Thanks for mentioning my post. Looking at initial question and my configs I found similar sensor in my network - there is no need to convert it in jinja or with math function as modbus already does it.
- name: hex_sensor
slave: 2
address: 0
count: 2
input_type: input
data_type: custom
structure: ">2h"
scan_interval: 20
If you look in to the source then you’ll find out that its actually straight call to the ‘struct’ Python function. Its actually powerful and compact utility function to work with network data. Take a look at documentation - struct — Interpret bytes as packed binary data — Python 3.9.6 documentation
Not sure why Jan or someone who contributes to the modbus module did not put a link to the functions in HA documentation.
Then you have converted value without decimal that I validate and divide by 10 in a template value:
foo_v:
friendly_name: Foo Voltage
value_template: >-
{% set valid = not is_state('sensor.hex_sensor', 'unavailable') %}
{% set values = states('sensor.hex_sensor').split(',') %}
{{ (values[0]|float / 10) if valid else 'unavailable' }}
icon_template: mdi:sine-wave
unit_of_measurement: V
This approach is also good for debug - when you see wrong data you can dig in to original value received by modbus before conversion. And for the end user you have nice value from template.
I usually keep separate hidden tab with all values from RS485 network. This help to identify RS485 problems by network segment.
Hope this helps.
Rostislav
Sorry, but I don’t think struct would help here.
It is used for unpacking C structs. You seem to be reading 2 registers and interpreting that as 2 short integers.
$ python3
Python 3.8.10 (default, Jun 2 2021, 10:49:15)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
+ >>> import struct
+ >>> struct.unpack(">2h", b'\x00\x03\x01\x01')
(3, 257)
Unless I’m missing something, this won’t help us convert the number to hex.
Thank you for posting that! I suspected there had to be a way for the Modbus integration to convert received values, including hexadecimal values.
Can you check if adding scale: 0.1
will effectively divide the converted value by 10? The documentation indicates that the scale
value is used to multiply the received value. If it works then the Template Sensor isn’t strictly required.
I would try it myself but I have no Modbus devices.
What you got from Modbus? Can you read values with some util, like QModMaster? If yes then post screenshots here.
Struct is flexible, you can read 4 bytes with “i” or unsigned with “I”. Also check there is “>” and “<” for little and big endian.
">I" or "<I"
I think scale works only if you read float. Anyway you need to validate date. Just sending data straight in to triggers is crazy idea. Even modbus message checksum validation passed sometimes temperature sensors give -500, this will make false alarms.