Correct modbus config validator: slave/swap (#97798)

This commit is contained in:
jan iversen 2023-08-18 10:55:39 +02:00 committed by GitHub
parent e42b9e6c4c
commit 59d37f65d5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 31 deletions

View file

@ -65,25 +65,14 @@ def struct_validator(config: dict[str, Any]) -> dict[str, Any]:
name = config[CONF_NAME]
structure = config.get(CONF_STRUCTURE)
slave_count = config.get(CONF_SLAVE_COUNT, 0) + 1
swap_type = config.get(CONF_SWAP)
if config[CONF_DATA_TYPE] != DataType.CUSTOM:
if structure:
error = f"{name} structure: cannot be mixed with {data_type}"
slave = config.get(CONF_SLAVE, 0)
swap_type = config.get(CONF_SWAP, CONF_SWAP_NONE)
if config[CONF_DATA_TYPE] == DataType.CUSTOM:
if slave or slave_count > 1:
error = f"{name}: `{CONF_STRUCTURE}` illegal with `{CONF_SLAVE_COUNT}` / `{CONF_SLAVE}`"
raise vol.Invalid(error)
if data_type not in DEFAULT_STRUCT_FORMAT:
error = f"Error in sensor {name}. data_type `{data_type}` not supported"
raise vol.Invalid(error)
structure = f">{DEFAULT_STRUCT_FORMAT[data_type].struct_id}"
if CONF_COUNT not in config:
config[CONF_COUNT] = DEFAULT_STRUCT_FORMAT[data_type].register_count
if slave_count > 1:
structure = f">{slave_count}{DEFAULT_STRUCT_FORMAT[data_type].struct_id}"
else:
structure = f">{DEFAULT_STRUCT_FORMAT[data_type].struct_id}"
else:
if slave_count > 1:
error = f"{name} structure: cannot be mixed with {CONF_SLAVE_COUNT}"
if swap_type != CONF_SWAP_NONE:
error = f"{name}: `{CONF_STRUCTURE}` illegal with `{CONF_SWAP}`"
raise vol.Invalid(error)
if not structure:
error = (
@ -102,19 +91,43 @@ def struct_validator(config: dict[str, Any]) -> dict[str, Any]:
f"Structure request {size} bytes, "
f"but {count} registers have a size of {bytecount} bytes"
)
return {
**config,
CONF_STRUCTURE: structure,
CONF_SWAP: swap_type,
}
if swap_type != CONF_SWAP_NONE:
if swap_type == CONF_SWAP_BYTE:
regs_needed = 1
else: # CONF_SWAP_WORD_BYTE, CONF_SWAP_WORD
regs_needed = 2
if count < regs_needed or (count % regs_needed) != 0:
raise vol.Invalid(
f"Error in sensor {name} swap({swap_type}) "
"not possible due to the registers "
f"count: {count}, needed: {regs_needed}"
)
if structure:
error = f"{name} structure: cannot be mixed with {data_type}"
raise vol.Invalid(error)
if data_type not in DEFAULT_STRUCT_FORMAT:
error = f"Error in sensor {name}. data_type `{data_type}` not supported"
raise vol.Invalid(error)
if (slave or slave_count > 1) and data_type == DataType.STRING:
error = (
f"{name}: `{data_type}` illegal with `{CONF_SLAVE_COUNT}` / `{CONF_SLAVE}`"
)
raise vol.Invalid(error)
if CONF_COUNT not in config:
config[CONF_COUNT] = DEFAULT_STRUCT_FORMAT[data_type].register_count
if swap_type != CONF_SWAP_NONE:
if swap_type == CONF_SWAP_BYTE:
regs_needed = 1
else: # CONF_SWAP_WORD_BYTE, CONF_SWAP_WORD
regs_needed = 2
count = config[CONF_COUNT]
if count < regs_needed or (count % regs_needed) != 0:
raise vol.Invalid(
f"Error in sensor {name} swap({swap_type}) "
"not possible due to the registers "
f"count: {count}, needed: {regs_needed}"
)
structure = f">{DEFAULT_STRUCT_FORMAT[data_type].struct_id}"
if slave_count > 1:
structure = f">{slave_count}{DEFAULT_STRUCT_FORMAT[data_type].struct_id}"
else:
structure = f">{DEFAULT_STRUCT_FORMAT[data_type].struct_id}"
return {
**config,
CONF_STRUCTURE: structure,

View file

@ -181,7 +181,6 @@ async def test_nan_validator() -> None:
CONF_COUNT: 2,
CONF_DATA_TYPE: DataType.CUSTOM,
CONF_STRUCTURE: ">i",
CONF_SWAP: CONF_SWAP_BYTE,
},
],
)
@ -239,6 +238,16 @@ async def test_ok_struct_validator(do_config) -> None:
CONF_STRUCTURE: ">f",
CONF_SLAVE_COUNT: 5,
},
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_DATA_TYPE: DataType.STRING,
CONF_SLAVE_COUNT: 2,
},
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_DATA_TYPE: DataType.INT16,
CONF_SWAP: CONF_SWAP_WORD,
},
],
)
async def test_exception_struct_validator(do_config) -> None:

View file

@ -246,7 +246,7 @@ async def test_config_sensor(hass: HomeAssistant, mock_modbus) -> None:
},
]
},
f"Error in sensor {TEST_ENTITY_NAME} swap(word) not possible due to the registers count: 1, needed: 2",
f"{TEST_ENTITY_NAME}: `structure` illegal with `swap`",
),
],
)