[modbus] Reject send_wait_time and turnaround_time above 65535 ms (#20160)

This commit is contained in:
Bascht74
2026-10-05 08:46:36 -05:00
committed by GitHub
parent bbd05e4811
commit 862047386c
2 changed files with 23 additions and 7 deletions
+8 -6
View File
@@ -52,6 +52,12 @@ CONF_TURNAROUND_TIME = "turnaround_time"
MODBUS_ROLES = ["client", "server"]
# The client hub takes these times as 16-bit milliseconds; a Modbus timeout is far shorter anyway.
_HUB_TIME_PERIOD = cv.All(
cv.positive_time_period_milliseconds,
cv.Range(max=cv.TimePeriod(milliseconds=65535)),
)
# The write (mutating) function codes, matching modbus::helpers::is_function_code_write(). 0x17
# (read/write multiple) is included: it mutates, so the hub treats it as a write despite its read half.
@@ -273,12 +279,8 @@ CONFIG_SCHEMA = cv.typed_schema(
{
cv.GenerateID(): cv.declare_id(ModbusClient),
cv.Optional(CONF_FLOW_CONTROL_PIN): pins.gpio_output_pin_schema,
cv.Optional(
CONF_SEND_WAIT_TIME, default="2000ms"
): cv.positive_time_period_milliseconds,
cv.Optional(
CONF_TURNAROUND_TIME, default="600ms"
): cv.positive_time_period_milliseconds,
cv.Optional(CONF_SEND_WAIT_TIME, default="2000ms"): _HUB_TIME_PERIOD,
cv.Optional(CONF_TURNAROUND_TIME, default="600ms"): _HUB_TIME_PERIOD,
}
)
.extend(cv.COMPONENT_SCHEMA)
+15 -1
View File
@@ -4,7 +4,11 @@ import pytest
from esphome import config_validation as cv
from esphome.components import modbus
from esphome.components.modbus import CONF_MODBUS_ID, _validate_server_address
from esphome.components.modbus import (
_HUB_TIME_PERIOD,
CONF_MODBUS_ID,
_validate_server_address,
)
from esphome.const import CONF_ADDRESS
@@ -36,3 +40,13 @@ def test_client_schema_still_accepts_address_zero() -> None:
# A client may address 0: writes are broadcast, and reads are allowed with allow_broadcast_read.
schema = modbus.modbus_device_schema(0x01)
assert schema({CONF_MODBUS_ID: "hub", CONF_ADDRESS: 0})[CONF_ADDRESS] == 0
def test_hub_time_accepts_up_to_65535_ms() -> None:
assert _HUB_TIME_PERIOD("65535ms").total_milliseconds == 65535
def test_hub_time_rejects_values_the_hub_would_truncate() -> None:
# The setters take 16-bit milliseconds: 70 s would silently become 4464 ms.
with pytest.raises(cv.Invalid):
_HUB_TIME_PERIOD("70s")