Add more system information from Supervisor (#35560)
parent
306f15723d
commit
eddb5c6c3f
|
@ -41,7 +41,8 @@ CONFIG_SCHEMA = vol.Schema(
|
|||
)
|
||||
|
||||
|
||||
DATA_HOMEASSISTANT_VERSION = "hassio_hass_version"
|
||||
DATA_INFO = "hassio_info"
|
||||
DATA_HOST_INFO = "hassio_host_info"
|
||||
HASSIO_UPDATE_INTERVAL = timedelta(minutes=55)
|
||||
|
||||
SERVICE_ADDON_START = "addon_start"
|
||||
|
@ -130,7 +131,29 @@ def get_homeassistant_version(hass):
|
|||
|
||||
Async friendly.
|
||||
"""
|
||||
return hass.data.get(DATA_HOMEASSISTANT_VERSION)
|
||||
if DATA_INFO not in hass.data:
|
||||
return None
|
||||
return hass.data[DATA_INFO].get("homeassistant")
|
||||
|
||||
|
||||
@callback
|
||||
@bind_hass
|
||||
def get_info(hass):
|
||||
"""Return generic information from Supervisor.
|
||||
|
||||
Async friendly.
|
||||
"""
|
||||
return hass.data.get(DATA_INFO)
|
||||
|
||||
|
||||
@callback
|
||||
@bind_hass
|
||||
def get_host_info(hass):
|
||||
"""Return generic host information.
|
||||
|
||||
Async friendly.
|
||||
"""
|
||||
return hass.data.get(DATA_HOST_INFO)
|
||||
|
||||
|
||||
@callback
|
||||
|
@ -247,20 +270,20 @@ async def async_setup(hass, config):
|
|||
DOMAIN, service, async_service_handler, schema=settings[1]
|
||||
)
|
||||
|
||||
async def update_homeassistant_version(now):
|
||||
"""Update last available Home Assistant version."""
|
||||
async def update_info_data(now):
|
||||
"""Update last available supervisor information."""
|
||||
try:
|
||||
data = await hassio.get_homeassistant_info()
|
||||
hass.data[DATA_HOMEASSISTANT_VERSION] = data["last_version"]
|
||||
hass.data[DATA_INFO] = await hassio.get_info()
|
||||
hass.data[DATA_HOST_INFO] = await hassio.get_host_info()
|
||||
except HassioAPIError as err:
|
||||
_LOGGER.warning("Can't read last version: %s", err)
|
||||
|
||||
hass.helpers.event.async_track_point_in_utc_time(
|
||||
update_homeassistant_version, utcnow() + HASSIO_UPDATE_INTERVAL
|
||||
update_info_data, utcnow() + HASSIO_UPDATE_INTERVAL
|
||||
)
|
||||
|
||||
# Fetch last version
|
||||
await update_homeassistant_version(None)
|
||||
await update_info_data(None)
|
||||
|
||||
async def async_handle_core_service(call):
|
||||
"""Service handler for handling core services."""
|
||||
|
|
|
@ -68,12 +68,20 @@ class HassIO:
|
|||
return self.send_command("/supervisor/ping", method="get", timeout=15)
|
||||
|
||||
@_api_data
|
||||
def get_homeassistant_info(self):
|
||||
"""Return data for Home Assistant.
|
||||
def get_info(self):
|
||||
"""Return generic Supervisor information.
|
||||
|
||||
This method return a coroutine.
|
||||
"""
|
||||
return self.send_command("/homeassistant/info", method="get")
|
||||
return self.send_command("/info", method="get")
|
||||
|
||||
@_api_data
|
||||
def get_host_info(self):
|
||||
"""Return data for Host.
|
||||
|
||||
This method return a coroutine.
|
||||
"""
|
||||
return self.send_command("/host/info", method="get")
|
||||
|
||||
@_api_data
|
||||
def get_addon_info(self, addon):
|
||||
|
|
|
@ -14,6 +14,7 @@ from .typing import HomeAssistantType
|
|||
async def async_get_system_info(hass: HomeAssistantType) -> Dict:
|
||||
"""Return info about the system."""
|
||||
info_object = {
|
||||
"installation_type": "Unknown",
|
||||
"version": current_version,
|
||||
"dev": "dev" in current_version,
|
||||
"hassio": hass.components.hassio.is_hassio(),
|
||||
|
@ -33,4 +34,26 @@ async def async_get_system_info(hass: HomeAssistantType) -> Dict:
|
|||
elif platform.system() == "Linux":
|
||||
info_object["docker"] = os.path.isfile("/.dockerenv")
|
||||
|
||||
# Determine installation type on current data
|
||||
if info_object["docker"]:
|
||||
info_object["installation_type"] = "Home Assistant Core on Docker"
|
||||
elif is_virtual_env():
|
||||
info_object[
|
||||
"installation_type"
|
||||
] = "Home Assistant Core in a Python Virtual Environment"
|
||||
|
||||
# Enrich with Supervisor information
|
||||
if hass.components.hassio.is_hassio():
|
||||
info = hass.components.hassio.get_info()
|
||||
host = hass.components.hassio.get_host_info()
|
||||
|
||||
info_object["supervisor"] = info.get("supervisor")
|
||||
info_object["host_os"] = host.get("operating_system")
|
||||
info_object["chassis"] = host.get("chassis")
|
||||
|
||||
if info.get("hassos") is not None:
|
||||
info_object["installation_type"] = "Home Assistant"
|
||||
else:
|
||||
info_object["installation_type"] = "Home Assistant Supervised"
|
||||
|
||||
return info_object
|
||||
|
|
|
@ -19,7 +19,7 @@ def hassio_env():
|
|||
"homeassistant.components.hassio.HassIO.is_connected",
|
||||
return_value={"result": "ok", "data": {}},
|
||||
), patch.dict(os.environ, {"HASSIO_TOKEN": "123456"}), patch(
|
||||
"homeassistant.components.hassio.HassIO.get_homeassistant_info",
|
||||
"homeassistant.components.hassio.HassIO.get_info",
|
||||
Mock(side_effect=HassioAPIError()),
|
||||
):
|
||||
yield
|
||||
|
@ -35,8 +35,7 @@ def hassio_stubs(hassio_env, hass, hass_client, aioclient_mock):
|
|||
"homeassistant.components.hassio.HassIO.update_hass_timezone",
|
||||
return_value={"result": "ok"},
|
||||
), patch(
|
||||
"homeassistant.components.hassio.HassIO.get_homeassistant_info",
|
||||
side_effect=HassioAPIError(),
|
||||
"homeassistant.components.hassio.HassIO.get_info", side_effect=HassioAPIError(),
|
||||
):
|
||||
hass.state = CoreState.starting
|
||||
hass.loop.run_until_complete(async_setup_component(hass, "hassio", {}))
|
||||
|
|
|
@ -91,7 +91,7 @@ async def test_hassio_discovery_startup_done(hass, aioclient_mock, hassio_client
|
|||
"homeassistant.components.hassio.HassIO.update_hass_api",
|
||||
return_value={"result": "ok"},
|
||||
), patch(
|
||||
"homeassistant.components.hassio.HassIO.get_homeassistant_info",
|
||||
"homeassistant.components.hassio.HassIO.get_info",
|
||||
Mock(side_effect=HassioAPIError()),
|
||||
), patch(
|
||||
"homeassistant.components.mqtt.config_flow.FlowHandler.async_step_hassio",
|
||||
|
|
|
@ -30,26 +30,64 @@ async def test_api_ping_exeption(hassio_handler, aioclient_mock):
|
|||
assert aioclient_mock.call_count == 1
|
||||
|
||||
|
||||
async def test_api_homeassistant_info(hassio_handler, aioclient_mock):
|
||||
"""Test setup with API Home Assistant info."""
|
||||
async def test_api_info(hassio_handler, aioclient_mock):
|
||||
"""Test setup with API generic info."""
|
||||
aioclient_mock.get(
|
||||
"http://127.0.0.1/homeassistant/info",
|
||||
json={"result": "ok", "data": {"last_version": "10.0"}},
|
||||
"http://127.0.0.1/info",
|
||||
json={
|
||||
"result": "ok",
|
||||
"data": {"supervisor": "222", "homeassistant": "0.110.0", "hassos": None},
|
||||
},
|
||||
)
|
||||
|
||||
data = await hassio_handler.get_homeassistant_info()
|
||||
data = await hassio_handler.get_info()
|
||||
assert aioclient_mock.call_count == 1
|
||||
assert data["last_version"] == "10.0"
|
||||
assert data["hassos"] is None
|
||||
assert data["homeassistant"] == "0.110.0"
|
||||
assert data["supervisor"] == "222"
|
||||
|
||||
|
||||
async def test_api_homeassistant_info_error(hassio_handler, aioclient_mock):
|
||||
async def test_api_info_error(hassio_handler, aioclient_mock):
|
||||
"""Test setup with API Home Assistant info error."""
|
||||
aioclient_mock.get(
|
||||
"http://127.0.0.1/homeassistant/info", json={"result": "error", "message": None}
|
||||
"http://127.0.0.1/info", json={"result": "error", "message": None}
|
||||
)
|
||||
|
||||
with pytest.raises(HassioAPIError):
|
||||
await hassio_handler.get_homeassistant_info()
|
||||
await hassio_handler.get_info()
|
||||
|
||||
assert aioclient_mock.call_count == 1
|
||||
|
||||
|
||||
async def test_api_host_info(hassio_handler, aioclient_mock):
|
||||
"""Test setup with API Host info."""
|
||||
aioclient_mock.get(
|
||||
"http://127.0.0.1/host/info",
|
||||
json={
|
||||
"result": "ok",
|
||||
"data": {
|
||||
"chassis": "vm",
|
||||
"operating_system": "Debian GNU/Linux 10 (buster)",
|
||||
"kernel": "4.19.0-6-amd64",
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
data = await hassio_handler.get_host_info()
|
||||
assert aioclient_mock.call_count == 1
|
||||
assert data["chassis"] == "vm"
|
||||
assert data["kernel"] == "4.19.0-6-amd64"
|
||||
assert data["operating_system"] == "Debian GNU/Linux 10 (buster)"
|
||||
|
||||
|
||||
async def test_api_host_info_error(hassio_handler, aioclient_mock):
|
||||
"""Test setup with API Home Assistant info error."""
|
||||
aioclient_mock.get(
|
||||
"http://127.0.0.1/host/info", json={"result": "error", "message": None}
|
||||
)
|
||||
|
||||
with pytest.raises(HassioAPIError):
|
||||
await hassio_handler.get_host_info()
|
||||
|
||||
assert aioclient_mock.call_count == 1
|
||||
|
||||
|
|
|
@ -20,8 +20,25 @@ def mock_all(aioclient_mock):
|
|||
aioclient_mock.get("http://127.0.0.1/supervisor/ping", json={"result": "ok"})
|
||||
aioclient_mock.post("http://127.0.0.1/supervisor/options", json={"result": "ok"})
|
||||
aioclient_mock.get(
|
||||
"http://127.0.0.1/homeassistant/info",
|
||||
json={"result": "ok", "data": {"last_version": "10.0"}},
|
||||
"http://127.0.0.1/info",
|
||||
json={
|
||||
"result": "ok",
|
||||
"data": {"supervisor": "222", "homeassistant": "0.110.0", "hassos": None},
|
||||
},
|
||||
)
|
||||
aioclient_mock.get(
|
||||
"http://127.0.0.1/host/info",
|
||||
json={
|
||||
"result": "ok",
|
||||
"data": {
|
||||
"result": "ok",
|
||||
"data": {
|
||||
"chassis": "vm",
|
||||
"operating_system": "Debian GNU/Linux 10 (buster)",
|
||||
"kernel": "4.19.0-6-amd64",
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
aioclient_mock.get(
|
||||
"http://127.0.0.1/ingress/panels", json={"result": "ok", "data": {"panels": {}}}
|
||||
|
@ -34,8 +51,8 @@ async def test_setup_api_ping(hass, aioclient_mock):
|
|||
result = await async_setup_component(hass, "hassio", {})
|
||||
assert result
|
||||
|
||||
assert aioclient_mock.call_count == 5
|
||||
assert hass.components.hassio.get_homeassistant_version() == "10.0"
|
||||
assert aioclient_mock.call_count == 6
|
||||
assert hass.components.hassio.get_homeassistant_version() == "0.110.0"
|
||||
assert hass.components.hassio.is_hassio()
|
||||
|
||||
|
||||
|
@ -73,7 +90,7 @@ async def test_setup_api_push_api_data(hass, aioclient_mock):
|
|||
)
|
||||
assert result
|
||||
|
||||
assert aioclient_mock.call_count == 5
|
||||
assert aioclient_mock.call_count == 6
|
||||
assert not aioclient_mock.mock_calls[1][2]["ssl"]
|
||||
assert aioclient_mock.mock_calls[1][2]["port"] == 9999
|
||||
assert aioclient_mock.mock_calls[1][2]["watchdog"]
|
||||
|
@ -89,7 +106,7 @@ async def test_setup_api_push_api_data_server_host(hass, aioclient_mock):
|
|||
)
|
||||
assert result
|
||||
|
||||
assert aioclient_mock.call_count == 5
|
||||
assert aioclient_mock.call_count == 6
|
||||
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"]
|
||||
|
@ -101,7 +118,7 @@ async def test_setup_api_push_api_data_default(hass, aioclient_mock, hass_storag
|
|||
result = await async_setup_component(hass, "hassio", {"http": {}, "hassio": {}})
|
||||
assert result
|
||||
|
||||
assert aioclient_mock.call_count == 5
|
||||
assert aioclient_mock.call_count == 6
|
||||
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"]
|
||||
|
@ -148,7 +165,7 @@ async def test_setup_api_existing_hassio_user(hass, aioclient_mock, hass_storage
|
|||
result = await async_setup_component(hass, "hassio", {"http": {}, "hassio": {}})
|
||||
assert result
|
||||
|
||||
assert aioclient_mock.call_count == 5
|
||||
assert aioclient_mock.call_count == 6
|
||||
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
|
||||
|
@ -162,7 +179,7 @@ async def test_setup_core_push_timezone(hass, aioclient_mock):
|
|||
result = await async_setup_component(hass, "hassio", {"hassio": {}})
|
||||
assert result
|
||||
|
||||
assert aioclient_mock.call_count == 5
|
||||
assert aioclient_mock.call_count == 6
|
||||
assert aioclient_mock.mock_calls[2][2]["timezone"] == "testzone"
|
||||
|
||||
await hass.config.async_update(time_zone="America/New_York")
|
||||
|
@ -178,7 +195,7 @@ async def test_setup_hassio_no_additional_data(hass, aioclient_mock):
|
|||
result = await async_setup_component(hass, "hassio", {"hassio": {}})
|
||||
assert result
|
||||
|
||||
assert aioclient_mock.call_count == 5
|
||||
assert aioclient_mock.call_count == 6
|
||||
assert aioclient_mock.mock_calls[-1][3]["X-Hassio-Key"] == "123456"
|
||||
|
||||
|
||||
|
|
|
@ -154,7 +154,12 @@ async def test_new_version_shows_entity_after_hour_hassio(
|
|||
"""Test if binary sensor gets updated if new version is available / Hass.io."""
|
||||
mock_get_uuid.return_value = MOCK_HUUID
|
||||
mock_component(hass, "hassio")
|
||||
hass.data["hassio_hass_version"] = "999.0"
|
||||
hass.data["hassio_info"] = {"hassos": None, "homeassistant": "999.0"}
|
||||
hass.data["hassio_host"] = {
|
||||
"supervisor": "222",
|
||||
"chassis": "vm",
|
||||
"operating_system": "HassOS 4.6",
|
||||
}
|
||||
|
||||
assert await async_setup_component(hass, updater.DOMAIN, {updater.DOMAIN: {}})
|
||||
|
||||
|
|
Loading…
Reference in New Issue