mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 08:47:57 +00:00
Get modbus coverage back to 100% (#108734)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
parent
a6807b8a7f
commit
d8f16c14ab
@ -133,12 +133,10 @@ from .const import ( # noqa: F401
|
||||
)
|
||||
from .modbus import ModbusHub, async_modbus_setup
|
||||
from .validators import (
|
||||
duplicate_entity_validator,
|
||||
check_config,
|
||||
duplicate_fan_mode_validator,
|
||||
duplicate_modbus_validator,
|
||||
nan_validator,
|
||||
number_validator,
|
||||
scan_interval_validator,
|
||||
struct_validator,
|
||||
)
|
||||
|
||||
@ -417,12 +415,10 @@ CONFIG_SCHEMA = vol.Schema(
|
||||
{
|
||||
DOMAIN: vol.All(
|
||||
cv.ensure_list,
|
||||
scan_interval_validator,
|
||||
duplicate_entity_validator,
|
||||
duplicate_modbus_validator,
|
||||
[
|
||||
vol.Any(SERIAL_SCHEMA, ETHERNET_SCHEMA),
|
||||
],
|
||||
check_config,
|
||||
),
|
||||
},
|
||||
extra=vol.ALLOW_EXTRA,
|
||||
|
@ -96,10 +96,6 @@ class BasePlatform(Entity):
|
||||
"url": "https://www.home-assistant.io/integrations/modbus",
|
||||
},
|
||||
)
|
||||
_LOGGER.warning(
|
||||
"`close_comm_on_error`: is deprecated and will be removed in version 2024.4"
|
||||
)
|
||||
|
||||
_LOGGER.warning(
|
||||
"`lazy_error_count`: is deprecated and will be removed in version 2024.7"
|
||||
)
|
||||
|
@ -203,6 +203,23 @@ def nan_validator(value: Any) -> int:
|
||||
raise vol.Invalid(f"invalid number {value}") from err
|
||||
|
||||
|
||||
def duplicate_fan_mode_validator(config: dict[str, Any]) -> dict:
|
||||
"""Control modbus climate fan mode values for duplicates."""
|
||||
fan_modes: set[int] = set()
|
||||
errors = []
|
||||
for key, value in config[CONF_FAN_MODE_VALUES].items():
|
||||
if value in fan_modes:
|
||||
warn = f"Modbus fan mode {key} has a duplicate value {value}, not loaded, values must be unique!"
|
||||
_LOGGER.warning(warn)
|
||||
errors.append(key)
|
||||
else:
|
||||
fan_modes.add(value)
|
||||
|
||||
for key in reversed(errors):
|
||||
del config[CONF_FAN_MODE_VALUES][key]
|
||||
return config
|
||||
|
||||
|
||||
def scan_interval_validator(config: dict) -> dict:
|
||||
"""Control scan_interval."""
|
||||
for hub in config:
|
||||
@ -306,7 +323,7 @@ def duplicate_entity_validator(config: dict) -> dict:
|
||||
return config
|
||||
|
||||
|
||||
def duplicate_modbus_validator(config: list) -> list:
|
||||
def duplicate_modbus_validator(config: dict) -> dict:
|
||||
"""Control modbus connection for duplicates."""
|
||||
hosts: set[str] = set()
|
||||
names: set[str] = set()
|
||||
@ -334,18 +351,9 @@ def duplicate_modbus_validator(config: list) -> list:
|
||||
return config
|
||||
|
||||
|
||||
def duplicate_fan_mode_validator(config: dict[str, Any]) -> dict:
|
||||
"""Control modbus climate fan mode values for duplicates."""
|
||||
fan_modes: set[int] = set()
|
||||
errors = []
|
||||
for key, value in config[CONF_FAN_MODE_VALUES].items():
|
||||
if value in fan_modes:
|
||||
wrn = f"Modbus fan mode {key} has a duplicate value {value}, not loaded, values must be unique!"
|
||||
_LOGGER.warning(wrn)
|
||||
errors.append(key)
|
||||
else:
|
||||
fan_modes.add(value)
|
||||
|
||||
for key in reversed(errors):
|
||||
del config[CONF_FAN_MODE_VALUES][key]
|
||||
return config
|
||||
def check_config(config: dict) -> dict:
|
||||
"""Do final config check."""
|
||||
config2 = duplicate_modbus_validator(config)
|
||||
config3 = scan_interval_validator(config2)
|
||||
config4 = duplicate_entity_validator(config3)
|
||||
return config4
|
||||
|
@ -309,6 +309,36 @@ async def test_temperature_climate(
|
||||
assert hass.states.get(ENTITY_ID).state == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"do_config",
|
||||
[
|
||||
{
|
||||
CONF_CLIMATES: [
|
||||
{
|
||||
CONF_NAME: TEST_ENTITY_NAME,
|
||||
CONF_SLAVE: 1,
|
||||
CONF_TARGET_TEMP: 117,
|
||||
CONF_ADDRESS: 117,
|
||||
CONF_DATA_TYPE: DataType.INT32,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
("register_words", "expected"),
|
||||
[
|
||||
(
|
||||
None,
|
||||
"unavailable",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_temperature_error(hass: HomeAssistant, expected, mock_do_cycle) -> None:
|
||||
"""Run test for given config."""
|
||||
assert hass.states.get(ENTITY_ID).state == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("do_config", "result", "register_words"),
|
||||
[
|
||||
|
@ -56,6 +56,7 @@ from homeassistant.components.modbus.const import (
|
||||
CONF_INPUT_TYPE,
|
||||
CONF_MSG_WAIT,
|
||||
CONF_PARITY,
|
||||
CONF_RETRIES,
|
||||
CONF_RETRY_ON_EMPTY,
|
||||
CONF_SLAVE_COUNT,
|
||||
CONF_STOPBITS,
|
||||
@ -610,6 +611,12 @@ async def test_duplicate_entity_validator_with_climate(do_config) -> None:
|
||||
CONF_PORT: TEST_PORT_TCP,
|
||||
CONF_CLOSE_COMM_ON_ERROR: True,
|
||||
},
|
||||
{
|
||||
CONF_TYPE: TCP,
|
||||
CONF_HOST: TEST_MODBUS_HOST,
|
||||
CONF_PORT: TEST_PORT_TCP,
|
||||
CONF_RETRIES: 3,
|
||||
},
|
||||
{
|
||||
CONF_TYPE: TCP,
|
||||
CONF_HOST: TEST_MODBUS_HOST,
|
||||
|
@ -9,6 +9,7 @@ from homeassistant.components.modbus.const import (
|
||||
CONF_DATA_TYPE,
|
||||
CONF_DEVICE_ADDRESS,
|
||||
CONF_INPUT_TYPE,
|
||||
CONF_LAZY_ERROR,
|
||||
CONF_MAX_VALUE,
|
||||
CONF_MIN_VALUE,
|
||||
CONF_NAN_VALUE,
|
||||
@ -173,6 +174,17 @@ SLAVE_UNIQUE_ID = "ground_floor_sensor"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
CONF_SENSORS: [
|
||||
{
|
||||
CONF_NAME: TEST_ENTITY_NAME,
|
||||
CONF_ADDRESS: 51,
|
||||
CONF_DATA_TYPE: DataType.INT32,
|
||||
CONF_VIRTUAL_COUNT: 5,
|
||||
CONF_LAZY_ERROR: 3,
|
||||
}
|
||||
]
|
||||
},
|
||||
],
|
||||
)
|
||||
async def test_config_sensor(hass: HomeAssistant, mock_modbus) -> None:
|
||||
|
Loading…
x
Reference in New Issue
Block a user