mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Replace modbus number_validator by HA standard (#108939)
This commit is contained in:
parent
858fb1fa37
commit
3cc5ffaa4b
@ -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,
|
||||
}
|
||||
),
|
||||
)
|
||||
|
@ -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}"
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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):
|
||||
|
@ -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."""
|
||||
|
||||
|
@ -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",
|
||||
),
|
||||
(
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user