Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions appdaemon/plugins/hass/hassplugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,8 @@ async def __post_auth__(self) -> None:
if not self.is_ready:
self.logger.info("Waiting for Home Assistant to start")
await self.ready_event.wait()
# Services registered while Home Assistant was starting are missing from the list fetched on connect
await self.get_hass_services()

await self.notify_plugin_started(meta=await self.get_hass_config(), state=await self.get_complete_state())
self.first_time = False
Expand Down
1 change: 1 addition & 0 deletions docs/HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

- Remove outdated references to `app_init_delay`
- Reworked how the `pin_app` and `pin_thread` settings work their way through the internals, and added corresponding tests.
- The HASS plugin refreshes the service list once Home Assistant has started, so services registered during startup, such as `weather/get_forecasts`, work right away.

**Breaking Changes**

Expand Down
39 changes: 39 additions & 0 deletions tests/unit/test_hass_startup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""Tests for the HassPlugin startup sequence."""

from unittest.mock import AsyncMock, MagicMock

import pytest
from appdaemon.plugins.hass.hassplugin import HassPlugin

pytestmark = [
pytest.mark.ci,
pytest.mark.unit,
]


@pytest.mark.asyncio
@pytest.mark.parametrize(
("is_ready", "expected"),
[
(False, ["ready", "services", "started"]),
(True, ["started"]),
],
)
async def test_services_refreshed_after_home_assistant_started(is_ready: bool, expected: list[str]):
"""Services are fetched again only if the plugin had to wait for Home Assistant to start."""
calls = []
plugin = MagicMock()
plugin.first_time = True
plugin.is_ready = is_ready
plugin.config.enable_started_event = True
plugin.websocket_send_json = AsyncMock(return_value={"success": True, "ad_duration": 0})
plugin.wait_for_conditions = AsyncMock()
plugin.ready_event.wait = AsyncMock(side_effect=lambda: calls.append("ready"))
plugin.get_hass_services = AsyncMock(side_effect=lambda: calls.append("services"))
plugin.get_hass_config = AsyncMock(return_value={})
plugin.get_complete_state = AsyncMock(return_value={})
plugin.notify_plugin_started = AsyncMock(side_effect=lambda **_: calls.append("started"))

await HassPlugin.__post_auth__(plugin)

assert calls == expected
Loading