Add auto_update property to supervisor and addon update entities (#69055)

This commit is contained in:
Joakim Sørensen 2022-04-01 17:31:39 +02:00 committed by GitHub
parent bda997efe9
commit 78e4d7e1ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 83 additions and 8 deletions

View File

@ -51,6 +51,7 @@ from .auth import async_setup_auth_view
from .const import (
ATTR_ADDON,
ATTR_ADDONS,
ATTR_AUTO_UPDATE,
ATTR_CHANGELOG,
ATTR_DISCOVERY,
ATTR_FOLDERS,
@ -98,6 +99,7 @@ DATA_INFO = "hassio_info"
DATA_OS_INFO = "hassio_os_info"
DATA_SUPERVISOR_INFO = "hassio_supervisor_info"
DATA_ADDONS_CHANGELOGS = "hassio_addons_changelogs"
DATA_ADDONS_INFO = "hassio_addons_info"
DATA_ADDONS_STATS = "hassio_addons_stats"
HASSIO_UPDATE_INTERVAL = timedelta(minutes=5)
@ -422,6 +424,16 @@ def get_supervisor_info(hass):
return hass.data.get(DATA_SUPERVISOR_INFO)
@callback
@bind_hass
def get_addons_info(hass):
"""Return Addons info.
Async friendly.
"""
return hass.data.get(DATA_ADDONS_INFO)
@callback
@bind_hass
def get_addons_stats(hass):
@ -607,6 +619,11 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
changelog = await hassio.get_addon_changelog(slug)
return (slug, changelog)
async def update_addon_info(slug):
"""Return the info for an add-on."""
info = await hassio.get_addon_info(slug)
return (slug, info)
async def update_info_data(now):
"""Update last available supervisor information."""
@ -641,6 +658,11 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
*[update_addon_changelog(addon[ATTR_SLUG]) for addon in addons]
)
)
hass.data[DATA_ADDONS_INFO] = dict(
await asyncio.gather(
*[update_addon_info(addon[ATTR_SLUG]) for addon in addons]
)
)
if ADDONS_COORDINATOR in hass.data:
await hass.data[ADDONS_COORDINATOR].async_refresh()
@ -845,6 +867,7 @@ class HassioDataUpdateCoordinator(DataUpdateCoordinator):
"""Update data via library."""
new_data = {}
supervisor_info = get_supervisor_info(self.hass)
addons_info = get_addons_info(self.hass)
addons_stats = get_addons_stats(self.hass)
addons_changelogs = get_addons_changelogs(self.hass)
store_data = get_store(self.hass)
@ -858,6 +881,9 @@ class HassioDataUpdateCoordinator(DataUpdateCoordinator):
addon[ATTR_SLUG]: {
**addon,
**((addons_stats or {}).get(addon[ATTR_SLUG], {})),
ATTR_AUTO_UPDATE: addons_info.get(addon[ATTR_SLUG], {}).get(
ATTR_AUTO_UPDATE, False
),
ATTR_CHANGELOG: (addons_changelogs or {}).get(addon[ATTR_SLUG]),
ATTR_REPOSITORY: repositories.get(
addon.get(ATTR_REPOSITORY), addon.get(ATTR_REPOSITORY, "")

View File

@ -39,6 +39,7 @@ WS_TYPE_SUBSCRIBE = "supervisor/subscribe"
EVENT_SUPERVISOR_EVENT = "supervisor_event"
ATTR_AUTO_UPDATE = "auto_update"
ATTR_VERSION = "version"
ATTR_VERSION_LATEST = "version_latest"
ATTR_UPDATE_AVAILABLE = "update_available"

View File

@ -24,6 +24,7 @@ from . import (
async_update_supervisor,
)
from .const import (
ATTR_AUTO_UPDATE,
ATTR_CHANGELOG,
ATTR_VERSION,
ATTR_VERSION_LATEST,
@ -99,6 +100,11 @@ class SupervisorAddonUpdateEntity(HassioAddonEntity, UpdateEntity):
"""Return the add-on data."""
return self.coordinator.data[DATA_KEY_ADDONS][self._addon_slug]
@property
def auto_update(self):
"""Return true if auto-update is enabled for the add-on."""
return self._addon_data[ATTR_AUTO_UPDATE]
@property
def title(self) -> str | None:
"""Return the title of the update."""
@ -210,6 +216,7 @@ class SupervisorOSUpdateEntity(HassioOSEntity, UpdateEntity):
class SupervisorSupervisorUpdateEntity(HassioSupervisorEntity, UpdateEntity):
"""Update entity to handle updates for the Home Assistant Supervisor."""
_attr_auto_update = True
_attr_supported_features = UpdateEntityFeature.INSTALL
_attr_title = "Home Assistant Supervisor"

View File

@ -115,7 +115,15 @@ def mock_all(aioclient_mock, request):
},
)
aioclient_mock.get("http://127.0.0.1/addons/test/changelog", text="")
aioclient_mock.get(
"http://127.0.0.1/addons/test/info",
json={"result": "ok", "data": {"auto_update": True}},
)
aioclient_mock.get("http://127.0.0.1/addons/test2/changelog", text="")
aioclient_mock.get(
"http://127.0.0.1/addons/test2/info",
json={"result": "ok", "data": {"auto_update": False}},
)
aioclient_mock.get(
"http://127.0.0.1/ingress/panels", json={"result": "ok", "data": {"panels": {}}}
)

View File

@ -139,7 +139,15 @@ def mock_all(aioclient_mock, request):
},
)
aioclient_mock.get("http://127.0.0.1/addons/test/changelog", text="")
aioclient_mock.get(
"http://127.0.0.1/addons/test/info",
json={"result": "ok", "data": {"auto_update": True}},
)
aioclient_mock.get("http://127.0.0.1/addons/test2/changelog", text="")
aioclient_mock.get(
"http://127.0.0.1/addons/test2/info",
json={"result": "ok", "data": {"auto_update": False}},
)
aioclient_mock.get(
"http://127.0.0.1/ingress/panels", json={"result": "ok", "data": {"panels": {}}}
)

View File

@ -108,7 +108,15 @@ def mock_all(aioclient_mock, request):
},
)
aioclient_mock.get("http://127.0.0.1/addons/test/changelog", text="")
aioclient_mock.get(
"http://127.0.0.1/addons/test/info",
json={"result": "ok", "data": {"auto_update": True}},
)
aioclient_mock.get("http://127.0.0.1/addons/test2/changelog", text="")
aioclient_mock.get(
"http://127.0.0.1/addons/test2/info",
json={"result": "ok", "data": {"auto_update": False}},
)
aioclient_mock.get(
"http://127.0.0.1/ingress/panels", json={"result": "ok", "data": {"panels": {}}}
)

View File

@ -121,23 +121,37 @@ def mock_all(aioclient_mock, request):
},
)
aioclient_mock.get("http://127.0.0.1/addons/test/changelog", text="")
aioclient_mock.get(
"http://127.0.0.1/addons/test/info",
json={"result": "ok", "data": {"auto_update": True}},
)
aioclient_mock.get("http://127.0.0.1/addons/test2/changelog", text="")
aioclient_mock.get(
"http://127.0.0.1/addons/test2/info",
json={"result": "ok", "data": {"auto_update": False}},
)
aioclient_mock.get(
"http://127.0.0.1/ingress/panels", json={"result": "ok", "data": {"panels": {}}}
)
@pytest.mark.parametrize(
"entity_id,expected",
"entity_id,expected_state, auto_update",
[
("update.home_assistant_operating_system_update", "on"),
("update.home_assistant_supervisor_update", "on"),
("update.home_assistant_core_update", "on"),
("update.test_update", "on"),
("update.test2_update", "off"),
("update.home_assistant_operating_system_update", "on", False),
("update.home_assistant_supervisor_update", "on", True),
("update.home_assistant_core_update", "on", False),
("update.test_update", "on", True),
("update.test2_update", "off", False),
],
)
async def test_update_entities(hass, entity_id, expected, aioclient_mock):
async def test_update_entities(
hass,
entity_id,
expected_state,
auto_update,
aioclient_mock,
):
"""Test update entities."""
config_entry = MockConfigEntry(domain=DOMAIN, data={}, unique_id=DOMAIN)
config_entry.add_to_hass(hass)
@ -153,7 +167,10 @@ async def test_update_entities(hass, entity_id, expected, aioclient_mock):
# Verify that the entity have the expected state.
state = hass.states.get(entity_id)
assert state.state == expected
assert state.state == expected_state
# Verify that the auto_update attribute is correct
assert state.attributes["auto_update"] is auto_update
async def test_update_addon(hass, aioclient_mock):