from __future__ import annotations from datetime import datetime, timezone import os import platform from flask import Blueprint, jsonify, request from app.core_settings import get_settings from app.services.capabilities import build_capabilities from app.services.catalog import get_catalog from app.services.kiosk_settings import get_kiosk_settings_service from app.services.auth import get_auth_service from app.services.influx_http import InfluxHTTPService from app.utils.serialization import to_plain dashboard_blueprint = Blueprint("dashboard", __name__) _APP_STARTED_AT = datetime.now(timezone.utc) @dashboard_blueprint.get("/dashboard/config") def dashboard_config(): settings = get_settings() catalog = get_catalog() capabilities = build_capabilities(catalog) payload = { "app": { "name": settings.app_name, "version": settings.version, "site_name": settings.site_name, "timezone": settings.timezone, "installed_power_kwp": settings.installed_power_kwp, }, "defaults": { "realtime_range": settings.realtime["history_default_range"], "analytics_range": settings.analytics["default_range"], "analytics_bucket": settings.analytics["default_bucket"], "tab": settings.frontend_defaults["tab"], "theme": settings.frontend_defaults["theme"], "language": settings.frontend_defaults["language"], }, "auth": { "enabled": settings.auth["enabled"], }, "i18n": settings.i18n, "capabilities": capabilities, "visible_entities": [ { "metric_id": metric.id, "label": metric.label, "entity_id": metric.entity_id, "measurement": metric.measurement, "unit": metric.unit, "kind": metric.kind, } for metric in catalog.visible_entities() ], } return jsonify(to_plain(payload)) @dashboard_blueprint.get("/dashboard/kiosk-settings") def dashboard_kiosk_settings(): requested_mode = request.args.get("mode") or ("public" if request.args.get("publicKiosk") == "1" else "private") try: payload = get_kiosk_settings_service().get(requested_mode) return jsonify(to_plain(payload)) except ValueError as exc: return jsonify({"detail": str(exc)}), 400 @dashboard_blueprint.put("/dashboard/kiosk-settings") def update_dashboard_kiosk_settings(): payload = request.get_json(silent=True) or {} mode = payload.get("mode", "private") auth_service = get_auth_service() try: auth_service.require_admin() updated = get_kiosk_settings_service().update_from_session(mode, payload) return jsonify(to_plain(updated)) except PermissionError as exc: return jsonify({"detail": str(exc)}), 403 except ValueError as exc: return jsonify({"detail": str(exc)}), 400 @dashboard_blueprint.get("/dashboard/diagnostics") def dashboard_diagnostics(): settings = get_settings() influx_diagnostics = InfluxHTTPService(settings).diagnose() now = datetime.now(timezone.utc) payload = { "app": { "name": settings.app_name, "version": settings.version, "debug": settings.debug, "timezone": settings.timezone, "site_name": settings.site_name, "installed_power_kwp": settings.installed_power_kwp, "auth_enabled": settings.auth["enabled"], "started_at": _APP_STARTED_AT.isoformat(), "uptime_seconds": max(int((now - _APP_STARTED_AT).total_seconds()), 0), "python_version": platform.python_version(), "pid": os.getpid(), }, "api": { "status": "ok", "prefix": settings.api_prefix, "cors_origins_count": len(settings.cors_origins), }, "influx": influx_diagnostics, "storage": { "sqlite_path": settings.storage["sqlite_path"], "historical_import_enabled": settings.history["enabled"], "auto_sync_enabled": settings.history["auto_sync_enabled"], "default_chunk_days": settings.history["default_chunk_days"], }, } return jsonify(to_plain(payload))