Skip to content
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

Do not create ESPHome Dashboard update entity if no configuration found #129751

Open
wants to merge 9 commits into
base: dev
Choose a base branch
from
19 changes: 14 additions & 5 deletions homeassistant/components/esphome/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ async def async_setup_entry(
if (dashboard := async_get_dashboard(hass)) is None:
return
entry_data = DomainData.get(hass).get_entry_data(entry)
assert entry_data.device_info is not None
device_name = entry_data.device_info.name
unsubs: list[CALLBACK_TYPE] = []

@callback
Expand All @@ -72,13 +74,22 @@ def _async_setup_update_entity() -> None:
if not entry_data.available or not dashboard.last_update_success:
return

# Do not add Dashboard Entity if this device is not known to the ESPHome dashboard.
if dashboard.data is None or dashboard.data.get(device_name) is None:
return

for unsub in unsubs:
unsub()
unsubs.clear()

async_add_entities([ESPHomeDashboardUpdateEntity(entry_data, dashboard)])

if entry_data.available and dashboard.last_update_success:
if (
entry_data.available
and dashboard.last_update_success
and dashboard.data is not None
and dashboard.data.get(device_name)
):
_async_setup_update_entity()
return

Expand Down Expand Up @@ -133,10 +144,8 @@ def _update_attrs(self) -> None:
self._attr_supported_features = NO_FEATURES
self._attr_installed_version = device_info.esphome_version
device = coordinator.data.get(device_info.name)
if device is None:
self._attr_latest_version = None
else:
self._attr_latest_version = device["current_version"]
assert device is not None
self._attr_latest_version = device["current_version"]

@callback
def _handle_coordinator_update(self) -> None:
Expand Down
47 changes: 36 additions & 11 deletions tests/components/esphome/test_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
STATE_OFF,
STATE_ON,
STATE_UNAVAILABLE,
STATE_UNKNOWN,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
Expand Down Expand Up @@ -83,11 +82,6 @@ def stub_reconnect():
"supported_features": 0,
},
),
(
[],
STATE_UNKNOWN, # dashboard is available but device is unknown
{"supported_features": 0},
),
],
)
async def test_update_entity(
Expand Down Expand Up @@ -408,11 +402,7 @@ async def test_update_becomes_available_at_runtime(
)
await hass.async_block_till_done()
state = hass.states.get("update.test_firmware")
assert state is not None
features = state.attributes[ATTR_SUPPORTED_FEATURES]
# There are no devices on the dashboard so no
# way to tell the version so install is disabled
assert features is UpdateEntityFeature(0)
assert state is None

# A device gets added to the dashboard
mock_dashboard["configured"] = [
Expand All @@ -433,6 +423,41 @@ async def test_update_becomes_available_at_runtime(
assert features is UpdateEntityFeature.INSTALL


async def test_update_entity_not_present_with_dashboard_but_unknown_device(
hass: HomeAssistant,
mock_client: APIClient,
mock_esphome_device: Callable[
[APIClient, list[EntityInfo], list[UserService], list[EntityState]],
Awaitable[MockESPHomeDevice],
],
mock_dashboard: dict[str, Any],
) -> None:
"""Test ESPHome update entity does not get created if the device is unknown to the dashboard."""
await mock_esphome_device(
mock_client=mock_client,
entity_info=[],
user_service=[],
states=[],
)

mock_dashboard["configured"] = [
{
"name": "other-test",
"current_version": "2023.2.0-dev",
"configuration": "other-test.yaml",
}
]

state = hass.states.get("update.test_firmware")
assert state is None

await async_get_dashboard(hass).async_refresh()
await hass.async_block_till_done()

state = hass.states.get("update.none_firmware")
assert state is None


async def test_generic_device_update_entity(
hass: HomeAssistant,
mock_client: APIClient,
Expand Down