Add more supervisor info to system info panel (#115715)
* Add virtualization field fo system info * Add ntp sync and host connectivity * Prevent nonetype errors * Add supervisor_connectivity and fix tests * Add mock of network info to other fixtures * Update more fixtures with network/info mockpull/118317/head
parent
e58d060f82
commit
dbcef2e3c3
|
@ -73,6 +73,7 @@ from .const import (
|
|||
DATA_HOST_INFO,
|
||||
DATA_INFO,
|
||||
DATA_KEY_SUPERVISOR_ISSUES,
|
||||
DATA_NETWORK_INFO,
|
||||
DATA_OS_INFO,
|
||||
DATA_STORE,
|
||||
DATA_SUPERVISOR_INFO,
|
||||
|
@ -429,6 +430,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
|
|||
hass.data[DATA_CORE_INFO],
|
||||
hass.data[DATA_SUPERVISOR_INFO],
|
||||
hass.data[DATA_OS_INFO],
|
||||
hass.data[DATA_NETWORK_INFO],
|
||||
) = await asyncio.gather(
|
||||
create_eager_task(hassio.get_info()),
|
||||
create_eager_task(hassio.get_host_info()),
|
||||
|
@ -436,6 +438,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
|
|||
create_eager_task(hassio.get_core_info()),
|
||||
create_eager_task(hassio.get_supervisor_info()),
|
||||
create_eager_task(hassio.get_os_info()),
|
||||
create_eager_task(hassio.get_network_info()),
|
||||
)
|
||||
|
||||
except HassioAPIError as err:
|
||||
|
|
|
@ -70,6 +70,7 @@ DATA_HOST_INFO = "hassio_host_info"
|
|||
DATA_STORE = "hassio_store"
|
||||
DATA_INFO = "hassio_info"
|
||||
DATA_OS_INFO = "hassio_os_info"
|
||||
DATA_NETWORK_INFO = "hassio_network_info"
|
||||
DATA_SUPERVISOR_INFO = "hassio_supervisor_info"
|
||||
DATA_SUPERVISOR_STATS = "hassio_supervisor_stats"
|
||||
DATA_ADDONS_CHANGELOGS = "hassio_addons_changelogs"
|
||||
|
|
|
@ -42,6 +42,7 @@ from .const import (
|
|||
DATA_KEY_OS,
|
||||
DATA_KEY_SUPERVISOR,
|
||||
DATA_KEY_SUPERVISOR_ISSUES,
|
||||
DATA_NETWORK_INFO,
|
||||
DATA_OS_INFO,
|
||||
DATA_STORE,
|
||||
DATA_SUPERVISOR_INFO,
|
||||
|
@ -100,6 +101,16 @@ def get_supervisor_info(hass: HomeAssistant) -> dict[str, Any] | None:
|
|||
return hass.data.get(DATA_SUPERVISOR_INFO)
|
||||
|
||||
|
||||
@callback
|
||||
@bind_hass
|
||||
def get_network_info(hass: HomeAssistant) -> dict[str, Any] | None:
|
||||
"""Return Host Network information.
|
||||
|
||||
Async friendly.
|
||||
"""
|
||||
return hass.data.get(DATA_NETWORK_INFO)
|
||||
|
||||
|
||||
@callback
|
||||
@bind_hass
|
||||
def get_addons_info(hass: HomeAssistant) -> dict[str, dict[str, Any]] | None:
|
||||
|
|
|
@ -382,6 +382,14 @@ class HassIO:
|
|||
"""
|
||||
return self.send_command("/supervisor/info", method="get")
|
||||
|
||||
@api_data
|
||||
def get_network_info(self) -> Coroutine:
|
||||
"""Return data for the Host Network.
|
||||
|
||||
This method returns a coroutine.
|
||||
"""
|
||||
return self.send_command("/network/info", method="get")
|
||||
|
||||
@api_data
|
||||
def get_addon_info(self, addon: str) -> Coroutine:
|
||||
"""Return data for a Add-on.
|
||||
|
|
|
@ -8,7 +8,13 @@ from typing import Any
|
|||
from homeassistant.components import system_health
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
|
||||
from .coordinator import get_host_info, get_info, get_os_info, get_supervisor_info
|
||||
from .coordinator import (
|
||||
get_host_info,
|
||||
get_info,
|
||||
get_network_info,
|
||||
get_os_info,
|
||||
get_supervisor_info,
|
||||
)
|
||||
|
||||
SUPERVISOR_PING = "http://{ip_address}/supervisor/ping"
|
||||
OBSERVER_URL = "http://{ip_address}:4357"
|
||||
|
@ -28,6 +34,7 @@ async def system_health_info(hass: HomeAssistant) -> dict[str, Any]:
|
|||
info = get_info(hass) or {}
|
||||
host_info = get_host_info(hass) or {}
|
||||
supervisor_info = get_supervisor_info(hass)
|
||||
network_info = get_network_info(hass) or {}
|
||||
|
||||
healthy: bool | dict[str, str]
|
||||
if supervisor_info is not None and supervisor_info.get("healthy"):
|
||||
|
@ -57,6 +64,10 @@ async def system_health_info(hass: HomeAssistant) -> dict[str, Any]:
|
|||
"disk_used": f"{host_info.get('disk_used')} GB",
|
||||
"healthy": healthy,
|
||||
"supported": supported,
|
||||
"host_connectivity": network_info.get("host_internet"),
|
||||
"supervisor_connectivity": network_info.get("supervisor_internet"),
|
||||
"ntp_synchronized": host_info.get("dt_synchronized"),
|
||||
"virtualization": host_info.get("virtualization"),
|
||||
}
|
||||
|
||||
if info.get("hassos") is not None:
|
||||
|
|
|
@ -308,3 +308,13 @@ def all_setup_requests(
|
|||
},
|
||||
},
|
||||
)
|
||||
aioclient_mock.get(
|
||||
"http://127.0.0.1/network/info",
|
||||
json={
|
||||
"result": "ok",
|
||||
"data": {
|
||||
"host_internet": True,
|
||||
"supervisor_internet": True,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
|
|
@ -180,6 +180,16 @@ def mock_all(aioclient_mock, request):
|
|||
},
|
||||
},
|
||||
)
|
||||
aioclient_mock.get(
|
||||
"http://127.0.0.1/network/info",
|
||||
json={
|
||||
"result": "ok",
|
||||
"data": {
|
||||
"host_internet": True,
|
||||
"supervisor_internet": True,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
|
@ -184,6 +184,16 @@ def mock_all(aioclient_mock, request):
|
|||
},
|
||||
},
|
||||
)
|
||||
aioclient_mock.get(
|
||||
"http://127.0.0.1/network/info",
|
||||
json={
|
||||
"result": "ok",
|
||||
"data": {
|
||||
"host_internet": True,
|
||||
"supervisor_internet": True,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
async def test_diagnostics(
|
||||
|
|
|
@ -237,6 +237,16 @@ def mock_all(aioclient_mock, request, os_info):
|
|||
},
|
||||
},
|
||||
)
|
||||
aioclient_mock.get(
|
||||
"http://127.0.0.1/network/info",
|
||||
json={
|
||||
"result": "ok",
|
||||
"data": {
|
||||
"host_internet": True,
|
||||
"supervisor_internet": True,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
async def test_setup_api_ping(
|
||||
|
@ -248,7 +258,7 @@ async def test_setup_api_ping(
|
|||
await hass.async_block_till_done()
|
||||
|
||||
assert result
|
||||
assert aioclient_mock.call_count == 19
|
||||
assert aioclient_mock.call_count == 20
|
||||
assert get_core_info(hass)["version_latest"] == "1.0.0"
|
||||
assert is_hassio(hass)
|
||||
|
||||
|
@ -293,7 +303,7 @@ async def test_setup_api_push_api_data(
|
|||
await hass.async_block_till_done()
|
||||
|
||||
assert result
|
||||
assert aioclient_mock.call_count == 19
|
||||
assert aioclient_mock.call_count == 20
|
||||
assert not aioclient_mock.mock_calls[1][2]["ssl"]
|
||||
assert aioclient_mock.mock_calls[1][2]["port"] == 9999
|
||||
assert "watchdog" not in aioclient_mock.mock_calls[1][2]
|
||||
|
@ -312,7 +322,7 @@ async def test_setup_api_push_api_data_server_host(
|
|||
await hass.async_block_till_done()
|
||||
|
||||
assert result
|
||||
assert aioclient_mock.call_count == 19
|
||||
assert aioclient_mock.call_count == 20
|
||||
assert not aioclient_mock.mock_calls[1][2]["ssl"]
|
||||
assert aioclient_mock.mock_calls[1][2]["port"] == 9999
|
||||
assert not aioclient_mock.mock_calls[1][2]["watchdog"]
|
||||
|
@ -329,7 +339,7 @@ async def test_setup_api_push_api_data_default(
|
|||
await hass.async_block_till_done()
|
||||
|
||||
assert result
|
||||
assert aioclient_mock.call_count == 19
|
||||
assert aioclient_mock.call_count == 20
|
||||
assert not aioclient_mock.mock_calls[1][2]["ssl"]
|
||||
assert aioclient_mock.mock_calls[1][2]["port"] == 8123
|
||||
refresh_token = aioclient_mock.mock_calls[1][2]["refresh_token"]
|
||||
|
@ -409,7 +419,7 @@ async def test_setup_api_existing_hassio_user(
|
|||
await hass.async_block_till_done()
|
||||
|
||||
assert result
|
||||
assert aioclient_mock.call_count == 19
|
||||
assert aioclient_mock.call_count == 20
|
||||
assert not aioclient_mock.mock_calls[1][2]["ssl"]
|
||||
assert aioclient_mock.mock_calls[1][2]["port"] == 8123
|
||||
assert aioclient_mock.mock_calls[1][2]["refresh_token"] == token.token
|
||||
|
@ -426,7 +436,7 @@ async def test_setup_core_push_timezone(
|
|||
await hass.async_block_till_done()
|
||||
|
||||
assert result
|
||||
assert aioclient_mock.call_count == 19
|
||||
assert aioclient_mock.call_count == 20
|
||||
assert aioclient_mock.mock_calls[2][2]["timezone"] == "testzone"
|
||||
|
||||
with patch("homeassistant.util.dt.set_default_time_zone"):
|
||||
|
@ -447,7 +457,7 @@ async def test_setup_hassio_no_additional_data(
|
|||
await hass.async_block_till_done()
|
||||
|
||||
assert result
|
||||
assert aioclient_mock.call_count == 19
|
||||
assert aioclient_mock.call_count == 20
|
||||
assert aioclient_mock.mock_calls[-1][3]["Authorization"] == "Bearer 123456"
|
||||
|
||||
|
||||
|
@ -535,14 +545,14 @@ async def test_service_calls(
|
|||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert aioclient_mock.call_count == 23
|
||||
assert aioclient_mock.call_count == 24
|
||||
assert aioclient_mock.mock_calls[-1][2] == "test"
|
||||
|
||||
await hass.services.async_call("hassio", "host_shutdown", {})
|
||||
await hass.services.async_call("hassio", "host_reboot", {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert aioclient_mock.call_count == 25
|
||||
assert aioclient_mock.call_count == 26
|
||||
|
||||
await hass.services.async_call("hassio", "backup_full", {})
|
||||
await hass.services.async_call(
|
||||
|
@ -557,7 +567,7 @@ async def test_service_calls(
|
|||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert aioclient_mock.call_count == 27
|
||||
assert aioclient_mock.call_count == 28
|
||||
assert aioclient_mock.mock_calls[-1][2] == {
|
||||
"name": "2021-11-13 03:48:00",
|
||||
"homeassistant": True,
|
||||
|
@ -582,7 +592,7 @@ async def test_service_calls(
|
|||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert aioclient_mock.call_count == 29
|
||||
assert aioclient_mock.call_count == 30
|
||||
assert aioclient_mock.mock_calls[-1][2] == {
|
||||
"addons": ["test"],
|
||||
"folders": ["ssl"],
|
||||
|
@ -601,7 +611,7 @@ async def test_service_calls(
|
|||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert aioclient_mock.call_count == 30
|
||||
assert aioclient_mock.call_count == 31
|
||||
assert aioclient_mock.mock_calls[-1][2] == {
|
||||
"name": "backup_name",
|
||||
"location": "backup_share",
|
||||
|
@ -617,7 +627,7 @@ async def test_service_calls(
|
|||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert aioclient_mock.call_count == 31
|
||||
assert aioclient_mock.call_count == 32
|
||||
assert aioclient_mock.mock_calls[-1][2] == {
|
||||
"name": "2021-11-13 03:48:00",
|
||||
"location": None,
|
||||
|
@ -636,7 +646,7 @@ async def test_service_calls(
|
|||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert aioclient_mock.call_count == 33
|
||||
assert aioclient_mock.call_count == 34
|
||||
assert aioclient_mock.mock_calls[-1][2] == {
|
||||
"name": "2021-11-13 11:48:00",
|
||||
"location": None,
|
||||
|
@ -1101,7 +1111,7 @@ async def test_setup_hardware_integration(
|
|||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
assert result
|
||||
assert aioclient_mock.call_count == 19
|
||||
assert aioclient_mock.call_count == 20
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
|
|
|
@ -202,6 +202,16 @@ def _install_default_mocks(aioclient_mock: AiohttpClientMocker):
|
|||
},
|
||||
},
|
||||
)
|
||||
aioclient_mock.get(
|
||||
"http://127.0.0.1/network/info",
|
||||
json={
|
||||
"result": "ok",
|
||||
"data": {
|
||||
"host_internet": True,
|
||||
"supervisor_internet": True,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
|
@ -43,6 +43,8 @@ async def test_hassio_system_health(
|
|||
"agent_version": "1337",
|
||||
"disk_total": "32.0",
|
||||
"disk_used": "30.0",
|
||||
"dt_synchronized": True,
|
||||
"virtualization": "qemu",
|
||||
}
|
||||
hass.data["hassio_os_info"] = {"board": "odroid-n2"}
|
||||
hass.data["hassio_supervisor_info"] = {
|
||||
|
@ -50,6 +52,10 @@ async def test_hassio_system_health(
|
|||
"supported": True,
|
||||
"addons": [{"name": "Awesome Addon", "version": "1.0.0"}],
|
||||
}
|
||||
hass.data["hassio_network_info"] = {
|
||||
"host_internet": True,
|
||||
"supervisor_internet": True,
|
||||
}
|
||||
|
||||
with patch.dict(os.environ, MOCK_ENVIRON):
|
||||
info = await get_system_health_info(hass, "hassio")
|
||||
|
@ -65,13 +71,17 @@ async def test_hassio_system_health(
|
|||
"disk_used": "30.0 GB",
|
||||
"docker_version": "19.0.3",
|
||||
"healthy": True,
|
||||
"host_connectivity": True,
|
||||
"supervisor_connectivity": True,
|
||||
"host_os": "Home Assistant OS 5.9",
|
||||
"installed_addons": "Awesome Addon (1.0.0)",
|
||||
"ntp_synchronized": True,
|
||||
"supervisor_api": "ok",
|
||||
"supervisor_version": "supervisor-2020.11.1",
|
||||
"supported": True,
|
||||
"update_channel": "stable",
|
||||
"version_api": "ok",
|
||||
"virtualization": "qemu",
|
||||
}
|
||||
|
||||
|
||||
|
@ -99,6 +109,7 @@ async def test_hassio_system_health_with_issues(
|
|||
"healthy": False,
|
||||
"supported": False,
|
||||
}
|
||||
hass.data["hassio_network_info"] = {}
|
||||
|
||||
with patch.dict(os.environ, MOCK_ENVIRON):
|
||||
info = await get_system_health_info(hass, "hassio")
|
||||
|
|
|
@ -189,6 +189,16 @@ def mock_all(aioclient_mock, request):
|
|||
},
|
||||
},
|
||||
)
|
||||
aioclient_mock.get(
|
||||
"http://127.0.0.1/network/info",
|
||||
json={
|
||||
"result": "ok",
|
||||
"data": {
|
||||
"host_internet": True,
|
||||
"supervisor_internet": True,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
|
@ -80,6 +80,16 @@ async def mock_supervisor_fixture(hass, aioclient_mock):
|
|||
},
|
||||
},
|
||||
)
|
||||
aioclient_mock.get(
|
||||
"http://127.0.0.1/network/info",
|
||||
json={
|
||||
"result": "ok",
|
||||
"data": {
|
||||
"host_internet": True,
|
||||
"supervisor_internet": True,
|
||||
},
|
||||
},
|
||||
)
|
||||
with (
|
||||
patch.dict(os.environ, {"SUPERVISOR": "127.0.0.1"}),
|
||||
patch(
|
||||
|
|
Loading…
Reference in New Issue