diff --git a/homeassistant/components/zeroconf/__init__.py b/homeassistant/components/zeroconf/__init__.py index e740b46c9eb..66c41c19474 100644 --- a/homeassistant/components/zeroconf/__init__.py +++ b/homeassistant/components/zeroconf/__init__.py @@ -24,7 +24,11 @@ from zeroconf.asyncio import AsyncServiceBrowser, AsyncServiceInfo from homeassistant import config_entries from homeassistant.components import network -from homeassistant.const import EVENT_HOMEASSISTANT_STOP, __version__ +from homeassistant.const import ( + EVENT_HOMEASSISTANT_CLOSE, + EVENT_HOMEASSISTANT_STOP, + __version__, +) from homeassistant.core import Event, HomeAssistant, callback from homeassistant.data_entry_flow import BaseServiceInfo from homeassistant.helpers import discovery_flow, instance_id @@ -163,7 +167,11 @@ async def _async_get_instance(hass: HomeAssistant, **zcargs: Any) -> HaAsyncZero """Stop Zeroconf.""" await aio_zc.ha_async_close() - hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, _async_stop_zeroconf) + # Wait to the close event to shutdown zeroconf to give + # integrations time to send a good bye message + hass.bus.async_listen_once( + EVENT_HOMEASSISTANT_CLOSE, _async_stop_zeroconf, run_immediately=True + ) hass.data[DOMAIN] = aio_zc return aio_zc @@ -240,7 +248,9 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: async def _async_zeroconf_hass_stop(_event: Event) -> None: await discovery.async_stop() - hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, _async_zeroconf_hass_stop) + hass.bus.async_listen_once( + EVENT_HOMEASSISTANT_STOP, _async_zeroconf_hass_stop, run_immediately=True + ) async_when_setup_or_start(hass, "frontend", _async_zeroconf_hass_start) return True diff --git a/tests/components/zeroconf/test_init.py b/tests/components/zeroconf/test_init.py index b156690d290..da817c84448 100644 --- a/tests/components/zeroconf/test_init.py +++ b/tests/components/zeroconf/test_init.py @@ -15,6 +15,7 @@ from zeroconf.asyncio import AsyncServiceInfo from homeassistant.components import zeroconf from homeassistant.const import ( EVENT_COMPONENT_LOADED, + EVENT_HOMEASSISTANT_CLOSE, EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STARTED, EVENT_HOMEASSISTANT_STOP, @@ -935,6 +936,11 @@ async def test_get_instance(hass: HomeAssistant, mock_async_zeroconf: None) -> N ) hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP) await hass.async_block_till_done() + assert len(mock_async_zeroconf.ha_async_close.mock_calls) == 0 + # Only shutdown at the close event so integrations have time + # to send out their goodbyes + hass.bus.async_fire(EVENT_HOMEASSISTANT_CLOSE) + await hass.async_block_till_done() assert len(mock_async_zeroconf.ha_async_close.mock_calls) == 1