This commit is contained in:
2026-01-20 05:45:02 +00:00
parent 95dd8b9dc2
commit 4c2a104af7

View File

@@ -6,48 +6,53 @@ from datetime import timedelta
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.components.panel_custom import async_register_panel
from homeassistant.helpers.event import async_track_time_interval, async_call_later
from homeassistant.const import EVENT_HOMEASSISTANT_STARTED
from homeassistant.helpers.event import async_call_later, async_track_time_interval
from .core import BCSCore, BCSConfig, BCSError
from .config_flow import CONF_GITHUB_TOKEN
from .const import CONF_GITHUB_TOKEN, DEFAULT_STORE_URL, DOMAIN
from .core import BCSError, BCSConfig, BCSCore
_LOGGER = logging.getLogger(__name__)
DOMAIN = "bahmcloud_store"
# Fixed store index URL (not configurable by users)
DEFAULT_STORE_URL = "https://git.bahmcloud.de/bahmcloud/ha_store/raw/branch/main/store.yaml"
PLATFORMS: list[str] = ["update"]
DATA_ENTRY = f"{DOMAIN}_entry_runtime"
async def async_setup(hass: HomeAssistant, config: dict) -> bool:
"""Set up Bahmcloud Store.
YAML configuration is intentionally not supported.
Setup must happen via the UI (Config Flow).
We intentionally do NOT support YAML configuration.
This method is kept so we can log a helpful message if someone tries.
"""
if DOMAIN in (config or {}):
_LOGGER.warning(
"BCS does not support configuration.yaml setup. "
"Please remove 'bahmcloud_store:' from configuration.yaml and set up the integration via Settings -> Devices & Services."
"BCS YAML configuration is no longer supported. "
"Please remove 'bahmcloud_store:' from configuration.yaml and set up the integration via the UI."
)
return True
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Bahmcloud Store from a config entry."""
token = (entry.options.get(CONF_GITHUB_TOKEN) or "").strip() or None
"""Set up Bahmcloud Store from a config entry (UI setup)."""
# Only one instance.
hass.data.setdefault(DOMAIN, {})
core = BCSCore(hass, BCSConfig(store_url=DEFAULT_STORE_URL, github_token=token))
hass.data[DOMAIN] = core
github_token = (entry.options.get(CONF_GITHUB_TOKEN) or "").strip() or None
core = BCSCore(
hass,
BCSConfig(
store_url=DEFAULT_STORE_URL,
github_token=github_token,
),
)
hass.data[DOMAIN][entry.entry_id] = core
# Keep a convenient shortcut for platforms that previously used hass.data[DOMAIN] directly.
hass.data[DOMAIN]["_core"] = core
await core.async_initialize()
# Register HTTP views + static assets
# HTTP views + panel (registered once per entry; we only allow one entry).
from .views import (
StaticAssetsView,
BCSApiView,
@@ -78,7 +83,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
hass.http.register_view(BCSRestoreView(core))
hass.http.register_view(BCSRestartView(core))
# Sidebar panel
await async_register_panel(
hass,
frontend_url_path="bahmcloud-store",
@@ -91,16 +95,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
config={},
)
# Forward platform setup (Update entities)
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
async def _do_startup_refresh(_now=None) -> None:
try:
await core.full_refresh(source="startup")
except BCSError as e:
_LOGGER.error("Initial refresh failed: %s", e)
# Do not block HA startup: schedule refresh after HA started.
# Do not block startup; refresh after HA is up.
def _on_ha_started(_event) -> None:
async_call_later(hass, 30, _do_startup_refresh)
@@ -115,30 +116,18 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
_LOGGER.exception("Unexpected error during periodic refresh: %s", e)
interval_seconds = int(getattr(core, "refresh_seconds", 300) or 300)
unsub = async_track_time_interval(hass, periodic, timedelta(seconds=interval_seconds))
async_track_time_interval(hass, periodic, timedelta(seconds=interval_seconds))
# Store unload callbacks safely
runtimes = hass.data.setdefault(DATA_ENTRY, {})
runtimes[entry.entry_id] = {"unsub_interval": unsub}
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
try:
runtimes = hass.data.get(DATA_ENTRY, {}) or {}
rt = runtimes.pop(entry.entry_id, {}) if isinstance(runtimes, dict) else {}
unsub = rt.get("unsub_interval")
if callable(unsub):
unsub()
except Exception:
pass
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if unload_ok:
hass.data.pop(DOMAIN, None)
try:
hass.data.get(DOMAIN, {}).pop(entry.entry_id, None)
except Exception:
pass
return unload_ok
async def async_reload_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
await hass.config_entries.async_reload(entry.entry_id)