mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 09:17:53 +00:00
Handle ESPHome dashboard discovery (#85662)
This commit is contained in:
parent
1a4cac95a1
commit
82ec769ec5
@ -56,6 +56,7 @@ from homeassistant.helpers.service import async_set_service_schema
|
||||
from homeassistant.helpers.template import Template
|
||||
|
||||
from .bluetooth import async_connect_scanner
|
||||
from .dashboard import async_get_dashboard
|
||||
from .domain_data import DOMAIN, DomainData
|
||||
|
||||
# Import config flow so that it's added to the registry
|
||||
@ -352,6 +353,8 @@ def _async_setup_device_registry(
|
||||
configuration_url = None
|
||||
if device_info.webserver_port > 0:
|
||||
configuration_url = f"http://{entry.data['host']}:{device_info.webserver_port}"
|
||||
elif dashboard := async_get_dashboard(hass):
|
||||
configuration_url = f"homeassistant://hassio/ingress/{dashboard.addon_slug}"
|
||||
|
||||
manufacturer = "espressif"
|
||||
if device_info.manufacturer:
|
||||
|
@ -17,6 +17,7 @@ from aioesphomeapi import (
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components import dhcp, zeroconf
|
||||
from homeassistant.components.hassio.discovery import HassioServiceInfo
|
||||
from homeassistant.config_entries import ConfigEntry, ConfigFlow
|
||||
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PASSWORD, CONF_PORT
|
||||
from homeassistant.core import callback
|
||||
@ -24,6 +25,7 @@ from homeassistant.data_entry_flow import FlowResult
|
||||
from homeassistant.helpers.device_registry import format_mac
|
||||
|
||||
from . import CONF_NOISE_PSK, DOMAIN
|
||||
from .dashboard import async_set_dashboard_info
|
||||
|
||||
ERROR_REQUIRES_ENCRYPTION_KEY = "requires_encryption_key"
|
||||
ESPHOME_URL = "https://esphome.io/"
|
||||
@ -173,6 +175,16 @@ class EsphomeFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
# for configured devices.
|
||||
return self.async_abort(reason="already_configured")
|
||||
|
||||
async def async_step_hassio(self, discovery_info: HassioServiceInfo) -> FlowResult:
|
||||
"""Handle Supervisor service discovery."""
|
||||
async_set_dashboard_info(
|
||||
self.hass,
|
||||
discovery_info.slug,
|
||||
discovery_info.config["host"],
|
||||
discovery_info.config["port"],
|
||||
)
|
||||
return self.async_abort(reason="service_received")
|
||||
|
||||
@callback
|
||||
def _async_get_entry(self) -> FlowResult:
|
||||
config_data = {
|
||||
|
28
homeassistant/components/esphome/dashboard.py
Normal file
28
homeassistant/components/esphome/dashboard.py
Normal file
@ -0,0 +1,28 @@
|
||||
"""Files to interact with a the ESPHome dashboard."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
|
||||
KEY_DASHBOARD = "esphome_dashboard"
|
||||
|
||||
|
||||
@callback
|
||||
def async_get_dashboard(hass: HomeAssistant) -> ESPHomeDashboard | None:
|
||||
"""Get an instance of the dashboard if set."""
|
||||
return hass.data.get(KEY_DASHBOARD)
|
||||
|
||||
|
||||
def async_set_dashboard_info(
|
||||
hass: HomeAssistant, addon_slug: str, _host: str, _port: int
|
||||
) -> None:
|
||||
"""Set the dashboard info."""
|
||||
hass.data[KEY_DASHBOARD] = ESPHomeDashboard(addon_slug)
|
||||
|
||||
|
||||
@dataclass
|
||||
class ESPHomeDashboard:
|
||||
"""Class to interact with the ESPHome dashboard."""
|
||||
|
||||
addon_slug: str
|
@ -4,7 +4,8 @@
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
|
||||
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
|
||||
"mdns_missing_mac": "Missing MAC address in MDNS properties."
|
||||
"mdns_missing_mac": "Missing MAC address in MDNS properties.",
|
||||
"service_received": "Service received"
|
||||
},
|
||||
"error": {
|
||||
"resolve_error": "Can't resolve address of the ESP. If this error persists, please set a static IP address",
|
||||
|
@ -11,9 +11,15 @@ from aioesphomeapi import (
|
||||
)
|
||||
import pytest
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant import config_entries, data_entry_flow
|
||||
from homeassistant.components import dhcp, zeroconf
|
||||
from homeassistant.components.esphome import CONF_NOISE_PSK, DOMAIN, DomainData
|
||||
from homeassistant.components.esphome import (
|
||||
CONF_NOISE_PSK,
|
||||
DOMAIN,
|
||||
DomainData,
|
||||
dashboard,
|
||||
)
|
||||
from homeassistant.components.hassio import HassioServiceInfo
|
||||
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
|
||||
@ -620,3 +626,26 @@ async def test_discovery_dhcp_no_changes(hass, mock_client):
|
||||
assert result["reason"] == "already_configured"
|
||||
|
||||
assert entry.data[CONF_HOST] == "192.168.43.183"
|
||||
|
||||
|
||||
async def test_discovery_hassio(hass):
|
||||
"""Test dashboard discovery."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
"esphome",
|
||||
data=HassioServiceInfo(
|
||||
config={
|
||||
"host": "mock-esphome",
|
||||
"port": 6052,
|
||||
},
|
||||
name="ESPHome",
|
||||
slug="mock-slug",
|
||||
),
|
||||
context={"source": config_entries.SOURCE_HASSIO},
|
||||
)
|
||||
assert result
|
||||
assert result["type"] == data_entry_flow.FlowResultType.ABORT
|
||||
assert result["reason"] == "service_received"
|
||||
|
||||
dash = dashboard.async_get_dashboard(hass)
|
||||
assert dash is not None
|
||||
assert dash.addon_slug == "mock-slug"
|
||||
|
Loading…
x
Reference in New Issue
Block a user