From ec2364ef439a9382cdf3dfe277d806f7a35fa257 Mon Sep 17 00:00:00 2001 From: jan iversen Date: Fri, 15 Sep 2023 14:00:02 +0200 Subject: [PATCH] Add virtual_count == slave_count in modbus configuration (#100398) * Add virtual_count as config parameter. * Review (other PR) comments. * Review. * Review comment. --- homeassistant/components/modbus/__init__.py | 7 +++++-- homeassistant/components/modbus/base_platform.py | 5 ++++- homeassistant/components/modbus/binary_sensor.py | 11 +++++++++-- homeassistant/components/modbus/const.py | 1 + homeassistant/components/modbus/sensor.py | 6 ++++-- homeassistant/components/modbus/validators.py | 7 ++++++- 6 files changed, 29 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/modbus/__init__.py b/homeassistant/components/modbus/__init__.py index c228ba64459..5f3ddd7a4b5 100644 --- a/homeassistant/components/modbus/__init__.py +++ b/homeassistant/components/modbus/__init__.py @@ -106,6 +106,7 @@ from .const import ( # noqa: F401 CONF_TARGET_TEMP, CONF_TARGET_TEMP_WRITE_REGISTERS, CONF_VERIFY, + CONF_VIRTUAL_COUNT, CONF_WRITE_REGISTERS, CONF_WRITE_TYPE, CONF_ZERO_SUPPRESS, @@ -310,7 +311,8 @@ SENSOR_SCHEMA = vol.All( vol.Optional(CONF_DEVICE_CLASS): SENSOR_DEVICE_CLASSES_SCHEMA, vol.Optional(CONF_STATE_CLASS): SENSOR_STATE_CLASSES_SCHEMA, vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string, - vol.Optional(CONF_SLAVE_COUNT, default=0): cv.positive_int, + vol.Exclusive(CONF_VIRTUAL_COUNT, "vir_sen_count"): cv.positive_int, + vol.Optional(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_NAN_VALUE): nan_validator, @@ -330,7 +332,8 @@ BINARY_SENSOR_SCHEMA = BASE_COMPONENT_SCHEMA.extend( CALL_TYPE_REGISTER_INPUT, ] ), - vol.Optional(CONF_SLAVE_COUNT, default=0): cv.positive_int, + vol.Exclusive(CONF_VIRTUAL_COUNT, "vir_bin_count"): cv.positive_int, + vol.Exclusive(CONF_SLAVE_COUNT, "vir_bin_count"): cv.positive_int, } ) diff --git a/homeassistant/components/modbus/base_platform.py b/homeassistant/components/modbus/base_platform.py index 739f234e8c4..ee98b51b72a 100644 --- a/homeassistant/components/modbus/base_platform.py +++ b/homeassistant/components/modbus/base_platform.py @@ -59,6 +59,7 @@ from .const import ( CONF_SWAP_WORD, CONF_SWAP_WORD_BYTE, CONF_VERIFY, + CONF_VIRTUAL_COUNT, CONF_WRITE_TYPE, CONF_ZERO_SUPPRESS, SIGNAL_START_ENTITY, @@ -166,7 +167,9 @@ class BaseStructPlatform(BasePlatform, RestoreEntity): if self._scale < 1 and not self._precision: self._precision = 2 self._offset = config[CONF_OFFSET] - self._slave_count = config.get(CONF_SLAVE_COUNT, 0) + self._slave_count = config.get(CONF_SLAVE_COUNT, None) or config.get( + CONF_VIRTUAL_COUNT, 0 + ) self._slave_size = self._count = config[CONF_COUNT] def _swap_registers(self, registers: list[int], slave_count: int) -> list[int]: diff --git a/homeassistant/components/modbus/binary_sensor.py b/homeassistant/components/modbus/binary_sensor.py index 05668bac0a9..3dabeee081c 100644 --- a/homeassistant/components/modbus/binary_sensor.py +++ b/homeassistant/components/modbus/binary_sensor.py @@ -24,7 +24,12 @@ from homeassistant.helpers.update_coordinator import ( from . import get_hub from .base_platform import BasePlatform -from .const import CALL_TYPE_COIL, CALL_TYPE_DISCRETE, CONF_SLAVE_COUNT +from .const import ( + CALL_TYPE_COIL, + CALL_TYPE_DISCRETE, + CONF_SLAVE_COUNT, + CONF_VIRTUAL_COUNT, +) from .modbus import ModbusHub _LOGGER = logging.getLogger(__name__) @@ -46,7 +51,9 @@ async def async_setup_platform( sensors: list[ModbusBinarySensor | SlaveSensor] = [] hub = get_hub(hass, discovery_info[CONF_NAME]) for entry in discovery_info[CONF_BINARY_SENSORS]: - slave_count = entry.get(CONF_SLAVE_COUNT, 0) + slave_count = entry.get(CONF_SLAVE_COUNT, None) or entry.get( + CONF_VIRTUAL_COUNT, 0 + ) sensor = ModbusBinarySensor(hub, entry, slave_count) if slave_count > 0: sensors.extend(await sensor.async_setup_slaves(hass, slave_count, entry)) diff --git a/homeassistant/components/modbus/const.py b/homeassistant/components/modbus/const.py index 7776cf96e70..92a38bb5e92 100644 --- a/homeassistant/components/modbus/const.py +++ b/homeassistant/components/modbus/const.py @@ -62,6 +62,7 @@ CONF_HVAC_MODE_DRY = "state_dry" CONF_HVAC_MODE_FAN_ONLY = "state_fan_only" CONF_WRITE_REGISTERS = "write_registers" CONF_VERIFY = "verify" +CONF_VIRTUAL_COUNT = "virtual_count" CONF_WRITE_TYPE = "write_type" CONF_ZERO_SUPPRESS = "zero_suppress" diff --git a/homeassistant/components/modbus/sensor.py b/homeassistant/components/modbus/sensor.py index f2ed504b41b..d7a6b4cca0f 100644 --- a/homeassistant/components/modbus/sensor.py +++ b/homeassistant/components/modbus/sensor.py @@ -28,7 +28,7 @@ from homeassistant.helpers.update_coordinator import ( from . import get_hub from .base_platform import BaseStructPlatform -from .const import CONF_SLAVE_COUNT +from .const import CONF_SLAVE_COUNT, CONF_VIRTUAL_COUNT from .modbus import ModbusHub _LOGGER = logging.getLogger(__name__) @@ -50,7 +50,9 @@ async def async_setup_platform( sensors: list[ModbusRegisterSensor | SlaveSensor] = [] hub = get_hub(hass, discovery_info[CONF_NAME]) for entry in discovery_info[CONF_SENSORS]: - slave_count = entry.get(CONF_SLAVE_COUNT, 0) + slave_count = entry.get(CONF_SLAVE_COUNT, None) or entry.get( + CONF_VIRTUAL_COUNT, 0 + ) sensor = ModbusRegisterSensor(hub, entry, slave_count) if slave_count > 0: sensors.extend(await sensor.async_setup_slaves(hass, slave_count, entry)) diff --git a/homeassistant/components/modbus/validators.py b/homeassistant/components/modbus/validators.py index 4297bf46cfe..ca08ace853a 100644 --- a/homeassistant/components/modbus/validators.py +++ b/homeassistant/components/modbus/validators.py @@ -33,6 +33,7 @@ from .const import ( CONF_SWAP_NONE, CONF_SWAP_WORD, CONF_SWAP_WORD_BYTE, + CONF_VIRTUAL_COUNT, CONF_WRITE_TYPE, DEFAULT_HUB, DEFAULT_SCAN_INTERVAL, @@ -98,6 +99,10 @@ def struct_validator(config: dict[str, Any]) -> dict[str, Any]: count = config.get(CONF_COUNT, None) structure = config.get(CONF_STRUCTURE, None) slave_count = config.get(CONF_SLAVE_COUNT, None) + slave_name = CONF_SLAVE_COUNT + if not slave_count: + slave_count = config.get(CONF_VIRTUAL_COUNT, 0) + slave_name = CONF_VIRTUAL_COUNT swap_type = config.get(CONF_SWAP, CONF_SWAP_NONE) validator = DEFAULT_STRUCT_FORMAT[data_type].validate_parm if count and not validator.count: @@ -113,7 +118,7 @@ def struct_validator(config: dict[str, Any]) -> dict[str, Any]: error = f"{name}: `{CONF_STRUCTURE}` missing or empty, demanded with `{CONF_DATA_TYPE}: {data_type}`" raise vol.Invalid(error) if slave_count and not validator.slave_count: - error = f"{name}: `{CONF_SLAVE_COUNT}: {slave_count}` cannot be combined with `{CONF_DATA_TYPE}: {data_type}`" + error = f"{name}: `{slave_name}: {slave_count}` cannot be combined with `{CONF_DATA_TYPE}: {data_type}`" raise vol.Invalid(error) if swap_type != CONF_SWAP_NONE: swap_type_validator = {