mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Fix modbus reload service (#68040)
* Fix modbus reload service. * Please coverage. * Resolve difference between local pytest and github.
This commit is contained in:
parent
a851921fe6
commit
1a79118600
@ -1,6 +1,7 @@
|
|||||||
"""Support for Modbus."""
|
"""Support for Modbus."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import logging
|
||||||
from typing import cast
|
from typing import cast
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
@ -110,6 +111,9 @@ from .validators import (
|
|||||||
struct_validator,
|
struct_validator,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
BASE_SCHEMA = vol.Schema({vol.Optional(CONF_NAME, default=DEFAULT_HUB): cv.string})
|
BASE_SCHEMA = vol.Schema({vol.Optional(CONF_NAME, default=DEFAULT_HUB): cv.string})
|
||||||
|
|
||||||
|
|
||||||
@ -342,3 +346,12 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||||||
hass,
|
hass,
|
||||||
config,
|
config,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_reset_platform(hass: HomeAssistant, integration_name: str) -> None:
|
||||||
|
"""Release modbus resources."""
|
||||||
|
_LOGGER.info("Modbus reloading")
|
||||||
|
hubs = hass.data[DOMAIN]
|
||||||
|
for name in hubs:
|
||||||
|
await hubs[name].async_close()
|
||||||
|
del hass.data[DOMAIN]
|
||||||
|
@ -130,10 +130,7 @@ async def async_modbus_setup(
|
|||||||
) -> bool:
|
) -> bool:
|
||||||
"""Set up Modbus component."""
|
"""Set up Modbus component."""
|
||||||
|
|
||||||
platform_names = []
|
await async_setup_reload_service(hass, DOMAIN, [DOMAIN])
|
||||||
for entry in PLATFORMS:
|
|
||||||
platform_names.append(entry[1])
|
|
||||||
await async_setup_reload_service(hass, DOMAIN, platform_names)
|
|
||||||
|
|
||||||
hass.data[DOMAIN] = hub_collect = {}
|
hass.data[DOMAIN] = hub_collect = {}
|
||||||
for conf_hub in config[DOMAIN]:
|
for conf_hub in config[DOMAIN]:
|
||||||
@ -245,14 +242,6 @@ async def async_modbus_setup(
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
async def async_reset_platform(hass: HomeAssistant, integration_name: str) -> None:
|
|
||||||
"""Release modbus resources."""
|
|
||||||
_LOGGER.info("Modbus reloading")
|
|
||||||
for hub in hass.data[DOMAIN]:
|
|
||||||
await hub.async_close()
|
|
||||||
del hass.data[DOMAIN]
|
|
||||||
|
|
||||||
|
|
||||||
class ModbusHub:
|
class ModbusHub:
|
||||||
"""Thread safe wrapper class for pymodbus."""
|
"""Thread safe wrapper class for pymodbus."""
|
||||||
|
|
||||||
@ -410,7 +399,7 @@ class ModbusHub:
|
|||||||
return None
|
return None
|
||||||
async with self._lock:
|
async with self._lock:
|
||||||
if not self._client:
|
if not self._client:
|
||||||
return None # pragma: no cover
|
return None
|
||||||
result = await self.hass.async_add_executor_job(
|
result = await self.hass.async_add_executor_job(
|
||||||
self._pymodbus_call, unit, address, value, use_call
|
self._pymodbus_call, unit, address, value, use_call
|
||||||
)
|
)
|
||||||
|
6
tests/components/modbus/fixtures/configuration.yaml
Normal file
6
tests/components/modbus/fixtures/configuration.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
modbus:
|
||||||
|
type: "tcp"
|
||||||
|
host: "testHost"
|
||||||
|
port: 5001
|
||||||
|
name: "testModbus"
|
||||||
|
|
@ -21,6 +21,7 @@ from pymodbus.pdu import ExceptionResponse, IllegalFunctionRequest
|
|||||||
import pytest
|
import pytest
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant import config as hass_config
|
||||||
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN
|
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN
|
||||||
from homeassistant.components.modbus.const import (
|
from homeassistant.components.modbus.const import (
|
||||||
ATTR_ADDRESS,
|
ATTR_ADDRESS,
|
||||||
@ -83,6 +84,7 @@ from homeassistant.const import (
|
|||||||
CONF_TIMEOUT,
|
CONF_TIMEOUT,
|
||||||
CONF_TYPE,
|
CONF_TYPE,
|
||||||
EVENT_HOMEASSISTANT_STOP,
|
EVENT_HOMEASSISTANT_STOP,
|
||||||
|
SERVICE_RELOAD,
|
||||||
STATE_ON,
|
STATE_ON,
|
||||||
STATE_UNAVAILABLE,
|
STATE_UNAVAILABLE,
|
||||||
STATE_UNKNOWN,
|
STATE_UNKNOWN,
|
||||||
@ -99,7 +101,7 @@ from .conftest import (
|
|||||||
ReadResult,
|
ReadResult,
|
||||||
)
|
)
|
||||||
|
|
||||||
from tests.common import async_fire_time_changed
|
from tests.common import async_fire_time_changed, get_fixture_path
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="mock_modbus_with_pymodbus")
|
@pytest.fixture(name="mock_modbus_with_pymodbus")
|
||||||
@ -824,3 +826,43 @@ async def test_stop_restart(hass, caplog, mock_modbus):
|
|||||||
assert mock_modbus.connect.called
|
assert mock_modbus.connect.called
|
||||||
assert f"modbus {TEST_MODBUS_NAME} communication closed" in caplog.text
|
assert f"modbus {TEST_MODBUS_NAME} communication closed" in caplog.text
|
||||||
assert f"modbus {TEST_MODBUS_NAME} communication open" in caplog.text
|
assert f"modbus {TEST_MODBUS_NAME} communication open" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("do_config", [{}])
|
||||||
|
async def test_write_no_client(hass, mock_modbus):
|
||||||
|
"""Run test for service stop and write without client."""
|
||||||
|
|
||||||
|
mock_modbus.reset()
|
||||||
|
data = {
|
||||||
|
ATTR_HUB: TEST_MODBUS_NAME,
|
||||||
|
}
|
||||||
|
await hass.services.async_call(DOMAIN, SERVICE_STOP, data, blocking=True)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert mock_modbus.close.called
|
||||||
|
|
||||||
|
data = {
|
||||||
|
ATTR_HUB: TEST_MODBUS_NAME,
|
||||||
|
ATTR_UNIT: 17,
|
||||||
|
ATTR_ADDRESS: 16,
|
||||||
|
ATTR_STATE: True,
|
||||||
|
}
|
||||||
|
await hass.services.async_call(DOMAIN, SERVICE_WRITE_COIL, data, blocking=True)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("do_config", [{}])
|
||||||
|
async def test_integration_reload(hass, caplog, mock_modbus):
|
||||||
|
"""Run test for integration reload."""
|
||||||
|
|
||||||
|
caplog.set_level(logging.INFO)
|
||||||
|
caplog.clear()
|
||||||
|
|
||||||
|
yaml_path = get_fixture_path("configuration.yaml", "modbus")
|
||||||
|
now = dt_util.utcnow()
|
||||||
|
with mock.patch.object(hass_config, "YAML_CONFIG_FILE", yaml_path):
|
||||||
|
await hass.services.async_call(DOMAIN, SERVICE_RELOAD, blocking=True)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
for i in range(4):
|
||||||
|
now = now + timedelta(seconds=1)
|
||||||
|
async_fire_time_changed(hass, now)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert "Modbus reloading" in caplog.text
|
||||||
|
Loading…
x
Reference in New Issue
Block a user