diff --git a/homeassistant/components/modbus/modbus.py b/homeassistant/components/modbus/modbus.py index f2b033bec3e..8d2ea46e293 100644 --- a/homeassistant/components/modbus/modbus.py +++ b/homeassistant/components/modbus/modbus.py @@ -249,17 +249,22 @@ class ModbusHub: for entry in self._pb_call.values(): entry[ENTRY_FUNC] = getattr(self._client, entry[ENTRY_NAME]) + await self.async_connect_task() + return True + + async def async_connect_task(self): + """Try to connect, and retry if needed.""" async with self._lock: if not await self.hass.async_add_executor_job(self._pymodbus_connect): - self._log_error("initial connect failed, no retry", error_state=False) - return False + err = f"{self._config_name} connect failed, retry in pymodbus" + self._log_error(err, error_state=False) + return # Start counting down to allow modbus requests. if self._config_delay: self._async_cancel_listener = async_call_later( self.hass, self._config_delay, self.async_end_delay ) - return True @callback def async_end_delay(self, args): @@ -313,8 +318,6 @@ class ModbusHub: return None if not self._client: return None - if not self._client.is_socket_open(): - return None async with self._lock: result = await self.hass.async_add_executor_job( self._pymodbus_call, unit, address, value, use_call diff --git a/tests/components/modbus/test_init.py b/tests/components/modbus/test_init.py index 7dda164e5eb..ec68b98efa0 100644 --- a/tests/components/modbus/test_init.py +++ b/tests/components/modbus/test_init.py @@ -515,35 +515,6 @@ async def test_pymodbus_constructor_fail(hass, caplog): assert mock_pb.called -@pytest.mark.parametrize( - "do_connect,do_exception,do_text", - [ - [False, None, "initial connect failed, no retry"], - [True, ModbusException("no connect"), "Modbus Error: no connect"], - ], -) -async def test_pymodbus_connect_fail( - hass, do_connect, do_exception, do_text, caplog, mock_pymodbus -): - """Run test for failing pymodbus connect.""" - config = { - DOMAIN: [ - { - CONF_TYPE: "tcp", - CONF_HOST: TEST_HOST, - CONF_PORT: 5501, - } - ] - } - caplog.set_level(logging.ERROR) - mock_pymodbus.connect.return_value = do_connect - mock_pymodbus.connect.side_effect = do_exception - assert await async_setup_component(hass, DOMAIN, config) is False - await hass.async_block_till_done() - assert caplog.messages[0].startswith(f"Pymodbus: {do_text}") - assert caplog.records[0].levelname == "ERROR" - - async def test_pymodbus_close_fail(hass, caplog, mock_pymodbus): """Run test for failing pymodbus close.""" config = { @@ -563,44 +534,6 @@ async def test_pymodbus_close_fail(hass, caplog, mock_pymodbus): # Close() is called as part of teardown -async def test_disconnect(hass, mock_pymodbus): - """Run test for startup delay.""" - - # the purpose of this test is to test a device disconnect - # We "hijiack" a binary_sensor to make a proper blackbox test. - entity_id = f"{BINARY_SENSOR_DOMAIN}.{TEST_SENSOR_NAME}" - config = { - DOMAIN: [ - { - CONF_TYPE: "tcp", - CONF_HOST: TEST_HOST, - CONF_PORT: 5501, - CONF_NAME: TEST_MODBUS_NAME, - CONF_BINARY_SENSORS: [ - { - CONF_INPUT_TYPE: CALL_TYPE_COIL, - CONF_NAME: f"{TEST_SENSOR_NAME}", - CONF_ADDRESS: 52, - }, - ], - } - ] - } - mock_pymodbus.read_coils.return_value = ReadResult([0x01]) - mock_pymodbus.is_socket_open.return_value = False - now = dt_util.utcnow() - with mock.patch("homeassistant.helpers.event.dt_util.utcnow", return_value=now): - assert await async_setup_component(hass, DOMAIN, config) is True - await hass.async_block_till_done() - - # pass first scan_interval - now = now + timedelta(seconds=20) - with mock.patch("homeassistant.helpers.event.dt_util.utcnow", return_value=now): - async_fire_time_changed(hass, now) - await hass.async_block_till_done() - assert hass.states.get(entity_id).state == STATE_UNAVAILABLE - - async def test_delay(hass, mock_pymodbus): """Run test for startup delay."""