mirror of
https://github.com/home-assistant/core.git
synced 2025-07-18 18:57:06 +00:00
Use async_release_notes in ESPHome update entity (#144440)
This commit is contained in:
parent
1322d54371
commit
bdf4a21976
@ -134,6 +134,22 @@ def esphome_state_property[_R, _EntityT: EsphomeEntity[Any, Any]](
|
|||||||
return _wrapper
|
return _wrapper
|
||||||
|
|
||||||
|
|
||||||
|
def async_esphome_state_property[_R, _EntityT: EsphomeEntity[Any, Any]](
|
||||||
|
func: Callable[[_EntityT], Awaitable[_R | None]],
|
||||||
|
) -> Callable[[_EntityT], Coroutine[Any, Any, _R | None]]:
|
||||||
|
"""Wrap a state property of an esphome entity.
|
||||||
|
|
||||||
|
This checks if the state object in the entity is set
|
||||||
|
and returns None if it is not set.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@functools.wraps(func)
|
||||||
|
async def _wrapper(self: _EntityT) -> _R | None:
|
||||||
|
return await func(self) if self._has_state else None
|
||||||
|
|
||||||
|
return _wrapper
|
||||||
|
|
||||||
|
|
||||||
def esphome_float_state_property[_EntityT: EsphomeEntity[Any, Any]](
|
def esphome_float_state_property[_EntityT: EsphomeEntity[Any, Any]](
|
||||||
func: Callable[[_EntityT], float | None],
|
func: Callable[[_EntityT], float | None],
|
||||||
) -> Callable[[_EntityT], float | None]:
|
) -> Callable[[_EntityT], float | None]:
|
||||||
|
@ -31,6 +31,7 @@ from .coordinator import ESPHomeDashboardCoordinator
|
|||||||
from .dashboard import async_get_dashboard
|
from .dashboard import async_get_dashboard
|
||||||
from .entity import (
|
from .entity import (
|
||||||
EsphomeEntity,
|
EsphomeEntity,
|
||||||
|
async_esphome_state_property,
|
||||||
convert_api_error_ha_error,
|
convert_api_error_ha_error,
|
||||||
esphome_state_property,
|
esphome_state_property,
|
||||||
platform_async_setup_entry,
|
platform_async_setup_entry,
|
||||||
@ -270,7 +271,9 @@ class ESPHomeUpdateEntity(EsphomeEntity[UpdateInfo, UpdateState], UpdateEntity):
|
|||||||
"""A update implementation for esphome."""
|
"""A update implementation for esphome."""
|
||||||
|
|
||||||
_attr_supported_features = (
|
_attr_supported_features = (
|
||||||
UpdateEntityFeature.INSTALL | UpdateEntityFeature.PROGRESS
|
UpdateEntityFeature.INSTALL
|
||||||
|
| UpdateEntityFeature.PROGRESS
|
||||||
|
| UpdateEntityFeature.RELEASE_NOTES
|
||||||
)
|
)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
@ -300,11 +303,12 @@ class ESPHomeUpdateEntity(EsphomeEntity[UpdateInfo, UpdateState], UpdateEntity):
|
|||||||
"""Return the latest version."""
|
"""Return the latest version."""
|
||||||
return self._state.latest_version
|
return self._state.latest_version
|
||||||
|
|
||||||
@property
|
@async_esphome_state_property
|
||||||
@esphome_state_property
|
async def async_release_notes(self) -> str | None:
|
||||||
def release_summary(self) -> str:
|
"""Return the release notes."""
|
||||||
"""Return the release summary."""
|
if self._state.release_summary:
|
||||||
return self._state.release_summary
|
return self._state.release_summary
|
||||||
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@esphome_state_property
|
@esphome_state_property
|
||||||
|
@ -13,6 +13,8 @@ from homeassistant.components.homeassistant import (
|
|||||||
SERVICE_UPDATE_ENTITY,
|
SERVICE_UPDATE_ENTITY,
|
||||||
)
|
)
|
||||||
from homeassistant.components.update import (
|
from homeassistant.components.update import (
|
||||||
|
ATTR_IN_PROGRESS,
|
||||||
|
ATTR_UPDATE_PERCENTAGE,
|
||||||
DOMAIN as UPDATE_DOMAIN,
|
DOMAIN as UPDATE_DOMAIN,
|
||||||
SERVICE_INSTALL,
|
SERVICE_INSTALL,
|
||||||
UpdateEntityFeature,
|
UpdateEntityFeature,
|
||||||
@ -29,6 +31,12 @@ from homeassistant.exceptions import HomeAssistantError
|
|||||||
|
|
||||||
from .conftest import MockESPHomeDeviceType, MockGenericDeviceEntryType
|
from .conftest import MockESPHomeDeviceType, MockGenericDeviceEntryType
|
||||||
|
|
||||||
|
from tests.typing import WebSocketGenerator
|
||||||
|
|
||||||
|
RELEASE_SUMMARY = "This is a release summary"
|
||||||
|
RELEASE_URL = "https://esphome.io/changelog"
|
||||||
|
ENTITY_ID = "update.test_myupdate"
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def enable_entity(entity_registry_enabled_by_default: None) -> None:
|
def enable_entity(entity_registry_enabled_by_default: None) -> None:
|
||||||
@ -461,8 +469,8 @@ async def test_generic_device_update_entity(
|
|||||||
current_version="2024.6.0",
|
current_version="2024.6.0",
|
||||||
latest_version="2024.6.0",
|
latest_version="2024.6.0",
|
||||||
title="ESPHome Project",
|
title="ESPHome Project",
|
||||||
release_summary="This is a release summary",
|
release_summary=RELEASE_SUMMARY,
|
||||||
release_url="https://esphome.io/changelog",
|
release_url=RELEASE_URL,
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
user_service = []
|
user_service = []
|
||||||
@ -472,7 +480,7 @@ async def test_generic_device_update_entity(
|
|||||||
user_service=user_service,
|
user_service=user_service,
|
||||||
states=states,
|
states=states,
|
||||||
)
|
)
|
||||||
state = hass.states.get("update.test_myupdate")
|
state = hass.states.get(ENTITY_ID)
|
||||||
assert state is not None
|
assert state is not None
|
||||||
assert state.state == STATE_OFF
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
@ -497,8 +505,8 @@ async def test_generic_device_update_entity_has_update(
|
|||||||
current_version="2024.6.0",
|
current_version="2024.6.0",
|
||||||
latest_version="2024.6.1",
|
latest_version="2024.6.1",
|
||||||
title="ESPHome Project",
|
title="ESPHome Project",
|
||||||
release_summary="This is a release summary",
|
release_summary=RELEASE_SUMMARY,
|
||||||
release_url="https://esphome.io/changelog",
|
release_url=RELEASE_URL,
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
user_service = []
|
user_service = []
|
||||||
@ -508,14 +516,14 @@ async def test_generic_device_update_entity_has_update(
|
|||||||
user_service=user_service,
|
user_service=user_service,
|
||||||
states=states,
|
states=states,
|
||||||
)
|
)
|
||||||
state = hass.states.get("update.test_myupdate")
|
state = hass.states.get(ENTITY_ID)
|
||||||
assert state is not None
|
assert state is not None
|
||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
UPDATE_DOMAIN,
|
UPDATE_DOMAIN,
|
||||||
SERVICE_INSTALL,
|
SERVICE_INSTALL,
|
||||||
{ATTR_ENTITY_ID: "update.test_myupdate"},
|
{ATTR_ENTITY_ID: ENTITY_ID},
|
||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -528,27 +536,129 @@ async def test_generic_device_update_entity_has_update(
|
|||||||
current_version="2024.6.0",
|
current_version="2024.6.0",
|
||||||
latest_version="2024.6.1",
|
latest_version="2024.6.1",
|
||||||
title="ESPHome Project",
|
title="ESPHome Project",
|
||||||
release_summary="This is a release summary",
|
release_summary=RELEASE_SUMMARY,
|
||||||
release_url="https://esphome.io/changelog",
|
release_url=RELEASE_URL,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
state = hass.states.get("update.test_myupdate")
|
state = hass.states.get(ENTITY_ID)
|
||||||
assert state is not None
|
assert state is not None
|
||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
assert state.attributes["in_progress"] is True
|
assert state.attributes[ATTR_IN_PROGRESS] is True
|
||||||
assert state.attributes["update_percentage"] == 50
|
assert state.attributes[ATTR_UPDATE_PERCENTAGE] == 50
|
||||||
|
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
HOMEASSISTANT_DOMAIN,
|
HOMEASSISTANT_DOMAIN,
|
||||||
SERVICE_UPDATE_ENTITY,
|
SERVICE_UPDATE_ENTITY,
|
||||||
{ATTR_ENTITY_ID: "update.test_myupdate"},
|
{ATTR_ENTITY_ID: ENTITY_ID},
|
||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
mock_device.set_state(
|
||||||
|
UpdateState(
|
||||||
|
key=1,
|
||||||
|
in_progress=True,
|
||||||
|
has_progress=False,
|
||||||
|
current_version="2024.6.0",
|
||||||
|
latest_version="2024.6.1",
|
||||||
|
title="ESPHome Project",
|
||||||
|
release_summary=RELEASE_SUMMARY,
|
||||||
|
release_url=RELEASE_URL,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
state = hass.states.get(ENTITY_ID)
|
||||||
|
assert state is not None
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
assert state.attributes[ATTR_IN_PROGRESS] is True
|
||||||
|
assert state.attributes[ATTR_UPDATE_PERCENTAGE] is None
|
||||||
|
|
||||||
mock_client.update_command.assert_called_with(key=1, command=UpdateCommand.CHECK)
|
mock_client.update_command.assert_called_with(key=1, command=UpdateCommand.CHECK)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_update_entity_release_notes(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_client: APIClient,
|
||||||
|
mock_esphome_device: MockESPHomeDeviceType,
|
||||||
|
hass_ws_client: WebSocketGenerator,
|
||||||
|
) -> None:
|
||||||
|
"""Test ESPHome update entity release notes."""
|
||||||
|
entity_info = [
|
||||||
|
UpdateInfo(
|
||||||
|
object_id="myupdate",
|
||||||
|
key=1,
|
||||||
|
name="my update",
|
||||||
|
unique_id="my_update",
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
user_service = []
|
||||||
|
mock_device = await mock_esphome_device(
|
||||||
|
mock_client=mock_client,
|
||||||
|
entity_info=entity_info,
|
||||||
|
user_service=user_service,
|
||||||
|
states=[],
|
||||||
|
)
|
||||||
|
|
||||||
|
# release notes
|
||||||
|
client = await hass_ws_client(hass)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
await client.send_json(
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"type": "update/release_notes",
|
||||||
|
"entity_id": ENTITY_ID,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
result = await client.receive_json()
|
||||||
|
assert result["result"] is None
|
||||||
|
|
||||||
|
mock_device.set_state(
|
||||||
|
UpdateState(
|
||||||
|
key=1,
|
||||||
|
current_version="2024.6.0",
|
||||||
|
latest_version="2024.6.1",
|
||||||
|
title="ESPHome Project",
|
||||||
|
release_summary="",
|
||||||
|
release_url=RELEASE_URL,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
await client.send_json(
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"type": "update/release_notes",
|
||||||
|
"entity_id": ENTITY_ID,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
result = await client.receive_json()
|
||||||
|
assert result["result"] is None
|
||||||
|
|
||||||
|
mock_device.set_state(
|
||||||
|
UpdateState(
|
||||||
|
key=1,
|
||||||
|
current_version="2024.6.0",
|
||||||
|
latest_version="2024.6.1",
|
||||||
|
title="ESPHome Project",
|
||||||
|
release_summary=RELEASE_SUMMARY,
|
||||||
|
release_url=RELEASE_URL,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
await client.send_json(
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"type": "update/release_notes",
|
||||||
|
"entity_id": ENTITY_ID,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
result = await client.receive_json()
|
||||||
|
assert result["result"] == RELEASE_SUMMARY
|
||||||
|
|
||||||
|
|
||||||
async def test_attempt_to_update_twice(
|
async def test_attempt_to_update_twice(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
mock_client: APIClient,
|
mock_client: APIClient,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user