From e3c9d1b19bc07e42b4c59749bf764625ea0dfef1 Mon Sep 17 00:00:00 2001 From: olaf Date: Sun, 8 Jun 2025 12:03:13 +0000 Subject: [PATCH] Finetuning prove of concept for the dashboard --- dashboard/callbacks/overview_callbacks.py | 45 ++++++++++++++++++----- dashboard/components/sidebar.py | 1 + dashboard/pages/clients.py | 12 ++++++ server/requirements.txt | 1 + 4 files changed, 49 insertions(+), 10 deletions(-) create mode 100644 dashboard/pages/clients.py diff --git a/dashboard/callbacks/overview_callbacks.py b/dashboard/callbacks/overview_callbacks.py index 513d183..cf09a40 100644 --- a/dashboard/callbacks/overview_callbacks.py +++ b/dashboard/callbacks/overview_callbacks.py @@ -11,8 +11,11 @@ from utils.mqtt_client import publish, start_loop from config import ENV import dash_bootstrap_components as dbc import os +import time +import pytz +from datetime import datetime -API_BASE_URL = os.getenv("API_BASE_URL", "http://infoscreen-api:8000") +API_BASE_URL = os.getenv("API_BASE_URL", "http://192.168.43.100") mqtt_thread_started = False SCREENSHOT_DIR = "received-screenshots" @@ -25,12 +28,13 @@ def ensure_mqtt_running(): mqtt_thread_started = True def get_latest_screenshot(client_uuid): + cache_buster = int(time.time()) # aktuelle Unix-Zeit in Sekunden # TODO: Hier genau im Produkitv-Modus die IPs testen! # Wenn API_BASE_URL auf "http" beginnt, absolute URL verwenden (z.B. im lokalen Dev) if API_BASE_URL.startswith("http"): - return f"{API_BASE_URL}/screenshots/{client_uuid}" + return f"{API_BASE_URL}/screenshots/{client_uuid}?t={cache_buster}" # Sonst relative URL (nginx-Proxy übernimmt das Routing) - return f"/screenshots/{client_uuid}" + return f"/screenshots/{client_uuid}?t={cache_buster}" def fetch_clients(): try: @@ -52,21 +56,42 @@ def update_clients(n): cards = [] for client in clients: uuid = client["uuid"] - # screenshot = get_latest_screenshot(uuid) screenshot = get_latest_screenshot(uuid) - # if screenshot[-3] != "jpg": - # screenshot += ".jpg" - print(f"UUID: {uuid}, Screenshot: {screenshot}") + last_alive_utc = client.get("last_alive") + if last_alive_utc: + try: + # Unterstützt sowohl "2024-06-08T12:34:56Z" als auch "2024-06-08T12:34:56" + if last_alive_utc.endswith("Z"): + dt_utc = datetime.strptime(last_alive_utc, "%Y-%m-%dT%H:%M:%SZ") + else: + dt_utc = datetime.strptime(last_alive_utc, "%Y-%m-%dT%H:%M:%S") + dt_utc = dt_utc.replace(tzinfo=pytz.UTC) + # Lokale Zeitzone fest angeben, z.B. Europe/Berlin + local_tz = pytz.timezone("Europe/Berlin") + dt_local = dt_utc.astimezone(local_tz) + last_alive_str = dt_local.strftime("%d.%m.%Y %H:%M:%S") + except Exception: + last_alive_str = last_alive_utc + else: + last_alive_str = "-" + card = dbc.Card( [ dbc.CardHeader(client["location"]), dbc.CardBody([ html.Img( src=screenshot, - style={"width": "160px", "height": "90px", "object-fit": "cover"}, + style={ + "width": "240px", + "height": "135px", + "object-fit": "cover", + "display": "block", + "margin-left": "auto", + "margin-right": "auto" + }, ), - html.P(f"IP: {client["ip_address"] or '-'}", className="card-text"), - html.P(f"Letzte Aktivität: {client["last_alive"] or '-'}", className="card-text"), + html.P(f"IP: {client['ip_address'] or '-'}", className="card-text"), + html.P(f"Letzte Aktivität: {last_alive_str}", className="card-text"), dbc.ButtonGroup([ dbc.Button("Reload Page", color="primary", id={"type": "btn-reload", "index": uuid}, n_clicks=0), dbc.Button("Restart Client", color="danger", id={"type": "btn-restart", "index": uuid}, n_clicks=0), diff --git a/dashboard/components/sidebar.py b/dashboard/components/sidebar.py index 03c129a..dce89ea 100644 --- a/dashboard/components/sidebar.py +++ b/dashboard/components/sidebar.py @@ -14,6 +14,7 @@ def Sidebar(collapsed: bool = False) -> List[Any]: nav_items = [ {"label": "Übersicht", "href": "/overview", "icon": "mdi:view-dashboard"}, {"label": "Termine", "href": "/appointments","icon": "mdi:calendar"}, + {"label": "Bildschirme", "href": "/clients", "icon": "mdi:monitor"}, {"label": "Einstellungen","href": "/settings", "icon": "mdi:cog"}, {"label": "Benutzer", "href": "/users", "icon": "mdi:account"}, ] diff --git a/dashboard/pages/clients.py b/dashboard/pages/clients.py new file mode 100644 index 0000000..b8dcc65 --- /dev/null +++ b/dashboard/pages/clients.py @@ -0,0 +1,12 @@ +# dashboard/pages/clients.py +from dash import html, dcc +import dash + +dash.register_page(__name__, path="/clients", name="Bildschirme") + +layout = html.Div( + className="clients-page", + children=[ + html.H3("Bildschirme"), + ] +) \ No newline at end of file diff --git a/server/requirements.txt b/server/requirements.txt index 578c4ef..99ee5db 100644 --- a/server/requirements.txt +++ b/server/requirements.txt @@ -1,3 +1,4 @@ +alembic>=1.16.1 bcrypt>=4.3.0 paho-mqtt>=2.1.0 PyMySQL>=1.1.1