Stellt Spotify-Musik via Spotify Connect als HTTP-MP3-Stream bereit, den das Busch-Jäger Unterputz-Internetradio direkt abspielen kann. Komponenten: - ha-addon/: Home Assistant Add-on (librespot + ffmpeg + Icecast2) - custom_components/: Optionale HA Integration mit Media-Player-Entity - README.md: Vollständige Installations- und Konfigurationsanleitung - example-config.yaml: Kommentierte Beispielkonfiguration Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
110 lines
3.3 KiB
Python
110 lines
3.3 KiB
Python
"""Config Flow für die Busch-Radio Spotify Bridge Integration.
|
|
|
|
Führt den Nutzer durch die Einrichtung in der HA-Oberfläche.
|
|
Fragt nach:
|
|
- Hostname/IP des HA-Hosts (normalerweise 'localhost' wenn Add-on läuft)
|
|
- Port (Standard: 8000)
|
|
- Stream-Mount-Pfad (Standard: /stream.mp3)
|
|
- Icecast Admin-Passwort (identisch mit 'icecast_password' in der Add-on Konfig)
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
import aiohttp
|
|
import voluptuous as vol
|
|
from homeassistant import config_entries
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
|
|
|
from . import CONF_HOST, CONF_MOUNT, CONF_PASSWORD, CONF_PORT, DOMAIN
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
DEFAULT_HOST = "localhost"
|
|
DEFAULT_PORT = 8000
|
|
DEFAULT_MOUNT = "/stream.mp3"
|
|
DEFAULT_PASSWORD = "busch-radio-geheim"
|
|
|
|
|
|
async def _test_icecast_connection(
|
|
hass: HomeAssistant, host: str, port: int, password: str
|
|
) -> str | None:
|
|
"""Verbindung zu Icecast testen.
|
|
|
|
Gibt None zurück wenn alles ok, sonst einen Fehlercode.
|
|
"""
|
|
session = async_get_clientsession(hass)
|
|
url = f"http://{host}:{port}/admin/stats"
|
|
auth = aiohttp.BasicAuth("admin", password)
|
|
|
|
try:
|
|
async with session.get(
|
|
url,
|
|
auth=auth,
|
|
timeout=aiohttp.ClientTimeout(total=5),
|
|
) as resp:
|
|
if resp.status == 200:
|
|
return None
|
|
if resp.status == 401:
|
|
return "invalid_auth"
|
|
return "cannot_connect"
|
|
except aiohttp.ClientConnectorError:
|
|
return "cannot_connect"
|
|
except Exception:
|
|
return "unknown"
|
|
|
|
|
|
class BuschRadioSpotifyConfigFlow(
|
|
config_entries.ConfigFlow, domain=DOMAIN
|
|
):
|
|
"""Config Flow für Busch-Radio Spotify Bridge."""
|
|
|
|
VERSION = 1
|
|
|
|
async def async_step_user(
|
|
self, user_input: dict | None = None
|
|
) -> config_entries.FlowResult:
|
|
"""Ersten Einrichtungsschritt anzeigen."""
|
|
errors: dict[str, str] = {}
|
|
|
|
if user_input is not None:
|
|
error = await _test_icecast_connection(
|
|
self.hass,
|
|
user_input[CONF_HOST],
|
|
user_input[CONF_PORT],
|
|
user_input[CONF_PASSWORD],
|
|
)
|
|
|
|
if error is None:
|
|
# Doppelte Einrichtung verhindern
|
|
await self.async_set_unique_id(
|
|
f"{user_input[CONF_HOST]}:{user_input[CONF_PORT]}"
|
|
)
|
|
self._abort_if_unique_id_configured()
|
|
|
|
return self.async_create_entry(
|
|
title=f"Busch-Radio ({user_input[CONF_HOST]}:{user_input[CONF_PORT]})",
|
|
data=user_input,
|
|
)
|
|
else:
|
|
errors["base"] = error
|
|
|
|
schema = vol.Schema(
|
|
{
|
|
vol.Required(CONF_HOST, default=DEFAULT_HOST): str,
|
|
vol.Required(CONF_PORT, default=DEFAULT_PORT): vol.All(
|
|
vol.Coerce(int), vol.Range(min=1, max=65535)
|
|
),
|
|
vol.Required(CONF_MOUNT, default=DEFAULT_MOUNT): str,
|
|
vol.Required(CONF_PASSWORD, default=DEFAULT_PASSWORD): str,
|
|
}
|
|
)
|
|
|
|
return self.async_show_form(
|
|
step_id="user",
|
|
data_schema=schema,
|
|
errors=errors,
|
|
)
|