mirror of
https://github.com/home-assistant/core.git
synced 2026-09-26 17:31:15 -04:00
Bump modbus-connection to 4.12.0 (#182149)
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude
parent
09e3474f91
commit
48671e144c
@@ -34,6 +34,27 @@ DATA_MODBUS_CONNECTIONS: HassKey[dict[ModbusEndpoint, _SharedConnection]] = Hass
|
||||
)
|
||||
|
||||
|
||||
def _canonical(params: ModbusParams) -> ModbusParams:
|
||||
"""Return the params in the form the link is actually built from.
|
||||
|
||||
RTU and ASCII frame a serial line, so `ModbusTcpParams` carrying one builds
|
||||
the serial link over a `socket://` device that `ModbusSerialParams` names
|
||||
directly. Both spellings of that link have to reach the same connection.
|
||||
"""
|
||||
if not isinstance(params, ModbusTcpParams) or params.framer not in ("rtu", "ascii"):
|
||||
return params
|
||||
# An IPv6 literal is bracketed, or its own colons read as the port separator.
|
||||
host = f"[{params.host}]" if ":" in params.host else params.host
|
||||
return ModbusSerialParams(
|
||||
device=f"socket://{host}:{params.port}",
|
||||
framer=params.framer,
|
||||
# The line speed modbus-connection gives a socket-carried serial framing.
|
||||
# It is fast enough to land on tmodbus's 1.75 ms inter-frame gap floor,
|
||||
# which any value at or above 19200 baud also gets.
|
||||
baudrate=115200,
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class _SharedConnection:
|
||||
"""A connection and the units held on it."""
|
||||
@@ -77,6 +98,7 @@ def _async_acquire(
|
||||
Raises `HomeAssistantError` if the device is already in use over different
|
||||
link settings, which cannot both be honoured on one connection.
|
||||
"""
|
||||
params = _canonical(params)
|
||||
endpoint = params.endpoint
|
||||
connections = hass.data.setdefault(DATA_MODBUS_CONNECTIONS, {})
|
||||
if (shared := connections.get(endpoint)) is None:
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"loggers": ["pymodbus"],
|
||||
"requirements": [
|
||||
"pymodbus==3.13.1",
|
||||
"modbus-connection[tmodbus]==4.11.1",
|
||||
"modbus-connection[tmodbus]==4.12.0",
|
||||
"tmodbus==0.6.2"
|
||||
]
|
||||
}
|
||||
|
||||
Generated
+1
-1
@@ -1641,7 +1641,7 @@ mitsubishi-comfort==0.5.2
|
||||
moat-ble==0.1.1
|
||||
|
||||
# homeassistant.components.modbus
|
||||
modbus-connection[tmodbus]==4.11.1
|
||||
modbus-connection[tmodbus]==4.12.0
|
||||
|
||||
# homeassistant.components.moehlenhoff_alpha2
|
||||
moehlenhoff-alpha2==1.4.0
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
from collections.abc import Callable, Generator
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from modbus_connection import ModbusSerialParams, ModbusTcpParams
|
||||
from modbus_connection import ModbusSerialParams, ModbusTcpParams, ModbusTlsParams
|
||||
from modbus_connection.tmodbus import ModbusConnection
|
||||
import pytest
|
||||
|
||||
@@ -100,6 +100,63 @@ async def test_the_same_device_reached_by_a_different_name_still_shares(
|
||||
assert len(hass.data[DATA_MODBUS_CONNECTIONS]) == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"device",
|
||||
[
|
||||
pytest.param("socket://1.2.3.4:502", id="ipv4"),
|
||||
pytest.param("socket://[fe80::1]:502", id="ipv6"),
|
||||
],
|
||||
)
|
||||
async def test_a_serial_framing_over_a_socket_shares_the_serial_link(
|
||||
hass: HomeAssistant, consumer: ConsumerFactory, device: str
|
||||
) -> None:
|
||||
"""A serial framing on a TCP link is the serial link the socket device names.
|
||||
|
||||
Both spellings build one link at one line speed, so splitting them would put
|
||||
a second connection on a gateway that can only answer one.
|
||||
"""
|
||||
entry = consumer()
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
host = device.removeprefix("socket://").rpartition(":")[0].strip("[]")
|
||||
|
||||
async_get_unit(
|
||||
hass, entry, ModbusSerialParams(device=device, framer="rtu", baudrate=115200), 1
|
||||
)
|
||||
with pytest.deprecated_call():
|
||||
async_get_unit(
|
||||
hass, entry, ModbusTcpParams(host=host, port=502, framer="rtu"), 2
|
||||
)
|
||||
|
||||
assert len(hass.data[DATA_MODBUS_CONNECTIONS]) == 1
|
||||
|
||||
|
||||
async def test_a_serial_framing_over_a_socket_keeps_the_line_speed_asked_for(
|
||||
hass: HomeAssistant, consumer: ConsumerFactory
|
||||
) -> None:
|
||||
"""The framing alone says nothing about the line speed, so it cannot assume one.
|
||||
|
||||
A slower line needs a longer gap between frames, which the connection built
|
||||
for the faster one does not leave.
|
||||
"""
|
||||
entry = consumer()
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
|
||||
async_get_unit(
|
||||
hass,
|
||||
entry,
|
||||
ModbusSerialParams(device="socket://1.2.3.4:502", framer="rtu", baudrate=9600),
|
||||
1,
|
||||
)
|
||||
|
||||
with (
|
||||
pytest.deprecated_call(),
|
||||
pytest.raises(HomeAssistantError, match="different link settings"),
|
||||
):
|
||||
async_get_unit(
|
||||
hass, entry, ModbusTcpParams(host="1.2.3.4", port=502, framer="rtu"), 2
|
||||
)
|
||||
|
||||
|
||||
async def test_one_device_cannot_be_used_with_two_link_settings(
|
||||
hass: HomeAssistant, consumer: ConsumerFactory
|
||||
) -> None:
|
||||
@@ -114,9 +171,7 @@ async def test_one_device_cannot_be_used_with_two_link_settings(
|
||||
async_get_unit(hass, entry, ModbusTcpParams(host="1.2.3.4", port=502), 1)
|
||||
|
||||
with pytest.raises(HomeAssistantError, match="different link settings"):
|
||||
async_get_unit(
|
||||
hass, entry, ModbusTcpParams(host="1.2.3.4", port=502, framer="rtu"), 2
|
||||
)
|
||||
async_get_unit(hass, entry, ModbusTlsParams(host="1.2.3.4", port=502), 2)
|
||||
|
||||
|
||||
async def test_the_last_consumer_closes_the_connection(
|
||||
@@ -251,7 +306,7 @@ async def test_a_temporary_unit_cannot_clash_with_held_link_settings(
|
||||
|
||||
with pytest.raises(HomeAssistantError, match="different link settings"):
|
||||
async with async_get_temporary_unit(
|
||||
hass, ModbusTcpParams(host="1.2.3.4", port=502, framer="rtu"), 2
|
||||
hass, ModbusTlsParams(host="1.2.3.4", port=502), 2
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from modbus_connection import ModbusTcpParams
|
||||
from modbus_connection import ModbusTlsParams
|
||||
from pystiebeleltron import ControllerModel, StiebelEltronModbusError
|
||||
import pytest
|
||||
|
||||
@@ -79,9 +79,7 @@ async def test_form_conflicting_link_settings(hass: HomeAssistant) -> None:
|
||||
async_get_unit(
|
||||
hass,
|
||||
other_entry,
|
||||
ModbusTcpParams(
|
||||
host=USER_INPUT[CONF_HOST], port=USER_INPUT[CONF_PORT], framer="rtu"
|
||||
),
|
||||
ModbusTlsParams(host=USER_INPUT[CONF_HOST], port=USER_INPUT[CONF_PORT]),
|
||||
UNIT_ID,
|
||||
)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ from typing import Any
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
from modbus_connection import ModbusError, ModbusTcpParams
|
||||
from modbus_connection import ModbusError, ModbusTcpParams, ModbusTlsParams
|
||||
from modbus_connection.mock import MockModbusConnection
|
||||
from pystiebeleltron import StiebelEltronModbusError
|
||||
import pytest
|
||||
@@ -82,7 +82,7 @@ async def test_async_setup_entry_conflicting_link_settings(
|
||||
async_get_unit(
|
||||
hass,
|
||||
other_entry,
|
||||
ModbusTcpParams(host="1.1.1.1", port=502, framer="rtu"),
|
||||
ModbusTlsParams(host="1.1.1.1", port=502),
|
||||
UNIT_ID,
|
||||
)
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
Reference in New Issue
Block a user