mirror of
https://github.com/home-assistant/core.git
synced 2025-04-27 02:37:50 +00:00
Add auto_update property to supervisor and addon update entities (#69055)
This commit is contained in:
parent
bda997efe9
commit
78e4d7e1ca
@ -51,6 +51,7 @@ from .auth import async_setup_auth_view
|
|||||||
from .const import (
|
from .const import (
|
||||||
ATTR_ADDON,
|
ATTR_ADDON,
|
||||||
ATTR_ADDONS,
|
ATTR_ADDONS,
|
||||||
|
ATTR_AUTO_UPDATE,
|
||||||
ATTR_CHANGELOG,
|
ATTR_CHANGELOG,
|
||||||
ATTR_DISCOVERY,
|
ATTR_DISCOVERY,
|
||||||
ATTR_FOLDERS,
|
ATTR_FOLDERS,
|
||||||
@ -98,6 +99,7 @@ DATA_INFO = "hassio_info"
|
|||||||
DATA_OS_INFO = "hassio_os_info"
|
DATA_OS_INFO = "hassio_os_info"
|
||||||
DATA_SUPERVISOR_INFO = "hassio_supervisor_info"
|
DATA_SUPERVISOR_INFO = "hassio_supervisor_info"
|
||||||
DATA_ADDONS_CHANGELOGS = "hassio_addons_changelogs"
|
DATA_ADDONS_CHANGELOGS = "hassio_addons_changelogs"
|
||||||
|
DATA_ADDONS_INFO = "hassio_addons_info"
|
||||||
DATA_ADDONS_STATS = "hassio_addons_stats"
|
DATA_ADDONS_STATS = "hassio_addons_stats"
|
||||||
HASSIO_UPDATE_INTERVAL = timedelta(minutes=5)
|
HASSIO_UPDATE_INTERVAL = timedelta(minutes=5)
|
||||||
|
|
||||||
@ -422,6 +424,16 @@ def get_supervisor_info(hass):
|
|||||||
return hass.data.get(DATA_SUPERVISOR_INFO)
|
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
|
@callback
|
||||||
@bind_hass
|
@bind_hass
|
||||||
def get_addons_stats(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)
|
changelog = await hassio.get_addon_changelog(slug)
|
||||||
return (slug, changelog)
|
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):
|
async def update_info_data(now):
|
||||||
"""Update last available supervisor information."""
|
"""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]
|
*[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:
|
if ADDONS_COORDINATOR in hass.data:
|
||||||
await hass.data[ADDONS_COORDINATOR].async_refresh()
|
await hass.data[ADDONS_COORDINATOR].async_refresh()
|
||||||
@ -845,6 +867,7 @@ class HassioDataUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
"""Update data via library."""
|
"""Update data via library."""
|
||||||
new_data = {}
|
new_data = {}
|
||||||
supervisor_info = get_supervisor_info(self.hass)
|
supervisor_info = get_supervisor_info(self.hass)
|
||||||
|
addons_info = get_addons_info(self.hass)
|
||||||
addons_stats = get_addons_stats(self.hass)
|
addons_stats = get_addons_stats(self.hass)
|
||||||
addons_changelogs = get_addons_changelogs(self.hass)
|
addons_changelogs = get_addons_changelogs(self.hass)
|
||||||
store_data = get_store(self.hass)
|
store_data = get_store(self.hass)
|
||||||
@ -858,6 +881,9 @@ class HassioDataUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
addon[ATTR_SLUG]: {
|
addon[ATTR_SLUG]: {
|
||||||
**addon,
|
**addon,
|
||||||
**((addons_stats or {}).get(addon[ATTR_SLUG], {})),
|
**((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_CHANGELOG: (addons_changelogs or {}).get(addon[ATTR_SLUG]),
|
||||||
ATTR_REPOSITORY: repositories.get(
|
ATTR_REPOSITORY: repositories.get(
|
||||||
addon.get(ATTR_REPOSITORY), addon.get(ATTR_REPOSITORY, "")
|
addon.get(ATTR_REPOSITORY), addon.get(ATTR_REPOSITORY, "")
|
||||||
|
@ -39,6 +39,7 @@ WS_TYPE_SUBSCRIBE = "supervisor/subscribe"
|
|||||||
|
|
||||||
EVENT_SUPERVISOR_EVENT = "supervisor_event"
|
EVENT_SUPERVISOR_EVENT = "supervisor_event"
|
||||||
|
|
||||||
|
ATTR_AUTO_UPDATE = "auto_update"
|
||||||
ATTR_VERSION = "version"
|
ATTR_VERSION = "version"
|
||||||
ATTR_VERSION_LATEST = "version_latest"
|
ATTR_VERSION_LATEST = "version_latest"
|
||||||
ATTR_UPDATE_AVAILABLE = "update_available"
|
ATTR_UPDATE_AVAILABLE = "update_available"
|
||||||
|
@ -24,6 +24,7 @@ from . import (
|
|||||||
async_update_supervisor,
|
async_update_supervisor,
|
||||||
)
|
)
|
||||||
from .const import (
|
from .const import (
|
||||||
|
ATTR_AUTO_UPDATE,
|
||||||
ATTR_CHANGELOG,
|
ATTR_CHANGELOG,
|
||||||
ATTR_VERSION,
|
ATTR_VERSION,
|
||||||
ATTR_VERSION_LATEST,
|
ATTR_VERSION_LATEST,
|
||||||
@ -99,6 +100,11 @@ class SupervisorAddonUpdateEntity(HassioAddonEntity, UpdateEntity):
|
|||||||
"""Return the add-on data."""
|
"""Return the add-on data."""
|
||||||
return self.coordinator.data[DATA_KEY_ADDONS][self._addon_slug]
|
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
|
@property
|
||||||
def title(self) -> str | None:
|
def title(self) -> str | None:
|
||||||
"""Return the title of the update."""
|
"""Return the title of the update."""
|
||||||
@ -210,6 +216,7 @@ class SupervisorOSUpdateEntity(HassioOSEntity, UpdateEntity):
|
|||||||
class SupervisorSupervisorUpdateEntity(HassioSupervisorEntity, UpdateEntity):
|
class SupervisorSupervisorUpdateEntity(HassioSupervisorEntity, UpdateEntity):
|
||||||
"""Update entity to handle updates for the Home Assistant Supervisor."""
|
"""Update entity to handle updates for the Home Assistant Supervisor."""
|
||||||
|
|
||||||
|
_attr_auto_update = True
|
||||||
_attr_supported_features = UpdateEntityFeature.INSTALL
|
_attr_supported_features = UpdateEntityFeature.INSTALL
|
||||||
_attr_title = "Home Assistant Supervisor"
|
_attr_title = "Home Assistant Supervisor"
|
||||||
|
|
||||||
|
@ -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/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/changelog", text="")
|
||||||
|
aioclient_mock.get(
|
||||||
|
"http://127.0.0.1/addons/test2/info",
|
||||||
|
json={"result": "ok", "data": {"auto_update": False}},
|
||||||
|
)
|
||||||
aioclient_mock.get(
|
aioclient_mock.get(
|
||||||
"http://127.0.0.1/ingress/panels", json={"result": "ok", "data": {"panels": {}}}
|
"http://127.0.0.1/ingress/panels", json={"result": "ok", "data": {"panels": {}}}
|
||||||
)
|
)
|
||||||
|
@ -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/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/changelog", text="")
|
||||||
|
aioclient_mock.get(
|
||||||
|
"http://127.0.0.1/addons/test2/info",
|
||||||
|
json={"result": "ok", "data": {"auto_update": False}},
|
||||||
|
)
|
||||||
aioclient_mock.get(
|
aioclient_mock.get(
|
||||||
"http://127.0.0.1/ingress/panels", json={"result": "ok", "data": {"panels": {}}}
|
"http://127.0.0.1/ingress/panels", json={"result": "ok", "data": {"panels": {}}}
|
||||||
)
|
)
|
||||||
|
@ -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/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/changelog", text="")
|
||||||
|
aioclient_mock.get(
|
||||||
|
"http://127.0.0.1/addons/test2/info",
|
||||||
|
json={"result": "ok", "data": {"auto_update": False}},
|
||||||
|
)
|
||||||
aioclient_mock.get(
|
aioclient_mock.get(
|
||||||
"http://127.0.0.1/ingress/panels", json={"result": "ok", "data": {"panels": {}}}
|
"http://127.0.0.1/ingress/panels", json={"result": "ok", "data": {"panels": {}}}
|
||||||
)
|
)
|
||||||
|
@ -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/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/changelog", text="")
|
||||||
|
aioclient_mock.get(
|
||||||
|
"http://127.0.0.1/addons/test2/info",
|
||||||
|
json={"result": "ok", "data": {"auto_update": False}},
|
||||||
|
)
|
||||||
aioclient_mock.get(
|
aioclient_mock.get(
|
||||||
"http://127.0.0.1/ingress/panels", json={"result": "ok", "data": {"panels": {}}}
|
"http://127.0.0.1/ingress/panels", json={"result": "ok", "data": {"panels": {}}}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"entity_id,expected",
|
"entity_id,expected_state, auto_update",
|
||||||
[
|
[
|
||||||
("update.home_assistant_operating_system_update", "on"),
|
("update.home_assistant_operating_system_update", "on", False),
|
||||||
("update.home_assistant_supervisor_update", "on"),
|
("update.home_assistant_supervisor_update", "on", True),
|
||||||
("update.home_assistant_core_update", "on"),
|
("update.home_assistant_core_update", "on", False),
|
||||||
("update.test_update", "on"),
|
("update.test_update", "on", True),
|
||||||
("update.test2_update", "off"),
|
("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."""
|
"""Test update entities."""
|
||||||
config_entry = MockConfigEntry(domain=DOMAIN, data={}, unique_id=DOMAIN)
|
config_entry = MockConfigEntry(domain=DOMAIN, data={}, unique_id=DOMAIN)
|
||||||
config_entry.add_to_hass(hass)
|
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.
|
# Verify that the entity have the expected state.
|
||||||
state = hass.states.get(entity_id)
|
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):
|
async def test_update_addon(hass, aioclient_mock):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user