Ok, New issue. Apparently my PLC is sending hex values in it’s register. I to have to convert them into a decimal with an online calc. I have value 2329 in my plc register and home assistant sees it as 9001. The calc. confirmed that. Hmm. Is there a way to do the math?
The PLC is sending binary data. It is up to the receiver how to display it (and even how to interpret it – it could be a float for example).
You are reading value this on the PLC itself, right? I guess it just displays everything in hex.
I don’t know what the number you are reading is supposed to mean, so I’ll just assume you just want it displayed in hex.
You should be able to convert the state of a sensor to hex with this template: {{ "%0x" % (states('sensor.sensor_name') | int) }}
. I guess you’ll have to use it in a template sensor.
Basically I am reading the timer value on T0 register from the Koyo directlogic 06 PLC . The number in the timer in the Directsoft software on the ladder timer block is 2329. When home assistant reads it under sensor, it determines the number is 9001. I would like to get the 2329 number as displayed on my controller timer register location. I am not exactly sure what is going on yet. I mostly work with Allen Bradley controllers and software so I am still figuring this out. I assume that the value is getting converted from hex to decimal. I thought by reading a input register from the Modbus would directly read what is in the register. Still trying to wrap my head around it to fully explain what is going on.
Exactly. There are 16 bits of binary data in the register. It’s up to you to interpret it (Is it a signed integer? Unsigned integer? Float?) and display it (the number 10 in decimal can also be displayed as 0xA hex, 012 octal and so on).
To get 2329, you’ll need to create a template sensor that reads the decimal value 9001 from your modbus sensor and converts it to hex:
template:
- sensor:
- name: "hex value"
unit_of_measurement: ""
state: '{{ "%0x" % (states("sensor.sensor_decimal") | int) }}'
Replace sensor_decimal
with the name of your sensor.
Is this right? I am getting value 0 on hex value. I feel so inept with this YAML coding.
modbus:
- name: hub1
type: tcp
host: 192.168.1.243
port: 502
switches:
- name: Switch33
slave: 255
address: 3074
write_type: coil
verify:
binary_sensors:
- name: "Pool_Pump"
address: 3074
scan_interval: 10
slave: 255
device_class: moving
input_type: coil
sensors:
- name: Timer1
slave: 255
address: 256
data_type: int # or float
unit_of_measurement: "Time"
template:
- sensor:
- name: "hex value"
unit_of_measurement: ""
state: '{{ "%0x" % (states("Timer1") | int) }}'
Nope, that should be state: '{{ "%0x" % (states("sensor.timer1") | int) }}'
I just put this in and nothing under Modbus works now. Hmm, sure I’m not missing something more? Thanks.
modbus:
- name: hub1
type: tcp
host: 192.168.1.243
port: 502
switches:
- name: Switch33
slave: 255
address: 3074
write_type: coil
verify:
binary_sensors:
- name: "Pool_Pump"
address: 3074
scan_interval: 10
slave: 255
device_class: moving
input_type: coil
sensors:
- name: Timer1
slave: 255
address: 256
data_type: int # or float
unit_of_measurement: ""
template:
- sensor:
- name: "hex value"
unit_of_measurement: ""
state: '{{ "%0x" % (states("sensor.Timer1") | int) }}'
Check your logs. Maybe you already had a template:
section somewhere in your configuration.yaml (or !include
d files).
Some errors, not sure what they mean. Pretty vague.
Pymodbus: Modbus Error: [Input/Output] [Errno 32] Broken pipe
6:14:03 PM – (ERROR) Modbus
Setup of sensor platform modbus is taking over 10 seconds.
6:14:03 PM – (WARNING) Sensor - message first occurred at 6:14:03 PM and shows up 2 times
Setup of switch platform modbus is taking over 10 seconds.
6:14:03 PM – (WARNING) Switch
Setup of binary_sensor platform modbus is taking over 10 seconds.
6:14:03 PM – (WARNING) Binary sensor
Error doing job: Unclosed client session
6:13:49 PM – (ERROR) runner.py
No idea, sorry. Does not seem to be related to the template sensor you added. Try restarting Home Assistant.
Any idea why half the time on a restart of HA, entities for the Modbus are unavailable? I then restart and they will be working. Very odd.
Maybe you have to wait for the TCP connection to time out or something. Instead of a restart, try stopping HA, wait for 15 seconds or so and start it again.
Thank you for you suggestion.
Getting back to the template issue. I did find this error in the log that I missed before. Any idea?
Template variable error: 'sensor' is undefined when rendering '{{ "%0x" % (states(sensor.pool_temp) | int) }}'
TemplateError('UndefinedError: 'sensor' is undefined') while processing template 'Template("{{ "%0x" % (states(sensor.pool_temp) | int) }}")' for attribute '_attr_state' in entity 'sensor.hex_value'
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 389, in async_render
render_result = _render_with_context(self.template, compiled, **kwargs)
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 1358, in _render_with_context
return template.render(**kwargs)
File "/usr/local/lib/python3.9/site-packages/jinja2/environment.py", line 1304, in render
self.environment.handle_exception()
File "/usr/local/lib/python3.9/site-packages/jinja2/environment.py", line 925, in handle_exception
raise rewrite_traceback_stack(source=source)
File "<template>", line 1, in top-level template code
File "/usr/local/lib/python3.9/site-packages/jinja2/sandbox.py", line 326, in getattr
value = getattr(obj, attribute)
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 1382, in _fail_with_undefined_error
raise ex
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 1374, in _fail_with_undefined_error
return super()._fail_with_undefined_error(*args, **kwargs)
jinja2.exceptions.UndefinedError: 'sensor' is undefined
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 505, in async_render_to_info
render_info._result = self.async_render(variables, strict=strict, **kwargs)
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 391, in async_render
raise TemplateError(err) from err
homeassistant.exceptions.TemplateError: UndefinedError: 'sensor' is undefined
`modbus:
- name: hub1
type: tcp
host: 192.168.1.243
port: 502
` sensors:
- name: Pool Temp
address: 1024
scan_interval: 10
slave: 255
data_type: int # int or float
unit_of_measurement: "°F"
template:
- sensor:
- name: "hex value"
unit_of_measurement: "°F"
state: '{{ "%0x" % (states(sensor.pool_temp) | int) }}'
sensor.pool_temp
inside states()
needs to be inside quotes to be a string (otherwise, the template is looking for a variable named sensor
, which does not exist).
Like this?
state: '{{ "%0x" % (states("sensor.pool_temp") | int) }}'
Yes, that should work.
You rock…
That did it.
I now need to add a decimal to the value of the temp sensor. It is supposed to read 74.3
Maybe something like this:
state: '{{ ("%0x" % (states("sensor.pool_temp") | int)) | int / 10 }}'
Boomshakalaka… That was it…HAHA
If you lived close Id take you out for a few beers. Thanks so much.
How do you know this coding? Is there a site online to learn this or to understand these formulas?
FWIW, you can specify the number base in the int
function.
state: "{{ ('0x' ~ states('sensor.pool_temp')) | int(base=16) / 10 }}"