Replace modbus number_validator by HA standard (#108939)

This commit is contained in:
jan iversen 2024-01-27 16:39:33 +01:00 committed by GitHub
parent 858fb1fa37
commit 3cc5ffaa4b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 43 additions and 68 deletions

View File

@ -136,7 +136,6 @@ from .validators import (
check_config,
duplicate_fan_mode_validator,
nan_validator,
number_validator,
register_int_list_validator,
struct_validator,
)
@ -187,8 +186,8 @@ BASE_STRUCT_SCHEMA = BASE_COMPONENT_SCHEMA.extend(
]
),
vol.Optional(CONF_STRUCTURE): cv.string,
vol.Optional(CONF_SCALE, default=1): number_validator,
vol.Optional(CONF_OFFSET, default=0): number_validator,
vol.Optional(CONF_SCALE, default=1): cv.positive_float,
vol.Optional(CONF_OFFSET, default=0): vol.Coerce(float),
vol.Optional(CONF_PRECISION): cv.positive_int,
vol.Optional(
CONF_SWAP,
@ -242,8 +241,8 @@ CLIMATE_SCHEMA = vol.All(
{
vol.Required(CONF_TARGET_TEMP): cv.positive_int,
vol.Optional(CONF_TARGET_TEMP_WRITE_REGISTERS, default=False): cv.boolean,
vol.Optional(CONF_MAX_TEMP, default=35): number_validator,
vol.Optional(CONF_MIN_TEMP, default=5): number_validator,
vol.Optional(CONF_MAX_TEMP, default=35): cv.positive_float,
vol.Optional(CONF_MIN_TEMP, default=5): cv.positive_float,
vol.Optional(CONF_STEP, default=0.5): vol.Coerce(float),
vol.Optional(CONF_TEMPERATURE_UNIT, default=DEFAULT_TEMP_UNIT): cv.string,
vol.Optional(CONF_HVAC_ONOFF_REGISTER): cv.positive_int,
@ -343,10 +342,10 @@ SENSOR_SCHEMA = vol.All(
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
vol.Exclusive(CONF_VIRTUAL_COUNT, "vir_sen_count"): cv.positive_int,
vol.Exclusive(CONF_SLAVE_COUNT, "vir_sen_count"): cv.positive_int,
vol.Optional(CONF_MIN_VALUE): number_validator,
vol.Optional(CONF_MAX_VALUE): number_validator,
vol.Optional(CONF_MIN_VALUE): cv.positive_float,
vol.Optional(CONF_MAX_VALUE): cv.positive_float,
vol.Optional(CONF_NAN_VALUE): nan_validator,
vol.Optional(CONF_ZERO_SUPPRESS): number_validator,
vol.Optional(CONF_ZERO_SUPPRESS): cv.positive_float,
}
),
)

View File

@ -182,12 +182,25 @@ class BaseStructPlatform(BasePlatform, RestoreEntity):
self._data_type = config[CONF_DATA_TYPE]
self._structure: str = config[CONF_STRUCTURE]
self._scale = config[CONF_SCALE]
self._precision = config.get(CONF_PRECISION, 2 if self._scale < 1 else 0)
self._precision = config.get(CONF_PRECISION, 2)
self._offset = config[CONF_OFFSET]
self._slave_count = config.get(CONF_SLAVE_COUNT, None) or config.get(
CONF_VIRTUAL_COUNT, 0
)
self._slave_size = self._count = config[CONF_COUNT]
self._value_is_int: bool = self._data_type in (
DataType.INT16,
DataType.INT32,
DataType.INT64,
DataType.UINT16,
DataType.UINT32,
DataType.UINT64,
)
if self._value_is_int:
if self._min_value:
self._min_value = round(self._min_value)
if self._max_value:
self._max_value = round(self._max_value)
def _swap_registers(self, registers: list[int], slave_count: int) -> list[int]:
"""Do swap as needed."""
@ -227,7 +240,7 @@ class BaseStructPlatform(BasePlatform, RestoreEntity):
return str(self._max_value)
if self._zero_suppress is not None and abs(val) <= self._zero_suppress:
return "0"
if self._precision == 0:
if self._precision == 0 or self._value_is_int:
return str(int(round(val, 0)))
return f"{float(val):.{self._precision}f}"

View File

@ -125,7 +125,10 @@ class ModbusRegisterSensor(BaseStructPlatform, RestoreSensor, SensorEntity):
if self._coordinator:
if result:
result_array = list(
map(float if self._precision else int, result.split(","))
map(
float if not self._value_is_int else int,
result.split(","),
)
)
self._attr_native_value = result_array[0]
self._coordinator.async_set_updated_data(result_array)

View File

@ -172,23 +172,6 @@ def struct_validator(config: dict[str, Any]) -> dict[str, Any]:
}
def number_validator(value: Any) -> int | float:
"""Coerce a value to number without losing precision."""
if isinstance(value, int):
return value
if isinstance(value, float):
return value
try:
return int(value)
except (TypeError, ValueError):
pass
try:
return float(value)
except (TypeError, ValueError) as err:
raise vol.Invalid(f"invalid number {value}") from err
def nan_validator(value: Any) -> int:
"""Convert nan string to number (can be hex string or int)."""
if isinstance(value, int):

View File

@ -83,7 +83,6 @@ from homeassistant.components.modbus.validators import (
duplicate_fan_mode_validator,
duplicate_modbus_validator,
nan_validator,
number_validator,
register_int_list_validator,
struct_validator,
)
@ -157,28 +156,6 @@ async def test_register_int_list_validator() -> None:
register_int_list_validator(["aq"])
async def test_number_validator() -> None:
"""Test number validator."""
for value, value_type in (
(15, int),
(15.1, float),
("15", int),
("15.1", float),
(-15, int),
(-15.1, float),
("-15", int),
("-15.1", float),
):
assert isinstance(number_validator(value), value_type)
try:
number_validator("x15.1")
except vol.Invalid:
return
pytest.fail("Number_validator not throwing exception")
async def test_nan_validator() -> None:
"""Test number validator."""

View File

@ -357,7 +357,7 @@ async def test_config_wrong_struct_sensor(
},
[7],
False,
"34.0000",
"34",
),
(
{
@ -379,7 +379,7 @@ async def test_config_wrong_struct_sensor(
},
[9],
False,
"18.5",
"18",
),
(
{
@ -390,7 +390,7 @@ async def test_config_wrong_struct_sensor(
},
[1],
False,
"2.40",
"2",
),
(
{
@ -401,7 +401,7 @@ async def test_config_wrong_struct_sensor(
},
[2],
False,
"-8.3",
"-8",
),
(
{
@ -445,7 +445,7 @@ async def test_config_wrong_struct_sensor(
},
[0x89AB, 0xCDEF, 0x0123, 0x4567],
False,
"9920249030613615975",
"9920249030613616640",
),
(
{
@ -456,7 +456,7 @@ async def test_config_wrong_struct_sensor(
},
[0x0123, 0x4567, 0x89AB, 0xCDEF],
False,
"163971058432973793",
"163971058432973792",
),
(
{
@ -676,7 +676,7 @@ async def test_config_wrong_struct_sensor(
},
[0x00AB, 0xCDEF],
False,
"112593.75",
"112594",
),
(
{
@ -686,7 +686,7 @@ async def test_config_wrong_struct_sensor(
},
[0x00AB, 0xCDEF],
False,
"112593.75",
"112594",
),
],
)
@ -727,7 +727,7 @@ async def test_all_sensor(hass: HomeAssistant, mock_do_cycle, expected) -> None:
int.from_bytes(struct.pack(">f", float("nan"))[2:4]),
],
False,
["34899771392", "0"],
["34899771392.0", "0.0"],
),
(
{
@ -742,7 +742,7 @@ async def test_all_sensor(hass: HomeAssistant, mock_do_cycle, expected) -> None:
int.from_bytes(struct.pack(">f", float("nan"))[2:4]),
],
False,
["34899771392", "0"],
["34899771392.0", "0.0"],
),
(
{
@ -937,7 +937,7 @@ async def test_virtual_sensor(
},
[0x0102, 0x0304, 0x0506, 0x0708],
False,
[str(0x0708050603040102)],
[str(0x0708050603040100)],
),
(
{
@ -970,7 +970,7 @@ async def test_virtual_sensor(
},
[0x0102, 0x0304, 0x0506, 0x0708, 0x0901, 0x0902, 0x0903, 0x0904],
False,
[str(0x0708050603040102), str(0x0904090309020901)],
[str(0x0708050603040100), str(0x0904090309020900)],
),
(
{
@ -1035,10 +1035,10 @@ async def test_virtual_sensor(
],
False,
[
str(0x0604060306020601),
str(0x0704070307020701),
str(0x0804080308020801),
str(0x0904090309020901),
str(0x0604060306020600),
str(0x0704070307020700),
str(0x0804080308020800),
str(0x0904090309020900),
],
),
],
@ -1202,7 +1202,7 @@ async def test_unpack_ok(hass: HomeAssistant, mock_do_cycle, expected) -> None:
0x0000,
0x000A,
],
"0,10",
"0,10.00",
),
(
{