This commit is contained in:
2026-05-02 20:54:53 +02:00
parent 638f4a7b75
commit 408da56450
14 changed files with 1271 additions and 1104 deletions

0
raspi/templates/base.html Normal file → Executable file
View File

141
raspi/templates/dashboard.html Normal file → Executable file
View File

@@ -1,28 +1,30 @@
{% extends "base.html" %}
{% block title %}{{ title }}{% endblock %}
{% block body %}
{# Root element carries config as data-attributes for dashboard.js #}
<div id="mirror-root"
data-poll-ms="{{ poll_ms }}"
data-sensors="{{ sensors_json | e }}">
<div class="mirror-layout">
{# ══════════════════════════════════
HEADER — clock + connection badge
══════════════════════════════════ #}
<header class="mirror-header glass">
<!-- ══ HEADER ══ -->
<header class="mirror-header card">
<span class="mirror-title">{{ title }}</span>
<div class="header-brand">
<div class="brand-icon">🪞</div>
<div>
<div class="brand-name">{{ title }}</div>
<div class="brand-sub">Arduino Wetterstation</div>
</div>
</div>
<div class="mirror-clock">
<div class="clock-time" id="clock-time">00:00:00</div>
<div class="clock-date" id="clock-date"></div>
</div>
<div class="conn-badge glass" id="conn-badge">
<div class="conn-badge card" id="conn-badge">
<div class="conn-dot" id="conn-dot"></div>
<span id="conn-text">Verbinde …</span>
</div>
@@ -30,108 +32,117 @@
</header>
{# ══════════════════════════════════
BODY — sensors / chart / log
══════════════════════════════════ #}
<!-- ══ BODY ══ -->
<main class="mirror-body">
{# ── Sensor tiles (one per configured sensor) ── #}
<!-- Sensor tiles -->
{% set icons = ['🌡️','💧','🌧️','📡','📊','⚡'] %}
{% for s in sensors %}
<div class="sensor-tile glass" id="sc-{{ loop.index0 }}">
<div class="sensor-tile card" id="sc-{{ loop.index0 }}">
<div class="sensor-tile-header">
<div class="sensor-icon">{{ icons[loop.index0 % icons|length] }}</div>
<div class="sensor-state-dot" id="sd-{{ loop.index0 }}"></div>
</div>
<div class="sensor-label">{{ s.name }}</div>
<div class="sensor-value" id="sv-{{ loop.index0 }}"></div>
<div class="sensor-threshold">
{%- if s.threshold_low is not none -%}
↓ {{ s.threshold_low }}{{ s.unit }}
{%- endif -%}
{%- if s.threshold_high is not none -%}
&nbsp; ↑ {{ s.threshold_high }}{{ s.unit }}
{%- endif -%}
<div class="sensor-value" id="sv-{{ loop.index0 }}"></div>
<div class="sensor-meta">
<div class="sensor-threshold" id="st-{{ loop.index0 }}">
{%- if s.threshold_low is not none -%}↓ {{ s.threshold_low }}{{ s.unit }}{%- endif -%}
{%- if s.threshold_high is not none and s.threshold_low is not none -%}&nbsp;&nbsp;{%- endif -%}
{%- if s.threshold_high is not none -%}↑ {{ s.threshold_high }}{{ s.unit }}{%- endif -%}
</div>
</div>
</div>
{% endfor %}
{# ── Stat row ── #}
<!-- Stat row -->
<div class="stat-row">
<div class="stat-card glass">
<div class="stat-label">Letzter Wert</div>
<div class="stat-value" id="stat-last"></div>
<div class="stat-sub" id="stat-ts"></div>
<div class="stat-card card">
<div class="stat-card-icon blue">📥</div>
<div class="stat-info">
<div class="stat-label">Letzter Wert</div>
<div class="stat-value" id="stat-last"></div>
<div class="stat-sub" id="stat-ts"></div>
</div>
</div>
<div class="stat-card glass">
<div class="stat-label">Zeilen gesamt</div>
<div class="stat-value" id="stat-total">0</div>
<div class="stat-sub">empfangen</div>
<div class="stat-card card">
<div class="stat-card-icon green">📊</div>
<div class="stat-info">
<div class="stat-label">Zeilen gesamt</div>
<div class="stat-value" id="stat-total">0</div>
<div class="stat-sub">empfangen</div>
</div>
</div>
<div class="stat-card glass">
<div class="stat-label">Fehler</div>
<div class="stat-value red" id="stat-errors">0</div>
<div class="stat-sub">Verbindungsabbrüche</div>
<div class="stat-card card">
<div class="stat-card-icon red">⚠️</div>
<div class="stat-info">
<div class="stat-label">Fehler</div>
<div class="stat-value red" id="stat-errors">0</div>
<div class="stat-sub">Verbindungsabbrüche</div>
</div>
</div>
<div class="stat-card glass">
<div class="stat-label">Verbindung</div>
<div class="stat-value" id="stat-port" style="font-size:1rem;padding-top:.35rem"></div>
<div class="stat-sub" id="stat-baud"></div>
<div class="stat-card card">
<div class="stat-card-icon teal">🔌</div>
<div class="stat-info">
<div class="stat-label">Verbindung</div>
<div class="stat-value" id="stat-port" style="font-size:.9rem"></div>
<div class="stat-sub" id="stat-baud"></div>
</div>
</div>
</div>{# /stat-row #}
</div><!-- /stat-row -->
{# ── Chart panel ── #}
<div class="chart-panel glass">
<div class="panel-label">Verlauf — Kanal 1 (letzte 80 Messpunkte)</div>
<!-- Chart -->
<div class="chart-panel card">
<div class="panel-header">
<div class="panel-title">Temperaturverlauf</div>
<span class="panel-badge" id="chart-label">letzte 80 Werte</span>
</div>
<canvas id="chart"></canvas>
</div>
{# ── Log + Alerts panel ── #}
<div class="log-panel glass">
<!-- Log + Alerts -->
<div class="log-panel card">
<div class="tab-bar">
<div class="tab active" data-tab="log" onclick="switchTab('log')">Rohdaten</div>
<div class="tab" data-tab="alerts" onclick="switchTab('alerts')">
Alerts
<span class="alert-badge" id="alert-badge"></span>
Alerts <span class="alert-badge" id="alert-badge"></span>
</div>
</div>
<div class="tab-body">
<div class="tab-pane active" id="pane-log">
<div class="log-entry" style="color:var(--frost-ghost)">
<span>Warte auf Daten …</span>
<div class="log-entry" style="color:var(--txt-ghost)">
<span></span><span>Warte auf Daten …</span><span></span>
</div>
</div>
<div class="tab-pane" id="pane-alerts">
<div class="alert-entry" style="color:var(--frost-ghost)">
<span>Keine Alerts.</span>
<div class="alert-entry" style="color:var(--txt-ghost)">
<span></span><span></span><span>Keine Alerts.</span>
</div>
</div>
</div>
</div>
</div>{# /log-panel #}
</main>{# /mirror-body #}
</main><!-- /mirror-body -->
{# ══════════════════════════════════
FOOTER
══════════════════════════════════ #}
<!-- ══ FOOTER ══ -->
<footer class="mirror-footer">
<span>Smart Mirror · Arduino USB Monitor</span>
<span id="footer-ts"></span>
<span>Smart Mirror · TGBBz Dillingen · Arduino USB Monitor</span>
<span id="footer-ts"></span>
</footer>
</div>{# /mirror-layout #}
</div>{# /mirror-root #}
</div>
</div>
<script src="{{ url_for('static', filename='js/dashboard.js') }}"></script>
{# Keep footer timestamp fresh #}
<script>
setInterval(() => {
document.getElementById('footer-ts').textContent =