8000 Fix ESPHome entities unavailable if deep sleep enabled after entry setup by oddstr13 · Pull Request #144970 · home-assistant/core · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Fix ESPHome entities unavailable if deep sleep enabled after entry setup #144970

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 15, 2025
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
6 changes: 5 additions & 1 deletion homeassistant/components/esphome/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,6 @@ def __init__(
self._states = cast(dict[int, _StateT], entry_data.state[state_type])
assert entry_data.device_info is not None
device_info = entry_data.device_info
self._device_info = device_info
self._on_entry_data_changed()
self._key = entity_info.key
self._state_type = state_type
Expand Down Expand Up @@ -327,6 +326,11 @@ def _on_state_update(self) -> None:
@callback
def _on_entry_data_changed(self) -> None:
entry_data = self._entry_data
# Update the device info since it can change
# when the device is reconnected
if TYPE_CHECKING:
assert entry_data.device_info is not None
self._device_info = entry_data.device_info
self._api_version = entry_data.api_version
self._client = entry_data.client
if self._device_info.has_deep_sleep:
Expand Down
62 changes: 62 additions & 0 deletions tests/components/esphome/test_entity.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
"""Test ESPHome binary sensors."""

import asyncio
from dataclasses import asdict
from typing import Any
from unittest.mock import AsyncMock

from aioesphomeapi import (
APIClient,
BinarySensorInfo,
BinarySensorState,
DeviceInfo,
SensorInfo,
SensorState,
build_unique_id,
Expand Down Expand Up @@ -665,3 +667,63 @@ async def test_entity_id_preserved_on_upgrade_when_in_storage(
)
state = hass.states.get("binary_sensor.user_named")
assert state is not None


async def test_deep_sleep_added_after_setup(
hass: HomeAssistant,
mock_client: APIClient,
mock_esphome_device: MockESPHomeDeviceType,
) -> None:
"""Test deep sleep added after setup."""
mock_device = await mock_esphome_device(
mock_client=mock_client,
entity_info=[
BinarySensorInfo(
object_id="test",
key=1,
name="test",
unique_id="test",
),
],
user_service=[],
states=[
BinarySensorState(key=1, state=True, missing_state=False),
],
device_info={"has_deep_sleep": False},
)

entity_id = "binary_sensor.test_test"
state = hass.states.get(entity_id)
assert state is not None
assert state.state == STATE_ON

await mock_device.mock_disconnect(expected_disconnect=True)

# No deep sleep, should be unavailable
state = hass.states.get(entity_id)
assert state is not None
assert state.state == STATE_UNAVAILABLE

await mock_device.mock_connect()

# reconnect, should be available
state = hass.states.get(entity_id)
assert state is not None
assert state.state == STATE_ON

await mock_device.mock_disconnect(expected_disconnect=True)
new_device_info = DeviceInfo(
**{**asdict(mock_device.device_info), "has_deep_sleep": True}
)
mock_device.client.device_info = AsyncMock(return_value=new_device_info)
mock_device.device_info = new_device_info

await mock_device.mock_connect()

# Now disconnect that deep sleep is set in device info
await mock_device.mock_disconnect(expected_disconnect=True)

# Deep sleep, should be available
state = hass.states.get(entity_id)
assert state is not None
assert state.state == STATE_ON
0