custom_components/bahmcloud_store/__init__.py hinzugefügt

This commit is contained in:
2026-01-14 17:09:44 +00:00
parent 8270714f29
commit 56021cd9fe

View File

@@ -0,0 +1,144 @@
from __future__ import annotations
import logging
from datetime import timedelta
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.components import frontend
from homeassistant.components.http import HomeAssistantView
from .store import BahmcloudStore, StoreConfig, StoreError
_LOGGER = logging.getLogger(__name__)
DOMAIN = "bahmcloud_store"
CONF_STORE_URL = "store_url"
CONF_AUTO_UPDATE = "auto_update"
CONF_CHECK_INTERVAL_MIN = "check_interval_minutes"
DEFAULT_STORE_URL = "https://git.bahmcloud.de/bahmcloud/ha_store/raw/branch/main/store.json"
DEFAULT_AUTO_UPDATE = True
DEFAULT_CHECK_INTERVAL_MIN = 60
async def async_setup(hass: HomeAssistant, config: dict) -> bool:
# Minimaler YAML-Config-Block (damit es ohne Config Flow sofort läuft)
# Du kannst das später auf Config Flow umbauen, wenn du willst.
cfg = config.get(DOMAIN, {})
store_url = cfg.get(CONF_STORE_URL, DEFAULT_STORE_URL)
auto_update = cfg.get(CONF_AUTO_UPDATE, DEFAULT_AUTO_UPDATE)
interval_min = int(cfg.get(CONF_CHECK_INTERVAL_MIN, DEFAULT_CHECK_INTERVAL_MIN))
store = BahmcloudStore(
hass,
StoreConfig(
store_url=store_url,
auto_update=auto_update,
check_interval=timedelta(minutes=interval_min),
),
)
hass.data[DOMAIN] = store
# Panel in der Seitenleiste registrieren (wie HACS-Icon)
frontend.async_register_built_in_panel(
hass,
component_name=DOMAIN,
sidebar_title="Bahmcloud Store",
sidebar_icon="mdi:store",
frontend_url_path="bahmcloud-store",
config={},
require_admin=True,
)
# HTTP Views (UI + API)
hass.http.register_view(BahmcloudStoreUI(store))
hass.http.register_view(BahmcloudStoreAPI(store))
# Services
async def svc_install(call: ServiceCall) -> None:
package_id = call.data["package_id"]
await store.install(package_id)
async def svc_update(call: ServiceCall) -> None:
package_id = call.data["package_id"]
await store.update(package_id)
async def svc_update_all(call: ServiceCall) -> None:
await store.update_all()
hass.services.async_register(DOMAIN, "install", svc_install)
hass.services.async_register(DOMAIN, "update", svc_update)
hass.services.async_register(DOMAIN, "update_all", svc_update_all)
# Initial load
try:
await store.refresh()
except StoreError as e:
_LOGGER.error("Store refresh failed: %s", e)
# Periodische Checks + optional Auto-Update
async def periodic(_now) -> None:
try:
await store.refresh()
if store.config.auto_update:
await store.update_all()
except StoreError as e:
_LOGGER.warning("Periodic store check failed: %s", e)
async_track_time_interval(hass, periodic, timedelta(minutes=interval_min))
return True
class BahmcloudStoreUI(HomeAssistantView):
"""Serves the minimal UI page."""
requires_auth = True
name = "bahmcloud_store_ui"
url = "/api/bahmcloud_store/ui"
def __init__(self, store: BahmcloudStore) -> None:
self._store = store
async def get(self, request):
# serve index.html from package folder
content = self._store.load_panel_file("index.html")
return self.json({"html": content})
class BahmcloudStoreAPI(HomeAssistantView):
"""Simple JSON API for the panel JS."""
requires_auth = True
name = "bahmcloud_store_api"
url = "/api/bahmcloud_store"
def __init__(self, store: BahmcloudStore) -> None:
self._store = store
async def get(self, request):
# /api/bahmcloud_store?op=list
op = request.query.get("op", "list")
if op == "list":
await self._store.refresh()
return self.json(self._store.as_dict())
return self.json({"error": "unknown op"}, status_code=400)
async def post(self, request):
data = await request.json()
op = data.get("op")
if op in ("install", "update"):
package_id = data.get("package_id")
if not package_id:
return self.json({"error": "package_id missing"}, status_code=400)
if op == "install":
await self._store.install(package_id)
else:
await self._store.update(package_id)
return self.json({"ok": True})
if op == "update_all":
await self._store.update_all()
return self.json({"ok": True})
return self.json({"error": "unknown op"}, status_code=400)