Introduce HassioServiceInfo (#60844)

Co-authored-by: epenet <epenet@users.noreply.github.com>
This commit is contained in:
epenet 2021-12-02 20:17:54 +01:00 committed by GitHub
parent e641214c60
commit 0723b1c539
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 64 additions and 1 deletions

View File

@ -1,6 +1,11 @@
"""Implement the services discovery feature from Hass.io for Add-ons."""
from __future__ import annotations
import asyncio
from collections.abc import Mapping
from dataclasses import dataclass
import logging
from typing import Any
from aiohttp import web
from aiohttp.web_exceptions import HTTPServiceUnavailable
@ -9,6 +14,8 @@ from homeassistant import config_entries
from homeassistant.components.http import HomeAssistantView
from homeassistant.const import ATTR_NAME, ATTR_SERVICE, EVENT_HOMEASSISTANT_START
from homeassistant.core import HomeAssistant, callback
from homeassistant.data_entry_flow import BaseServiceInfo
from homeassistant.helpers.frame import report
from .const import ATTR_ADDON, ATTR_CONFIG, ATTR_DISCOVERY, ATTR_UUID
from .handler import HassioAPIError
@ -16,6 +23,32 @@ from .handler import HassioAPIError
_LOGGER = logging.getLogger(__name__)
@dataclass
class HassioServiceInfo(BaseServiceInfo):
"""Prepared info from hassio entries."""
config: Mapping[str, Any]
# Used to prevent log flooding. To be removed in 2022.6
_warning_logged: bool = False
def __getitem__(self, name: str) -> Any:
"""
Allow property access by name for compatibility reason.
Deprecated, and will be removed in version 2022.6.
"""
if not self._warning_logged:
report(
f"accessed discovery_info['{name}'] instead of discovery_info.config['{name}']; this will fail in version 2022.6",
exclude_integrations={"hassio"},
error_if_core=False,
level=logging.DEBUG,
)
self._warning_logged = True
return self.config[name]
@callback
def async_setup_discovery_view(hass: HomeAssistant, hassio):
"""Discovery setup."""

View File

@ -6,6 +6,7 @@ from unittest.mock import patch
from homeassistant import config_entries, data_entry_flow, setup
from homeassistant.components.almond import config_flow
from homeassistant.components.almond.const import DOMAIN
from homeassistant.components.hassio.discovery import HassioServiceInfo
from homeassistant.const import CONF_CLIENT_ID, CONF_CLIENT_SECRET
from homeassistant.helpers import config_entry_oauth2_flow
@ -51,7 +52,9 @@ async def test_hassio(hass):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_HASSIO},
data={"addon": "Almond add-on", "host": "almond-addon", "port": "1234"},
data=HassioServiceInfo(
config={"addon": "Almond add-on", "host": "almond-addon", "port": "1234"}
),
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM

View File

@ -2,6 +2,7 @@
from http import HTTPStatus
from unittest.mock import Mock, patch
from homeassistant.components.hassio.discovery import HassioServiceInfo
from homeassistant.components.hassio.handler import HassioAPIError
from homeassistant.const import EVENT_HOMEASSISTANT_START
from homeassistant.setup import async_setup_component
@ -168,3 +169,29 @@ async def test_hassio_discovery_webhook(hass, aioclient_mock, hassio_client):
"addon": "Mosquitto Test",
}
)
async def test_service_info_compatibility(hass, caplog):
"""Test compatibility with old-style dict.
To be removed in 2022.6
"""
discovery_info = HassioServiceInfo(
config={
"broker": "mock-broker",
"port": 1883,
"username": "mock-user",
"password": "mock-pass",
"protocol": "3.1.1",
"addon": "Mosquitto Test",
}
)
# Ensure first call get logged
assert discovery_info["broker"] == "mock-broker"
assert "Detected code that accessed discovery_info['broker']" in caplog.text
# Ensure second call doesn't get logged
caplog.clear()
assert discovery_info["broker"] == "mock-broker"
assert "Detected code that accessed discovery_info['broker']" not in caplog.text