"""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 ( CALL_TYPE_REGISTER_INPUT, CONF_REGISTER, CONF_REGISTER_TYPE, CONF_REGISTERS, DEFAULT_HUB, MODBUS_DOMAIN as DOMAIN, ) from homeassistant.const import CONF_NAME, CONF_PLATFORM, CONF_SCAN_INTERVAL from homeassistant.setup import async_setup_component import homeassistant.util.dt as dt_util from tests.common import MockModule, async_fire_time_changed, mock_integration _LOGGER = logging.getLogger(__name__) @pytest.fixture() def mock_hub(hass): """Mock hub.""" mock_integration(hass, MockModule(DOMAIN)) hub = mock.MagicMock() hub.name = "hub" hass.data[DOMAIN] = {DEFAULT_HUB: hub} return hub class ReadResult: """Storage class for register read results.""" def __init__(self, register_words): """Init.""" self.registers = register_words async def run_test( hass, use_mock_hub, register_config, entity_domain, register_words, expected ): """Run test for given config and check that sensor outputs expected result.""" # Full sensor configuration sensor_name = "modbus_test_sensor" scan_interval = 5 config = { entity_domain: { CONF_PLATFORM: "modbus", CONF_SCAN_INTERVAL: scan_interval, CONF_REGISTERS: [ dict(**{CONF_NAME: sensor_name, CONF_REGISTER: 1234}, **register_config) ], } } # Setup inputs for the sensor read_result = ReadResult(register_words) if register_config.get(CONF_REGISTER_TYPE) == CALL_TYPE_REGISTER_INPUT: use_mock_hub.read_input_registers.return_value = read_result else: use_mock_hub.read_holding_registers.return_value = read_result # Initialize sensor now = dt_util.utcnow() with mock.patch("homeassistant.helpers.event.dt_util.utcnow", return_value=now): assert await async_setup_component(hass, entity_domain, config) await hass.async_block_till_done() # Trigger update call with time_changed event now += timedelta(seconds=scan_interval + 1) 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}.{sensor_name}" state = hass.states.get(entity_id).state assert state == expected