release-2.0
This commit is contained in:
@@ -4,143 +4,214 @@
|
||||
{% block body %}
|
||||
<div id="mirror-root"
|
||||
data-poll-ms="{{ poll_ms }}"
|
||||
data-sensors="{{ sensors_json | e }}">
|
||||
data-sensors="{{ sensors_json | e }}"
|
||||
data-location="{{ location_json | e }}">
|
||||
|
||||
<div class="mirror-layout">
|
||||
<!-- ══════════════════════════════════════
|
||||
VIEW TOGGLE (tiny, hidden in corner)
|
||||
══════════════════════════════════════ -->
|
||||
<button id="view-toggle" title="Ansicht wechseln" onclick="toggleView()">
|
||||
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2 3h5v5H2V3zm7 0h5v5H9V3zm-7 7h5v3H2v-3zm7 0h5v3H9v-3z"/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<!-- ══ HEADER ══ -->
|
||||
<header class="mirror-header card">
|
||||
<!-- ══════════════════════════════════════
|
||||
DEV VIEW
|
||||
══════════════════════════════════════ -->
|
||||
<div id="view-dev">
|
||||
<div class="mirror-layout">
|
||||
|
||||
<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 card" id="conn-badge">
|
||||
<div class="conn-dot" id="conn-dot"></div>
|
||||
<span id="conn-text">Verbinde …</span>
|
||||
</div>
|
||||
|
||||
</header>
|
||||
|
||||
|
||||
<!-- ══ BODY ══ -->
|
||||
<main class="mirror-body">
|
||||
|
||||
<!-- Sensor tiles -->
|
||||
{% set icons = ['🌡️','💧','🌧️','📡','📊','⚡'] %}
|
||||
{% for s in sensors %}
|
||||
<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-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 -%} {%- endif -%}
|
||||
{%- if s.threshold_high is not none -%}↑ {{ s.threshold_high }}{{ s.unit }}{%- endif -%}
|
||||
<header class="mirror-header card">
|
||||
<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>
|
||||
{% endfor %}
|
||||
|
||||
|
||||
<!-- Stat row -->
|
||||
<div class="stat-row">
|
||||
|
||||
<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 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="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 class="conn-badge card" id="conn-badge">
|
||||
<div class="conn-dot" id="conn-dot"></div>
|
||||
<span id="conn-text">Verbinde …</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<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>
|
||||
<main class="mirror-body">
|
||||
|
||||
{% set icons = ['🌡️','💧','🌧️','📡','📊','⚡'] %}
|
||||
{% for s in sensors %}
|
||||
<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"></div>
|
||||
</div>
|
||||
</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 -->
|
||||
|
||||
|
||||
<!-- 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 -->
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-body">
|
||||
<div class="tab-pane active" id="pane-log">
|
||||
<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(--txt-ghost)">
|
||||
<span></span><span></span><span>Keine Alerts.</span>
|
||||
<div class="sensor-label">{{ s.name }}</div>
|
||||
<div class="sensor-value" id="sv-{{ loop.index0 }}">—</div>
|
||||
<div class="sensor-meta">
|
||||
<div class="sensor-threshold">
|
||||
{%- if s.threshold_low is not none -%}↓ {{ s.threshold_low }}{{ s.unit }} {%- endif -%}
|
||||
{%- if s.threshold_high is not none -%}↑ {{ s.threshold_high }}{{ s.unit }}{%- endif -%}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<div class="stat-row">
|
||||
<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 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 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 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>
|
||||
|
||||
<div class="chart-panel card">
|
||||
<div class="panel-header">
|
||||
<div class="panel-title">Temperaturverlauf (Sensor)</div>
|
||||
<span class="panel-badge">letzte 80 Werte</span>
|
||||
</div>
|
||||
<canvas id="chart"></canvas>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-body">
|
||||
<div class="tab-pane active" id="pane-log">
|
||||
<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(--txt-ghost)">
|
||||
<span></span><span></span><span>Keine Alerts.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
|
||||
<footer class="mirror-footer">
|
||||
<span>TGBBz Dillingen · Smart Mirror · Arduino USB Monitor</span>
|
||||
<span id="footer-ts">—</span>
|
||||
</footer>
|
||||
</div>
|
||||
</div><!-- /view-dev -->
|
||||
|
||||
|
||||
<!-- ══════════════════════════════════════
|
||||
CONSUMER VIEW
|
||||
══════════════════════════════════════ -->
|
||||
<div id="view-consumer">
|
||||
<div class="consumer-wrap">
|
||||
|
||||
<!-- Clock -->
|
||||
<div class="c-clock">
|
||||
<div class="c-time" id="c-time">00:00</div>
|
||||
<div class="c-date" id="c-date">—</div>
|
||||
</div>
|
||||
|
||||
</main><!-- /mirror-body -->
|
||||
<div class="c-divider"></div>
|
||||
|
||||
<!-- Weather -->
|
||||
<div class="c-weather">
|
||||
<div class="c-location" id="c-location">—</div>
|
||||
<div class="c-weather-main">
|
||||
<div class="c-weather-icon" id="c-icon">—</div>
|
||||
<div class="c-temp-outside" id="c-temp-out">—°</div>
|
||||
</div>
|
||||
<div class="c-weather-desc" id="c-desc">Wetterdaten werden geladen …</div>
|
||||
</div>
|
||||
|
||||
<!-- ══ FOOTER ══ -->
|
||||
<footer class="mirror-footer">
|
||||
<span>Smart Mirror · TGBBz Dillingen · Arduino USB Monitor</span>
|
||||
<span id="footer-ts">—</span>
|
||||
</footer>
|
||||
<!-- Stat pills -->
|
||||
<div class="c-stats">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- Arduino Temp -->
|
||||
<div class="c-stat">
|
||||
<div class="c-stat-icon">🌡️</div>
|
||||
<div class="c-stat-val loading" id="c-sensor-temp">—</div>
|
||||
<div class="c-stat-label">Innen Temp.</div>
|
||||
</div>
|
||||
|
||||
<!-- Arduino Humidity -->
|
||||
<div class="c-stat">
|
||||
<div class="c-stat-icon">💧</div>
|
||||
<div class="c-stat-val loading" id="c-sensor-hum">—</div>
|
||||
<div class="c-stat-label">Luftfeucht.</div>
|
||||
</div>
|
||||
|
||||
<!-- Weather humidity (outside) -->
|
||||
<div class="c-stat">
|
||||
<div class="c-stat-icon">🌬️</div>
|
||||
<div class="c-stat-val loading" id="c-humidity">—</div>
|
||||
<div class="c-stat-label">Außen Feuchte</div>
|
||||
</div>
|
||||
|
||||
<!-- Rain probability -->
|
||||
<div class="c-stat">
|
||||
<div class="c-stat-icon">🌧️</div>
|
||||
<div class="c-stat-val loading" id="c-rain">—</div>
|
||||
<div class="c-stat-label">Regenwahrsch.</div>
|
||||
<div class="c-rain-bar-wrap">
|
||||
<div class="c-rain-bar" id="c-rain-bar" style="width:0%"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Feels like -->
|
||||
<div class="c-stat">
|
||||
<div class="c-stat-icon">🧥</div>
|
||||
<div class="c-stat-val loading" id="c-feels">—</div>
|
||||
<div class="c-stat-label">Gefühlt</div>
|
||||
</div>
|
||||
|
||||
<!-- Wind -->
|
||||
<div class="c-stat">
|
||||
<div class="c-stat-icon">💨</div>
|
||||
<div class="c-stat-val loading" id="c-wind">—</div>
|
||||
<div class="c-stat-label">Wind</div>
|
||||
</div>
|
||||
|
||||
</div><!-- /c-stats -->
|
||||
|
||||
</div><!-- /consumer-wrap -->
|
||||
</div><!-- /view-consumer -->
|
||||
|
||||
</div><!-- /mirror-root -->
|
||||
|
||||
<script src="{{ url_for('static', filename='js/dashboard.js') }}"></script>
|
||||
<script>
|
||||
|
||||
Reference in New Issue
Block a user