Apply Precision/Scale/Offset to struct in modbus sensor (#48544)

The single values in struct are corrected with presicion, scale and offset,
just as it is done with single values.
This commit is contained in:
jan iversen 2021-04-16 22:33:58 +02:00 committed by GitHub
parent 65d092f1cc
commit ea9641f980
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 1 deletions

View File

@ -319,7 +319,19 @@ class ModbusRegisterSensor(RestoreEntity, SensorEntity):
# If unpack() returns a tuple greater than 1, don't try to process the value.
# Instead, return the values of unpack(...) separated by commas.
if len(val) > 1:
self._value = ",".join(map(str, val))
# Apply scale and precision to floats and ints
v_result = []
for entry in val:
v_temp = self._scale * entry + self._offset
# We could convert int to float, and the code would still work; however
# we lose some precision, and unit tests will fail. Therefore, we do
# the conversion only when it's absolutely necessary.
if isinstance(v_temp, int) and self._precision == 0:
v_result.append(str(v_temp))
else:
v_result.append(f"{float(v_temp):.{self._precision}f}")
self._value = ",".join(map(str, v_result))
else:
val = val[0]

View File

@ -12,6 +12,7 @@ from homeassistant.components.modbus.const import (
CONF_REGISTERS,
CONF_REVERSE_ORDER,
CONF_SCALE,
DATA_TYPE_CUSTOM,
DATA_TYPE_FLOAT,
DATA_TYPE_INT,
DATA_TYPE_STRING,
@ -26,6 +27,7 @@ from homeassistant.const import (
CONF_OFFSET,
CONF_SENSORS,
CONF_SLAVE,
CONF_STRUCTURE,
)
from .conftest import base_config_test, base_test
@ -338,6 +340,7 @@ async def test_config_sensor(hass, do_discovery, do_config):
)
async def test_all_sensor(hass, cfg, regs, expected):
"""Run test for sensor."""
sensor_name = "modbus_test_sensor"
state = await base_test(
hass,
@ -352,3 +355,41 @@ async def test_all_sensor(hass, cfg, regs, expected):
scan_interval=5,
)
assert state == expected
async def test_struct_sensor(hass):
"""Run test for sensor struct."""
sensor_name = "modbus_test_sensor"
# floats: 7.931250095367432, 10.600000381469727,
# 1.000879611487865e-28, 10.566553115844727
expected = "7.93,10.60,0.00,10.57"
state = await base_test(
hass,
{
CONF_NAME: sensor_name,
CONF_REGISTER: 1234,
CONF_COUNT: 8,
CONF_PRECISION: 2,
CONF_DATA_TYPE: DATA_TYPE_CUSTOM,
CONF_STRUCTURE: ">4f",
},
sensor_name,
SENSOR_DOMAIN,
CONF_SENSORS,
CONF_REGISTERS,
[
0x40FD,
0xCCCD,
0x4129,
0x999A,
0x10FD,
0xC0CD,
0x4129,
0x109A,
],
expected,
method_discovery=False,
scan_interval=5,
)
assert state == expected