Skip to content

Commit

Permalink
Replace modbus number_validator by HA standard (#108939)
Browse files Browse the repository at this point in the history
  • Loading branch information
janiversen committed Jan 27, 2024
1 parent 858fb1f commit 3cc5ffa
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 68 deletions.
15 changes: 7 additions & 8 deletions homeassistant/components/modbus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@
check_config,
duplicate_fan_mode_validator,
nan_validator,
number_validator,
register_int_list_validator,
struct_validator,
)
Expand Down Expand Up @@ -187,8 +186,8 @@
]
),
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,
Expand Down Expand Up @@ -242,8 +241,8 @@
{
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,
Expand Down Expand Up @@ -343,10 +342,10 @@
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,
}
),
)
Expand Down
17 changes: 15 additions & 2 deletions homeassistant/components/modbus/base_platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,12 +182,25 @@ def __init__(self, hass: HomeAssistant, hub: ModbusHub, config: dict) -> None:
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."""
Expand Down Expand Up @@ -227,7 +240,7 @@ def __process_raw_value(self, entry: float | int | str | bytes) -> str | None:
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}"

Expand Down
5 changes: 4 additions & 1 deletion homeassistant/components/modbus/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,10 @@ async def async_update(self, now: datetime | None = None) -> None:
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)
Expand Down
17 changes: 0 additions & 17 deletions homeassistant/components/modbus/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
23 changes: 0 additions & 23 deletions tests/components/modbus/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@
duplicate_fan_mode_validator,
duplicate_modbus_validator,
nan_validator,
number_validator,
register_int_list_validator,
struct_validator,
)
Expand Down Expand Up @@ -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."""

Expand Down
34 changes: 17 additions & 17 deletions tests/components/modbus/test_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ async def test_config_wrong_struct_sensor(
},
[7],
False,
"34.0000",
"34",
),
(
{
Expand All @@ -379,7 +379,7 @@ async def test_config_wrong_struct_sensor(
},
[9],
False,
"18.5",
"18",
),
(
{
Expand All @@ -390,7 +390,7 @@ async def test_config_wrong_struct_sensor(
},
[1],
False,
"2.40",
"2",
),
(
{
Expand All @@ -401,7 +401,7 @@ async def test_config_wrong_struct_sensor(
},
[2],
False,
"-8.3",
"-8",
),
(
{
Expand Down Expand Up @@ -445,7 +445,7 @@ async def test_config_wrong_struct_sensor(
},
[0x89AB, 0xCDEF, 0x0123, 0x4567],
False,
"9920249030613615975",
"9920249030613616640",
),
(
{
Expand All @@ -456,7 +456,7 @@ async def test_config_wrong_struct_sensor(
},
[0x0123, 0x4567, 0x89AB, 0xCDEF],
False,
"163971058432973793",
"163971058432973792",
),
(
{
Expand Down Expand Up @@ -676,7 +676,7 @@ async def test_config_wrong_struct_sensor(
},
[0x00AB, 0xCDEF],
False,
"112593.75",
"112594",
),
(
{
Expand All @@ -686,7 +686,7 @@ async def test_config_wrong_struct_sensor(
},
[0x00AB, 0xCDEF],
False,
"112593.75",
"112594",
),
],
)
Expand Down Expand Up @@ -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"],
),
(
{
Expand All @@ -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"],
),
(
{
Expand Down Expand Up @@ -937,7 +937,7 @@ async def test_virtual_sensor(
},
[0x0102, 0x0304, 0x0506, 0x0708],
False,
[str(0x0708050603040102)],
[str(0x0708050603040100)],
),
(
{
Expand Down Expand Up @@ -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)],
),
(
{
Expand Down Expand Up @@ -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),
],
),
],
Expand Down Expand Up @@ -1202,7 +1202,7 @@ async def test_unpack_ok(hass: HomeAssistant, mock_do_cycle, expected) -> None:
0x0000,
0x000A,
],
"0,10",
"0,10.00",
),
(
{
Expand Down

0 comments on commit 3cc5ffa

Please sign in to comment.