custom_components/bahmcloud_store/__init__.py hinzugefügt
This commit is contained in:
144
custom_components/bahmcloud_store/__init__.py
Normal file
144
custom_components/bahmcloud_store/__init__.py
Normal 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)
|
||||||
Reference in New Issue
Block a user