core/tests/components/modbus/conftest.py

150 lines
4.5 KiB
Python
Raw Normal View History

"""The tests for the Modbus sensor component."""
from datetime import timedelta
import logging
from unittest import mock
import pytest
from homeassistant.components.modbus.const import DEFAULT_HUB, MODBUS_DOMAIN as DOMAIN
from homeassistant.const import (
CONF_HOST,
CONF_NAME,
CONF_PLATFORM,
CONF_PORT,
CONF_SCAN_INTERVAL,
CONF_TYPE,
)
from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util
from tests.common import async_fire_time_changed
_LOGGER = logging.getLogger(__name__)
class ReadResult:
"""Storage class for register read results."""
def __init__(self, register_words):
"""Init."""
self.registers = register_words
self.bits = register_words
async def base_test(
hass,
config_device,
device_name,
entity_domain,
array_name_discovery,
array_name_old_config,
register_words,
expected,
method_discovery=False,
check_config_only=False,
config_modbus=None,
scan_interval=None,
):
"""Run test on device for given config."""
if config_modbus is None:
config_modbus = {
DOMAIN: {
CONF_NAME: DEFAULT_HUB,
CONF_TYPE: "tcp",
CONF_HOST: "modbusTest",
CONF_PORT: 5001,
},
}
mock_sync = mock.MagicMock()
with mock.patch(
"homeassistant.components.modbus.modbus.ModbusTcpClient", return_value=mock_sync
), mock.patch(
"homeassistant.components.modbus.modbus.ModbusSerialClient",
return_value=mock_sync,
), mock.patch(
"homeassistant.components.modbus.modbus.ModbusUdpClient", return_value=mock_sync
):
# Setup inputs for the sensor
read_result = ReadResult(register_words)
mock_sync.read_coils.return_value = read_result
mock_sync.read_discrete_inputs.return_value = read_result
mock_sync.read_input_registers.return_value = read_result
mock_sync.read_holding_registers.return_value = read_result
# mock timer and add old/new config
now = dt_util.utcnow()
with mock.patch("homeassistant.helpers.event.dt_util.utcnow", return_value=now):
if method_discovery and config_device is not None:
# setup modbus which in turn does setup for the devices
config_modbus[DOMAIN].update(
{array_name_discovery: [{**config_device}]}
)
config_device = None
assert await async_setup_component(hass, DOMAIN, config_modbus)
await hass.async_block_till_done()
# setup platform old style
if config_device is not None:
config_device = {
entity_domain: {
CONF_PLATFORM: DOMAIN,
array_name_old_config: [
{
**config_device,
}
],
}
}
if scan_interval is not None:
config_device[entity_domain][CONF_SCAN_INTERVAL] = scan_interval
assert await async_setup_component(hass, entity_domain, config_device)
await hass.async_block_till_done()
assert DOMAIN in hass.data
if config_device is not None:
entity_id = f"{entity_domain}.{device_name}"
device = hass.states.get(entity_id)
if device is None:
pytest.fail("CONFIG failed, see output")
if check_config_only:
return
# Trigger update call with time_changed event
now = now + timedelta(seconds=scan_interval + 60)
with mock.patch("homeassistant.helpers.event.dt_util.utcnow", return_value=now):
async_fire_time_changed(hass, now)
await hass.async_block_till_done()
# Check state
entity_id = f"{entity_domain}.{device_name}"
return hass.states.get(entity_id).state
async def base_config_test(
hass,
config_device,
device_name,
entity_domain,
array_name_discovery,
array_name_old_config,
method_discovery=False,
config_modbus=None,
):
"""Check config of device for given config."""
await base_test(
hass,
config_device,
device_name,
entity_domain,
array_name_discovery,
array_name_old_config,
None,
None,
method_discovery=method_discovery,
check_config_only=True,
)