Add esphome native device update entities (#119339)

Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
Jesse Hills 2024-06-18 16:31:50 +12:00 committed by GitHub
parent faf2a447a4
commit f8711dbfbf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 205 additions and 8 deletions

View file

@ -3,12 +3,21 @@
from collections.abc import Awaitable, Callable
from unittest.mock import Mock, patch
from aioesphomeapi import APIClient, EntityInfo, EntityState, UserService
from aioesphomeapi import (
APIClient,
EntityInfo,
EntityState,
UpdateInfo,
UpdateState,
UserService,
)
import pytest
from homeassistant.components.esphome.dashboard import async_get_dashboard
from homeassistant.components.update import UpdateEntityFeature
from homeassistant.components.update import DOMAIN as UPDATE_DOMAIN, UpdateEntityFeature
from homeassistant.components.update.const import SERVICE_INSTALL
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_SUPPORTED_FEATURES,
STATE_OFF,
STATE_ON,
@ -83,7 +92,7 @@ async def test_update_entity(
with patch(
"homeassistant.components.esphome.update.DomainData.get_entry_data",
return_value=Mock(available=True, device_info=mock_device_info),
return_value=Mock(available=True, device_info=mock_device_info, info={}),
):
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
@ -266,7 +275,7 @@ async def test_update_entity_dashboard_not_available_startup(
with (
patch(
"homeassistant.components.esphome.update.DomainData.get_entry_data",
return_value=Mock(available=True, device_info=mock_device_info),
return_value=Mock(available=True, device_info=mock_device_info, info={}),
),
patch(
"esphome_dashboard_api.ESPHomeDashboardAPI.get_devices",
@ -358,7 +367,7 @@ async def test_update_entity_not_present_without_dashboard(
"""Test ESPHome update entity does not get created if there is no dashboard."""
with patch(
"homeassistant.components.esphome.update.DomainData.get_entry_data",
return_value=Mock(available=True, device_info=mock_device_info),
return_value=Mock(available=True, device_info=mock_device_info, info={}),
):
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
@ -408,3 +417,104 @@ async def test_update_becomes_available_at_runtime(
# We now know the version so install is enabled
features = state.attributes[ATTR_SUPPORTED_FEATURES]
assert features is UpdateEntityFeature.INSTALL
async def test_generic_device_update_entity(
hass: HomeAssistant,
mock_client: APIClient,
mock_generic_device_entry,
) -> None:
"""Test a generic device update entity."""
entity_info = [
UpdateInfo(
object_id="myupdate",
key=1,
name="my update",
unique_id="my_update",
)
]
states = [
UpdateState(
key=1,
current_version="2024.6.0",
latest_version="2024.6.0",
title="ESPHome Project",
release_summary="This is a release summary",
release_url="https://esphome.io/changelog",
)
]
user_service = []
await mock_generic_device_entry(
mock_client=mock_client,
entity_info=entity_info,
user_service=user_service,
states=states,
)
state = hass.states.get("update.test_myupdate")
assert state is not None
assert state.state == STATE_OFF
async def test_generic_device_update_entity_has_update(
hass: HomeAssistant,
mock_client: APIClient,
mock_esphome_device: Callable[
[APIClient, list[EntityInfo], list[UserService], list[EntityState]],
Awaitable[MockESPHomeDevice],
],
) -> None:
"""Test a generic device update entity with an update."""
entity_info = [
UpdateInfo(
object_id="myupdate",
key=1,
name="my update",
unique_id="my_update",
)
]
states = [
UpdateState(
key=1,
current_version="2024.6.0",
latest_version="2024.6.1",
title="ESPHome Project",
release_summary="This is a release summary",
release_url="https://esphome.io/changelog",
)
]
user_service = []
mock_device: MockESPHomeDevice = await mock_esphome_device(
mock_client=mock_client,
entity_info=entity_info,
user_service=user_service,
states=states,
)
state = hass.states.get("update.test_myupdate")
assert state is not None
assert state.state == STATE_ON
await hass.services.async_call(
UPDATE_DOMAIN,
SERVICE_INSTALL,
{ATTR_ENTITY_ID: "update.test_myupdate"},
blocking=True,
)
mock_device.set_state(
UpdateState(
key=1,
in_progress=True,
has_progress=True,
progress=50,
current_version="2024.6.0",
latest_version="2024.6.1",
title="ESPHome Project",
release_summary="This is a release summary",
release_url="https://esphome.io/changelog",
)
)
state = hass.states.get("update.test_myupdate")
assert state is not None
assert state.state == STATE_ON
assert state.attributes["in_progress"] == 50