Add modbus get_hub (#54277)

* Add dict with hubs.

* Update flexit to use get_hub.

* Remove executor_task for close.
This commit is contained in:
jan iversen 2021-08-08 22:48:33 +02:00 committed by GitHub
parent 7590cb2861
commit e8aa280d7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 36 additions and 30 deletions

View File

@ -11,13 +11,13 @@ from homeassistant.components.climate.const import (
SUPPORT_FAN_MODE, SUPPORT_FAN_MODE,
SUPPORT_TARGET_TEMPERATURE, SUPPORT_TARGET_TEMPERATURE,
) )
from homeassistant.components.modbus import get_hub
from homeassistant.components.modbus.const import ( from homeassistant.components.modbus.const import (
CALL_TYPE_REGISTER_HOLDING, CALL_TYPE_REGISTER_HOLDING,
CALL_TYPE_REGISTER_INPUT, CALL_TYPE_REGISTER_INPUT,
CALL_TYPE_WRITE_REGISTER, CALL_TYPE_WRITE_REGISTER,
CONF_HUB, CONF_HUB,
DEFAULT_HUB, DEFAULT_HUB,
MODBUS_DOMAIN,
) )
from homeassistant.components.modbus.modbus import ModbusHub from homeassistant.components.modbus.modbus import ModbusHub
from homeassistant.const import ( from homeassistant.const import (
@ -53,7 +53,7 @@ async def async_setup_platform(
"""Set up the Flexit Platform.""" """Set up the Flexit Platform."""
modbus_slave = config.get(CONF_SLAVE) modbus_slave = config.get(CONF_SLAVE)
name = config.get(CONF_NAME) name = config.get(CONF_NAME)
hub = hass.data[MODBUS_DOMAIN][config.get(CONF_HUB)] hub = get_hub(hass, config[CONF_HUB])
async_add_entities([Flexit(hub, modbus_slave, name)], True) async_add_entities([Flexit(hub, modbus_slave, name)], True)

View File

@ -42,6 +42,7 @@ from homeassistant.const import (
CONF_TYPE, CONF_TYPE,
CONF_UNIT_OF_MEASUREMENT, CONF_UNIT_OF_MEASUREMENT,
) )
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from .const import ( from .const import (
@ -114,7 +115,7 @@ from .const import (
DEFAULT_TEMP_UNIT, DEFAULT_TEMP_UNIT,
MODBUS_DOMAIN as DOMAIN, MODBUS_DOMAIN as DOMAIN,
) )
from .modbus import async_modbus_setup from .modbus import ModbusHub, async_modbus_setup
from .validators import number_validator, scan_interval_validator, struct_validator from .validators import number_validator, scan_interval_validator, struct_validator
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -357,6 +358,11 @@ SERVICE_WRITE_COIL_SCHEMA = vol.Schema(
) )
def get_hub(hass: HomeAssistant, name: str) -> ModbusHub:
"""Return modbus hub with name."""
return hass.data[DOMAIN][name]
async def async_setup(hass, config): async def async_setup(hass, config):
"""Set up Modbus component.""" """Set up Modbus component."""
return await async_modbus_setup( return await async_modbus_setup(

View File

@ -9,8 +9,8 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from . import get_hub
from .base_platform import BasePlatform from .base_platform import BasePlatform
from .const import MODBUS_DOMAIN
PARALLEL_UPDATES = 1 PARALLEL_UPDATES = 1
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -29,7 +29,7 @@ async def async_setup_platform(
return return
for entry in discovery_info[CONF_BINARY_SENSORS]: for entry in discovery_info[CONF_BINARY_SENSORS]:
hub = hass.data[MODBUS_DOMAIN][discovery_info[CONF_NAME]] hub = get_hub(hass, discovery_info[CONF_NAME])
sensors.append(ModbusBinarySensor(hub, entry)) sensors.append(ModbusBinarySensor(hub, entry))
async_add_entities(sensors) async_add_entities(sensors)

View File

@ -23,6 +23,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from . import get_hub
from .base_platform import BaseStructPlatform from .base_platform import BaseStructPlatform
from .const import ( from .const import (
ATTR_TEMPERATURE, ATTR_TEMPERATURE,
@ -39,7 +40,6 @@ from .const import (
DATA_TYPE_UINT16, DATA_TYPE_UINT16,
DATA_TYPE_UINT32, DATA_TYPE_UINT32,
DATA_TYPE_UINT64, DATA_TYPE_UINT64,
MODBUS_DOMAIN,
) )
from .modbus import ModbusHub from .modbus import ModbusHub
@ -59,7 +59,7 @@ async def async_setup_platform(
entities = [] entities = []
for entity in discovery_info[CONF_CLIMATES]: for entity in discovery_info[CONF_CLIMATES]:
hub: ModbusHub = hass.data[MODBUS_DOMAIN][discovery_info[CONF_NAME]] hub: ModbusHub = get_hub(hass, discovery_info[CONF_NAME])
entities.append(ModbusThermostat(hub, entity)) entities.append(ModbusThermostat(hub, entity))
async_add_entities(entities) async_add_entities(entities)

View File

@ -19,6 +19,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from . import get_hub
from .base_platform import BasePlatform from .base_platform import BasePlatform
from .const import ( from .const import (
CALL_TYPE_COIL, CALL_TYPE_COIL,
@ -30,7 +31,6 @@ from .const import (
CONF_STATE_OPENING, CONF_STATE_OPENING,
CONF_STATUS_REGISTER, CONF_STATUS_REGISTER,
CONF_STATUS_REGISTER_TYPE, CONF_STATUS_REGISTER_TYPE,
MODBUS_DOMAIN,
) )
from .modbus import ModbusHub from .modbus import ModbusHub
@ -50,7 +50,7 @@ async def async_setup_platform(
covers = [] covers = []
for cover in discovery_info[CONF_COVERS]: for cover in discovery_info[CONF_COVERS]:
hub: ModbusHub = hass.data[MODBUS_DOMAIN][discovery_info[CONF_NAME]] hub: ModbusHub = get_hub(hass, discovery_info[CONF_NAME])
covers.append(ModbusCover(hub, cover)) covers.append(ModbusCover(hub, cover))
async_add_entities(covers) async_add_entities(covers)

View File

@ -8,8 +8,9 @@ from homeassistant.const import CONF_NAME
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
from . import get_hub
from .base_platform import BaseSwitch from .base_platform import BaseSwitch
from .const import CONF_FANS, MODBUS_DOMAIN from .const import CONF_FANS
from .modbus import ModbusHub from .modbus import ModbusHub
PARALLEL_UPDATES = 1 PARALLEL_UPDATES = 1
@ -25,7 +26,7 @@ async def async_setup_platform(
fans = [] fans = []
for entry in discovery_info[CONF_FANS]: for entry in discovery_info[CONF_FANS]:
hub: ModbusHub = hass.data[MODBUS_DOMAIN][discovery_info[CONF_NAME]] hub: ModbusHub = get_hub(hass, discovery_info[CONF_NAME])
fans.append(ModbusFan(hub, entry)) fans.append(ModbusFan(hub, entry))
async_add_entities(fans) async_add_entities(fans)

View File

@ -8,8 +8,8 @@ from homeassistant.const import CONF_LIGHTS, CONF_NAME
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
from . import get_hub
from .base_platform import BaseSwitch from .base_platform import BaseSwitch
from .const import MODBUS_DOMAIN
from .modbus import ModbusHub from .modbus import ModbusHub
PARALLEL_UPDATES = 1 PARALLEL_UPDATES = 1
@ -25,7 +25,7 @@ async def async_setup_platform(
lights = [] lights = []
for entry in discovery_info[CONF_LIGHTS]: for entry in discovery_info[CONF_LIGHTS]:
hub: ModbusHub = hass.data[MODBUS_DOMAIN][discovery_info[CONF_NAME]] hub: ModbusHub = get_hub(hass, discovery_info[CONF_NAME])
lights.append(ModbusLight(hub, entry)) lights.append(ModbusLight(hub, entry))
async_add_entities(lights) async_add_entities(lights)

View File

@ -1,4 +1,6 @@
"""Support for Modbus.""" """Support for Modbus."""
from __future__ import annotations
import asyncio import asyncio
from collections import namedtuple from collections import namedtuple
import logging import logging
@ -57,6 +59,7 @@ from .const import (
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
ConfEntry = namedtuple("ConfEntry", "call_type attr func_name") ConfEntry = namedtuple("ConfEntry", "call_type attr func_name")
RunEntry = namedtuple("RunEntry", "attr func") RunEntry = namedtuple("RunEntry", "attr func")
PYMODBUS_CALL = [ PYMODBUS_CALL = [
@ -184,6 +187,8 @@ async def async_modbus_setup(
class ModbusHub: class ModbusHub:
"""Thread safe wrapper class for pymodbus.""" """Thread safe wrapper class for pymodbus."""
name: str
def __init__(self, hass, client_config): def __init__(self, hass, client_config):
"""Initialize the Modbus hub.""" """Initialize the Modbus hub."""
@ -193,7 +198,7 @@ class ModbusHub:
self._in_error = False self._in_error = False
self._lock = asyncio.Lock() self._lock = asyncio.Lock()
self.hass = hass self.hass = hass
self._config_name = client_config[CONF_NAME] self.name = client_config[CONF_NAME]
self._config_type = client_config[CONF_TYPE] self._config_type = client_config[CONF_TYPE]
self._config_delay = client_config[CONF_DELAY] self._config_delay = client_config[CONF_DELAY]
self._pb_call = {} self._pb_call = {}
@ -262,7 +267,7 @@ class ModbusHub:
"""Try to connect, and retry if needed.""" """Try to connect, and retry if needed."""
async with self._lock: async with self._lock:
if not await self.hass.async_add_executor_job(self._pymodbus_connect): if not await self.hass.async_add_executor_job(self._pymodbus_connect):
err = f"{self._config_name} connect failed, retry in pymodbus" err = f"{self.name} connect failed, retry in pymodbus"
self._log_error(err, error_state=False) self._log_error(err, error_state=False)
return return
@ -278,8 +283,11 @@ class ModbusHub:
self._async_cancel_listener = None self._async_cancel_listener = None
self._config_delay = 0 self._config_delay = 0
def _pymodbus_close(self): async def async_close(self):
"""Close sync. pymodbus.""" """Disconnect client."""
if self._async_cancel_listener:
self._async_cancel_listener()
self._async_cancel_listener = None
if self._client: if self._client:
try: try:
self._client.close() self._client.close()
@ -287,15 +295,6 @@ class ModbusHub:
self._log_error(str(exception_error)) self._log_error(str(exception_error))
self._client = None self._client = None
async def async_close(self):
"""Disconnect client."""
if self._async_cancel_listener:
self._async_cancel_listener()
self._async_cancel_listener = None
async with self._lock:
return await self.hass.async_add_executor_job(self._pymodbus_close)
def _pymodbus_connect(self): def _pymodbus_connect(self):
"""Connect client.""" """Connect client."""
try: try:

View File

@ -10,8 +10,8 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from . import get_hub
from .base_platform import BaseStructPlatform from .base_platform import BaseStructPlatform
from .const import MODBUS_DOMAIN
from .modbus import ModbusHub from .modbus import ModbusHub
PARALLEL_UPDATES = 1 PARALLEL_UPDATES = 1
@ -31,7 +31,7 @@ async def async_setup_platform(
return return
for entry in discovery_info[CONF_SENSORS]: for entry in discovery_info[CONF_SENSORS]:
hub = hass.data[MODBUS_DOMAIN][discovery_info[CONF_NAME]] hub = get_hub(hass, discovery_info[CONF_NAME])
sensors.append(ModbusRegisterSensor(hub, entry)) sensors.append(ModbusRegisterSensor(hub, entry))
async_add_entities(sensors) async_add_entities(sensors)

View File

@ -8,8 +8,8 @@ from homeassistant.const import CONF_NAME, CONF_SWITCHES
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
from . import get_hub
from .base_platform import BaseSwitch from .base_platform import BaseSwitch
from .const import MODBUS_DOMAIN
from .modbus import ModbusHub from .modbus import ModbusHub
PARALLEL_UPDATES = 1 PARALLEL_UPDATES = 1
@ -26,7 +26,7 @@ async def async_setup_platform(
return return
for entry in discovery_info[CONF_SWITCHES]: for entry in discovery_info[CONF_SWITCHES]:
hub: ModbusHub = hass.data[MODBUS_DOMAIN][discovery_info[CONF_NAME]] hub: ModbusHub = get_hub(hass, discovery_info[CONF_NAME])
switches.append(ModbusSwitch(hub, entry)) switches.append(ModbusSwitch(hub, entry))
async_add_entities(switches) async_add_entities(switches)