Files
Smart-Dashboard/js/solar/anzeige.js
T
adminandClaude Opus 5 2e66bdeff5 Anzeige fuer den Pi ist jetzt die Solar-Seite im Anzeige-Modus
Statt einer eigenen Vorlage mit nachgebauter Verdrahtung: ?action=anzeige
ist der Eintrag solar mit "anzeige" => true. header.php laesst Kopfleiste
und Menue weg und setzt die schmale Leiste (neu: Diagramme), footer.php
den Fuss; die Realtime-Karte fuellt einen Bildschirm, Diagramme folgen
darunter. Damit gehen am Display auch die Bedienfenster (Heizstab,
Wallboxen, Bewaesserung) und die Diagramme - alles aus solarMQTT.js.

anzeige.js bleibt fuer Leerlauf, Verbindungspunkt, Uhr und Neuladen;
restricted/anzeige.php, "eigen" in index.php und klickFilter entfallen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 20:22:35 +02:00

104 lines
4.4 KiB
JavaScript

/* ==========================================================================
Anzeige-Modus der Solar-Seite (index.php?action=anzeige) für ein festes
Display, gebaut für den Raspberry Pi 3B+ mit 800 x 480.
Die Seite selbst ist die Solar-Seite: solarMQTT.js zeichnet Übersicht,
Anlage, Speicher und Diagramme und öffnet die Bedienfenster. header.php
lässt Kopfleiste und Menü weg und setzt stattdessen die schmale Leiste
links; die Übersicht bleibt quer (energieflussStarten() in solarMQTT.js
fragt nach der Klasse "anzeige" am body).
Hier steht nur, was ein Display ohne Bediener braucht:
- Leiste: Übersicht, Anlage, Speicher, Diagramme
- nach LEERLAUF ohne Berührung zurück zur Übersicht, ganz nach oben
- Punkt in der Leiste: grün verbunden, gelb keine frischen Werte,
rot getrennt
- alle NEU_LADEN Stunden neu laden - ein Browser, der wochenlang läuft,
sammelt sonst Speicher an, und Änderungen am Code kämen nie an
========================================================================== */
(function () {
"use strict";
const LEERLAUF = 2 * 60000;
const NEU_LADEN = 6 * 3600000;
const VERALTET = 30000;
const $ = id => document.getElementById(id);
let leerlaufUhr = null;
let letzteNachricht = null, letzteZeit = 0;
function leisteSetzen(name) {
document.querySelectorAll("[data-anzeige]").forEach(b =>
b.setAttribute("aria-pressed", b.dataset.anzeige === name ? "true" : "false"));
}
function karte() {
return $("energieflussKarte");
}
/** Eine Ansicht der Realtime-Karte zeigen - über ihren eigenen Umschalter. */
function zeige(name) {
if (name === "diagramme") {
// Die nächste Spalte nach der Realtime-Karte - dazwischen steht ein <script>.
let ziel = karte() && karte().closest("[class*=col-]").nextElementSibling;
while (ziel && !ziel.matches("[class*=col-]")) ziel = ziel.nextElementSibling;
if (ziel) ziel.scrollIntoView({ behavior: "instant", block: "start" });
leisteSetzen("diagramme");
return;
}
window.scrollTo({ top: 0, behavior: "instant" });
const knopf = document.querySelector('[data-enf-ansicht="' + name + '"]');
if (knopf) knopf.click();
leisteSetzen(name);
}
function wachHalten() {
clearTimeout(leerlaufUhr);
leerlaufUhr = setTimeout(() => {
const offen = document.querySelector(".modal.show");
if (offen && window.bootstrap) bootstrap.Modal.getOrCreateInstance(offen).hide();
zeige("fluss");
}, LEERLAUF);
}
function zustand() {
const nachricht = window.mqttData && mqttData["solarManager/P_Load"];
if (nachricht && nachricht !== letzteNachricht) { letzteNachricht = nachricht; letzteZeit = Date.now(); }
const verbunden = typeof solarMqttClient !== "undefined" && solarMqttClient && solarMqttClient.connected;
const frisch = Date.now() - letzteZeit < VERALTET;
const punkt = $("anzeigeVerbindung");
const klasse = "anzeige-punkt" + (verbunden && frisch ? " gut" : verbunden ? " warn" : "");
if (punkt.className !== klasse) {
punkt.className = klasse;
punkt.title = verbunden && frisch ? "verbunden" : verbunden ? "verbunden, aber keine frischen Werte" : "Verbindung getrennt";
}
const d = new Date();
const uhr = String(d.getHours()).padStart(2, "0") + ":" + String(d.getMinutes()).padStart(2, "0");
if ($("anzeigeUhr").textContent !== uhr) $("anzeigeUhr").textContent = uhr;
}
document.addEventListener("DOMContentLoaded", () => {
if (!document.body.classList.contains("anzeige")) return;
document.querySelectorAll("[data-anzeige]").forEach(b => b.addEventListener("click", () => zeige(b.dataset.anzeige)));
// Klick auf Sonne oder Batterie wechselt über den Umschalter der Karte -
// die Leiste zieht nach.
document.querySelectorAll("[data-enf-ansicht]").forEach(b =>
b.addEventListener("click", () => leisteSetzen(b.dataset.enfAnsicht)));
window.addEventListener("scroll", () => {
const k = karte();
if (!k) return;
const unten = k.getBoundingClientRect().bottom < window.innerHeight / 2;
const aktiv = document.querySelector("[data-enf-ansicht].active");
leisteSetzen(unten ? "diagramme" : aktiv ? aktiv.dataset.enfAnsicht : "fluss");
}, { passive: true });
document.addEventListener("pointerdown", wachHalten, { passive: true });
wachHalten();
setInterval(zustand, 1000);
zustand();
setTimeout(() => location.reload(), NEU_LADEN);
});
})();