Dokumentation
Erste Schritte
Das Dashboard bündelt die wichtigsten Informationen für den Bevölkerungsschutz in Berlin: Wetter, Regenradar, amtliche Warnungen, Einsätze der Berliner Feuerwehr und Wasserstände. Standardort ist Berlin.
Live unter dashboard-projekt-lenny-kevin.vercel.app. Lokal starten: README.md oder Entwicklung & Deployment.
Alle Einstellungen werden automatisch im Browser gespeichert und sind beim nächsten Öffnen wieder da.
Seitenleiste & Bedienung
- Warn-Banner
- In der Kopfzeile, zwischen Seitentitel und den Schaltflächen, läuft ein Hinweis von rechts nach links. Links und rechts steht immer „ACHTUNG“ (gelb-schwarz, auch bei Rot-Grün-Schwäche gut lesbar). Den Text stellst du unter Organisation im Widget „Warn-Banner“ ein. Ohne Text bleibt das Banner unsichtbar.
- Gegen Langeweile
- Zeigt Spielkacheln. Klondike-Solitaire kommt von solitaire-online.com, Tic Tac Toe und Dino Game von Jotform. „← Spiele“ führt zurück zur Auswahl.
- Dokumentation
- Öffnet diese Anleitung in einem eigenen Fenster.
- Version
- Zeigt die aktuelle Versionsnummer und öffnet das Changelog mit den Änderungen der Version 2.
- Einstellungen
- Tastaturkürzel für Übersicht, Wetter, Wasserpegel, Feuerwehr und Organisation. Standard ist 1–5. Eine Taste in der Liste anklicken und die neue Taste drücken; Rücktaste entfernt das Kürzel. In Suchfeldern greifen die Kürzel nicht.
- Modus: Hell / Dunkel
- Wechselt das Farbschema. Ohne eigene Wahl richtet sich das Dashboard nach der Systemeinstellung.
- Sprache
- Das Auswahlfeld neben dem Farbmodus stellt Dashboard und Dokumentation auf eine andere Sprache um (derzeit Deutsch und English). Die Seite lädt dabei kurz neu, alle Einstellungen bleiben erhalten. Ohne eigene Wahl gilt die Sprache des Browsers.
- Aktualisieren
- Lädt Wetter, Radar, Warnungen, Feuerwehr- und Pegeldaten neu. Die Kacheln laden kurz, der Knopf zeigt dann „aktualisiert“ und ist danach wieder der Knopf.
- Auto-Aktualisierung
- Bei „AN“ werden alle Daten alle 5 Minuten neu geladen. Ein Klick schaltet die Funktion aus oder wieder an.
- Standort & Datum
- Zeigt den aktuell gewählten Wetterort sowie Datum und Uhrzeit. Darunter steht, wann zuletzt aktualisiert wurde.
Übersicht
„Meine Übersicht“ ist frei zusammenstellbar. Beim ersten Start enthält sie aktuelles Wetter (Ort, Vorhersage und Stundenverlauf), Brandeinsätze pro Tag und die Pegel (Verlauf und Berliner Liste in einem Widget).
- Widget hinzufügen: „+ Widget“ öffnet den Katalog. Ein Klick auf einen Eintrag fügt das Widget hinzu — auch wenn es schon da ist, für Vergleiche (z. B. zwei Wetterorte oder zwei Pegel). Eine Zahl am Eintrag zeigt, wie oft es auf der Seite liegt.
- Widget entfernen: Im Anordnen-Modus erscheint oben rechts am Widget ein „ד.
- Einklappen: Der Pfeil am Widget klappt es auf die Titelzeile zusammen. Die übrigen Widgets nutzen den frei gewordenen Platz.
- Zurücksetzen: „↺ Zurücksetzen“ stellt nach einer Rückfrage die Standard-Auswahl und -Anordnung wieder her.
Widgets, die Daten einer anderen Seite zeigen (z. B. Temperatur oder Feuerwehr-Kennzahlen), sind Live-Kopien und aktualisieren sich automatisch mit. Zusätzliche Kacheln von „Aktuelles Wetter“ und „Pegelverlauf“ laden eigene Daten, damit du Orte und Pegel nebeneinander vergleichen kannst.
Anordnen & Größe ändern
Jede Seite hat oben die Schaltflächen ↺ Zurücksetzen, ✥ Anordnen und + Widget.
- „✥ Anordnen“ anklicken. Widgets und Bereiche bekommen einen gestrichelten Rahmen und oben einen Griff ⋮⋮⋮.
- Am Griff ziehen und das Widget an der gewünschten Stelle loslassen. Es landet vor oder hinter dem Widget, über dem der Mauszeiger steht.
- Auf den Unterseiten lassen sich alle Widgets frei verschieben, auch einzelne Kennzahl-Karten, und zwar in jede Reihe und Spalte. Ziehst du ein Widget in den oberen Griffbereich einer Spalte, landet es neben dieser Spalte.
- Wird ein Bereich leer, erscheint dort „Hierher ziehen“ als Ablagefläche.
- Die Größe änderst du mit dem Griff unten rechts am Widget. Widgets nutzen eine Standardhöhe und nur so viel Breite wie ihr Inhalt braucht. Freier Platz in einer Zeile erscheint als Platzhalter „Widget hinzufügen“ — ein Klick öffnet den Katalog, im Anordnen-Modus kannst du Widgets dorthin ziehen. Am Griff ziehst du einzelne Kacheln größer oder kleiner.
- „✓ Fertig“ beendet den Modus. Alles wird automatisch gespeichert.
Die Unterseiten haben ein festes Standard-Layout. „↺ Zurücksetzen“ stellt es nach einer Rückfrage wieder her, auch für Widgets, die in andere Bereiche verschoben wurden.
Die Seiten
Wetter
Aktuelles Wetter mit Temperatur, Wetterlage, Luftdruck, Luftfeuchtigkeit, Wind (Geschwindigkeit und Richtung als Kompass bzw. Himmelsrichtung), gefühlter Temperatur, UV-Index und Sonnenzeiten. Die Kennzahlen stehen im F-Muster in einer Zeile. Dazu kommen eine 6-Tage-Vorhersage, ein Stundenverlauf und das Regenradar neben dem aktuellen Wetter. Über das Suchfeld lässt sich ein anderer Ort wählen, z. B. „Lissabon“. Ein Klick auf einen Tag zeigt dessen Details.
Das Regenradar sitzt auf derselben Seite: Ort suchen oder eine Schnellwahl (Berlin, Potsdam, München, Hamburg) anklicken. Unter „Niederschlag“ wählst du die Quelle:
- RainViewer · Verlauf: Radarbilder der letzten Zeit. Mit ▶ abspielen oder mit dem Schieberegler durchblättern. Kostenlos bis Zoomstufe 7, darüber werden die Kacheln vergrößert.
- OpenWeather · aktuelle Karte: aktuelle Niederschlagskarte. Sie funktioniert nur mit einem API-Key (siehe Entwicklung).
Wasserpegel
Aktuelle Wasserstände der Bundeswasserstraßen, Standard ist Berlin-Köpenick. Andere Pegel findest du über die Suche (z. B. „Dresden“) oder in der Liste der Berliner Pegel. Der Verlauf zeigt die letzten 7 Tage mit den Richtwerten MNW (mittleres Niedrigwasser), MW (Mittelwasser) und MHW (mittleres Hochwasser).
Feuerwehr
Brandeinsätze der Berliner Feuerwehr der letzten 7 Tage: Kennzahlen im Vergleich zur Vorwoche, Einsätze pro Tag (der Spitzentag ist orange), Anteil an allen Einsätzen sowie eine Tagesübersicht mit Bränden, Hilfeleistungen und Eintreffzeit. Mit „CSV exportieren“ lädst du die Tabelle als Datei herunter.
Organisation
Amtliche Warnungen des Bundes (MoWaS, KATWARN, BIWAPP, DWD, Hochwasserzentralen), nach Ort filterbar und nach Schwere sortiert. Dazu gibt es die wichtigsten Notrufnummern, eine To-do-Liste (Vorschläge zur Notfallvorsorge, Einträge sind anpassbar) und das Warn-Banner in der Kopfzeile.
Gegen Langeweile
Optionale Spiele außerhalb der Lageübersicht: Klondike-Solitaire, Tic Tac Toe und Dino Game. Ein Klick auf eine Kachel startet das Spiel, „← Spiele“ führt zur Auswahl zurück.
Widget-Katalog
Diese Widgets lassen sich auf der Übersicht und auf jeder Unterseite über „+ Widget“ einblenden. Derselbe Typ darf mehrfach liegen; Wetter- und Pegelkacheln haben dann jeweils eine eigene Suche.
| Gruppe | Widget | Inhalt |
|---|---|---|
| Wetter | Aktuelles Wetter | Ort, Suche, Vorhersage und Stundenverlauf |
| Temperatur | Aktuelle Temperatur im Vergleich zu gestern | |
| Wind | Windgeschwindigkeit und -richtung (Kompass und Himmelsrichtung) im Vergleich zu gestern | |
| Luftfeuchte | Relative Luftfeuchtigkeit im Vergleich zu gestern | |
| Regenchance heute | Regenchance für heute im Vergleich zu gestern | |
| Vorhersage · Höchsttemperatur | Höchstwerte der nächsten Tage als Balken | |
| Regenwahrscheinlichkeit | Regenchance für heute | |
| Temperaturverlauf | Stündlicher Verlauf mit „jetzt“-Markierung | |
| Regenradar | Kleine Karte mit dem letzten Radarbild | |
| Kalender & Organisation | Kalender | Monatsansicht mit Terminen zum Eintragen |
| Termine heute | Heutige Einträge aus dem Kalender | |
| Notizen | Freier Notizzettel, speichert automatisch | |
| Aufgaben | To-do-Liste zum Abhaken | |
| Countdown | Tage bis zu einem Termin deiner Wahl | |
| Weltzeituhr | Uhrzeit in mehreren Städten | |
| Sicherheit | Warnungen | Amtliche Warnungen (BBK/NINA), nach Ort filterbar |
| Warn-Banner | Lauftext in der Kopfzeile, links und rechts „ACHTUNG“ | |
| To-do-Liste | Anpassbare Liste, Einträge untereinander, Vorschläge nach BBK | |
| Notrufnummern | 112, 110 und weitere wichtige Nummern | |
| Feuerwehr | Brände vom Vortag | Anzahl der Brandeinsätze am letzten Meldetag |
| Brandeinsätze (7 Tage) | Summe der letzten 7 Tage im Vergleich zur Vorwoche | |
| Ø pro Tag | Mittlere Zahl der Brandeinsätze pro Tag | |
| Spitzentag | Tag mit den meisten Brandeinsätzen | |
| Eintreffzeit 1. Löschfahrzeug | Mittlere Eintreffzeit des ersten Löschfahrzeugs | |
| Brandeinsätze pro Tag | Balkendiagramm der letzten 7 Tage | |
| Anteil Brandeinsätze | Anteil an allen Einsätzen der Woche | |
| Feuerwehr-Tagesübersicht | Tabelle mit Bränden, Hilfeleistungen und Eintreffzeit | |
| Wasserpegel | Wasserstand | Aktueller Wasserstand, Standard Berlin-Köpenick |
| Einordnung | Einordnung zum Mittelwasser | |
| Spanne 7 Tage | Tiefster und höchster Wasserstand der letzten 7 Tage | |
| Letzte Messung | Zeitpunkt der letzten Pegelmessung | |
| Pegelverlauf | 7-Tage-Verlauf und aktuelle Berliner Wasserstände | |
| Pegel in Berlin | Aktuelle Wasserstände der Berliner Pegel |
Smartphone & Tablet
Das Layout passt sich an die Bildschirmgröße an und nutzt die volle Breite. Unter 760 px Breite:
- Die Seitenleiste wird zur Kopfzeile. Das Menü öffnest du über die Schaltfläche ☰.
- Widgets stehen untereinander, und die Seite scrollt.
Deine Daten
Termine, Notizen, Aufgaben, Checkliste, Countdown, Layout und Farbmodus werden nur im lokalen Speicher deines Browsers (localStorage) abgelegt. Es gibt kein Benutzerkonto und keinen eigenen Server, der diese Daten speichert.
- Die Daten gelten nur für diesen Browser auf diesem Gerät.
- Wer die Website-Daten im Browser löscht, setzt das Dashboard komplett zurück.
- Für Wetter, Radar, Warnungen, Feuerwehr und Pegel ruft der Browser öffentliche Dienste ab (siehe Datenquellen). Dabei werden nur Ortsnamen bzw. Koordinaten übertragen.
Hilfe bei Problemen
Fällt eine Datenquelle aus, zeigt das betroffene Widget eine Meldung mit dem Grund und einem Knopf „Erneut versuchen“. Bereits geladene Daten bleiben dabei sichtbar („Angezeigt wird der letzte Stand“). Nach „Aktualisieren“ steht unten in der Seitenleiste rot, welche Bereiche nicht aktualisiert werden konnten.
- „keine Internetverbindung“
- Das Gerät ist offline. Sobald die Verbindung zurück ist, lädt das Dashboard automatisch neu.
- „zu viele Anfragen“
- Der Wetterdienst begrenzt viele Abrufe in kurzer Zeit. Eine Minute warten und erneut versuchen.
- „der Dienst antwortet nicht“ / „Dienst gerade gestört“
- Der externe Dienst ist langsam oder ausgefallen. Nach 12 Sekunden wird abgebrochen und einmal automatisch wiederholt. Später erneut versuchen.
- Keine Warnungen
- Die Warnungen laufen über den Server (
/api/warnings). Beim direkten Öffnen derindex.htmloder mit „Live Server“ fehlt diese Schnittstelle. Starte das Projekt stattdessen mitnode dev-server.js. „Unvollständig: …“ bedeutet, dass einzelne Warnsysteme gerade nicht erreichbar sind. - OpenWeather-Karte leer
- Kein Key gesetzt. Auf Vercel die Variable
OPENWEATHER_KEYeintragen, lokaljs/config.jsoder dieselbe Variable. Das Regenradar funktioniert dann nur mit RainViewer. - „Karte nicht verfügbar“
- Die Kartenbibliothek Leaflet konnte nicht geladen werden (z. B. durch einen Werbeblocker oder Netzwerkfilter). Der Rest des Dashboards funktioniert weiter.
- „Nicht gespeichert“
- Der Browser erlaubt kein Speichern (privater Modus, Speicher voll). Notizen, Layout und Einstellungen gehen dann beim Schließen verloren.
- Layout durcheinander
- Im Anordnen-Modus auf „↺ Zurücksetzen“ klicken.
- Port schon belegt
dev-server.jsmeldet das und beendet sich. Anderen Port wählen:PORT=3001 node dev-server.js.
Architektur & Dateien
Das Dashboard ist eine statische Single-Page-Anwendung aus HTML, CSS und Vanilla JavaScript ohne Build-Schritt und ohne Framework. Amtliche Warnungen und OpenWeather-Kacheln brauchen eine kleine Serverfunktion: warnung.bund.de sendet keine CORS-Header, der OpenWeather-Key soll nicht im Browser liegen.
| Datei | Aufgabe |
|---|---|
index.html | Struktur aller Seiten (.page), Seitenleiste, Dialoge für „Widget hinzufügen“, „Zurücksetzen“, Einstellungen und Changelog |
css/style.css | Alle Styles: Farbvariablen für Hell/Dunkel, Seitenleiste, Widgets, Container-Queries, Mobile-Ansicht |
js/app.js | Gesamte Logik: Navigation, Theme, Datenabrufe, Diagramme, Widget-Katalog, Layout-System |
js/i18n.js | Mehrsprachigkeit: Übersetzungsfunktion t(), Sprachwahl, Sprach-Auswahlfeld |
js/lang/<code>.js, js/lang/docs.<code>.js | Texte des Dashboards bzw. der Dokumentation pro Sprache (de, en) |
js/config.js | Optionaler OpenWeather-Key für den lokalen Fallback. Steht in .gitignore, Vorlage ist js/config.example.js. Auf Vercel gilt die Variable OPENWEATHER_KEY |
api/warnings.js | Serverless-Funktion (Vercel): holt MoWaS, KATWARN, BIWAPP, DWD und LHP und liefert sie gebündelt als JSON |
api/radar.js | Serverless-Funktion: liefert OpenWeather-Niederschlagskacheln, der Key bleibt auf dem Server |
dev-server.js | Lokaler Node-Server: liefert die Dateien aus und stellt /api/warnings und /api/radar bereit |
package.json, playwright.config.js, tests/ | Playwright-Suite. Start mit npm test, siehe Tests |
testresults/ | Markdown-Protokoll des letzten Testlaufs, eine Datei je Test plus Übersicht |
docs.html, css/docs.css, js/docs.js, img/docs/ | Diese Dokumentation mit Screenshots (WebP, 1440 × 900 bzw. Smartphone 390 px bei doppelter Auflösung) |
Ablauf in js/app.js
- Uhr, Navigation (
NAV_CATEGORIES) und Farbmodus initialisieren. - Daten laden:
loadWeatherForPlace,loadRadar,loadDisasterWarnings,loadFireData,loadWaterData. - Widget-Boards aufbauen (
OVERVIEW_WIDGETS,mountBoardWidget) und das gespeicherte Layout anwenden (initLayout). refreshDashboardDatalädt alles neu, manuell oder alle 5 Minuten (AUTO_REFRESH_INTERVAL_MS), und löst danach das Eventdashboard-refreshaus.
Entwicklung & Deployment
Voraussetzungen
Zum Starten: Node.js 18 oder neuer (LTS von nodejs.org, enthält npm) und Git zum Klonen. Prüfung: node -v, npm -v. Details und Installationsbefehle stehen in der README.md.
Lokal starten
git clone https://github.com/Kevin-Stein/Dashboard_Projekt_Lenny_Kevin.git
cd Dashboard_Projekt_Lenny_Kevin
node dev-server.js
# → http://localhost:3000 (anderer Port: PORT=3123 node dev-server.js)
Ein npm install ist zum Starten nicht nötig. Die Playwright-Tests brauchen zusätzlich die Pakete aus package.json (Chromium kommt mit npm install).
OpenWeather-Key (optional)
Auf Vercel unter Settings → Environment Variables OPENWEATHER_KEY eintragen (Production und Preview). Die Kacheln laufen über /api/radar, der Key erscheint nicht im Browser.
Lokal derselbe Key als Umgebungsvariable oder in js/config.js (Vorlage: js/config.example.js). js/config.js darf nicht committet werden. Beim direkten Öffnen der index.html ohne dev-server.js bleibt nur dieser Fallback, dann ist der Key in den Netzwerkanfragen sichtbar.
cp js/config.example.js js/config.js
# eigenen Key eintragen
# oder: OPENWEATHER_KEY=… node dev-server.js
Deployment auf Vercel
Die öffentliche Instanz: https://dashboard-projekt-lenny-kevin.vercel.app/
- Die statischen Dateien werden direkt ausgeliefert,
api/warnings.jsundapi/radar.jslaufen als Serverless-Funktionen unter/api/warningsbzw./api/radar. - Die Antwort wird mit
Cache-Control: s-maxage=60, stale-while-revalidate=300gecacht. .vercelignoreschließt lokale Ordner wie.cursor/und.claude/vom Upload aus, falls sie vorhanden sind.
Die automatisierten Tests stehen im Abschnitt Tests.
Tests
Die Oberfläche wird mit Playwright im echten Chromium geprüft. Die Suite startet selbst dev-server.js auf Port 3125 (127.0.0.1), damit ein lokal laufendes Dashboard und dessen localStorage unberührt bleiben. Wetter, Radar, Warnungen, Pegel und Feuerwehr werden im Test nachgebaut, es gehen also keine echten API-Aufrufe raus.
Starten
npm install # einmalig: Pakete und Chromium
npm test # alle Tests, unsichtbar
npm run test:headed # dieselben Tests, Browser sichtbar
npm install lädt Chromium über das Skript postinstall. Einzelne Dateien: npx playwright test tests/injection.spec.js.
Nach jedem Lauf schreibt tests/markdown-reporter.js die Ergebnisse nach testresults/: README.md als Übersicht und eine Markdown-Datei je Test mit Zweck, Ablauf, Erwartung und Status.
Dateien
| Datei | Aufgabe |
|---|---|
playwright.config.js | Port 3125, Locale de-DE, Reporter (Liste + Markdown) |
tests/helpers.js | Sprache setzen, Seiten öffnen, Widgets hinzufügen, API-Stubs |
tests/dashboard.spec.js | Navigation, Sprachen, Theme, Widget-Katalog, Doku, Smartphone-Menü |
tests/inputs.spec.js | Formulare, Suche, Speichern |
tests/injection.spec.js | XSS- und HTML-Payloads in allen Eingabefeldern |
tests/stress.spec.js | Viele Klicks, lange Texte, viele Widgets |
tests/markdown-reporter.js | Schreibt testresults/*.md |
Was die Suite prüft
Dashboard und Dokumentation
- Sprachmenü steht neben dem Farbmodus, Einträge Deutsch und English.
- Start auf Deutsch, Wechsel auf Englisch inkl. Reload: Titel, Navigation, Übersicht.
- Alle fünf Seiten (Übersicht, Wetter inkl. Regenradar, Wasserpegel, Feuerwehr, Organisation) und Tastaturkürzel 1–5.
- Widget-Katalog auf Deutsch und Englisch öffnen und schließen.
- Gegen Langeweile: Spielkacheln, Klondike, Tic Tac Toe und Dino Game.
- Dasselbe Widget mehrfach hinzufügen (Wetter und Pegel mit eigener Suche).
- Farbmodus Hell → Dunkel.
- Smartphone (390×844): Navigation verborgen, Menü öffnet die Seitenleiste.
- Dokumentation: deutsche Texte, Sprachwechsel, Abschnitt Mehrsprachigkeit, Knopf „Zum Dashboard“.
Eingabefelder
- Leeres Absenden bei Wetter, Radar und Pegel ändert nichts.
- Ortssuche: Treffer (Hamburg), unbekannter Name, Radar-Schnellwahl Potsdam.
- Notrufnummern und To-do-Liste auf der Organisations-Seite.
- Warnungsfilter (Dresden / kein Treffer) und Checkliste abhaken.
- Pegelsuche: Dresden anzeigen, unbekannter Name als Toast.
- Aufgaben anlegen, abhaken, löschen; Notizen speichern; Kalendertermin; Countdown.
- Radar-Quelle OpenWeather und Auto-Aktualisierung aus.
Code-Injection
Payloads wie <script>alert(1)</script>, <img src=x onerror=alert(1)>, SVG-onload, Textarea-Breakout, javascript:-URLs und Template-Injection in Aufgaben, Notizen, Kalender, Countdown, Wetter-/Radar-/Pegelsuche und Warnungsfilter. Erwartung: kein Dialog, Payload nur als Text, keine eingeschleusten img/script-Knoten. Ortsnamen im Radar-Popup werden per textContent gesetzt, nicht als HTML.
Belastung
- Alle Seiten achtmal hintereinander umschalten.
- Theme, Widget-Katalog und Anordnen sehr oft klicken.
- Leere Formulare und 4000-Zeichen-Text mit HTML und Umlauten.
- 40 Aufgaben, mehrere Widgets hinzufügen und wieder entfernen.
- Aktualisieren, Auto-Aktualisierung und Sprachwechsel mehrfach.
Datenquellen & APIs
| Bereich | Endpunkt | Hinweise |
|---|---|---|
| Wetter | api.open-meteo.com/v1/forecast | forecast_days=6&past_days=1. Der Vortag wird abgetrennt (splitOffYesterday) und für den Vergleich „gegenüber gestern“ genutzt |
| Ortssuche | geocoding-api.open-meteo.com/v1/search | Erster Treffer, Sprache Deutsch |
| Radar | api.rainviewer.com/public/weather-maps.json | Liste der Radarbilder, Kacheln als Leaflet-Layer, Animation alle 850 ms |
| Niederschlag | /api/radar → tile.openweathermap.org/map/precipitation_new | Key über Vercel OPENWEATHER_KEY oder lokal js/config.js. Ohne Server fällt der Browser auf den Key in js/config.js zurück |
| Karte | server.arcgisonline.com/…/World_Light_Gray_Base | Hintergrundkacheln von Esri |
| Warnungen | /api/warnings → warnung.bund.de/api31/<quelle>/mapData.json | Quellen: mowas, katwarn, biwapp, dwd, lhp. Timeout 8 s pro Quelle; ausgefallene Quellen stehen im Header X-Warnings-Failed, erst wenn alle ausfallen gibt es HTTP 502 |
| Feuerwehr | raw.githubusercontent.com/Berliner-Feuerwehr/BF-Open-Data/…/BFw_mission_data_daily.csv | Tägliche CSV, ausgewertet werden die letzten 7 Tage und die Vorwoche |
| Wasserpegel | www.pegelonline.wsv.de/webservices/rest-api/v2 | Stationen, aktueller Wert, 7-Tage-Messreihe, Kennwerte MNW/MW/MHW |
Fehlerbehandlung
Datenabrufe: fetchData(url, optionen)
Alle Abrufe in js/app.js laufen über diese Funktion. Sie bricht nach FETCH_TIMEOUT_MS (12 s) per AbortController ab und wiederholt bei Timeout, Netzfehler, HTTP 429 und 5xx einmal (mit Retry-After bzw. kurzer Wartezeit). Fehler werden als FetchError mit kind geworfen:
kind | Bedeutung | Text von describeError |
|---|---|---|
offline | navigator.onLine ist false | keine Internetverbindung |
timeout | Abbruch nach Timeout | der Dienst antwortet nicht |
network | DNS, CORS, blockiert | Dienst nicht erreichbar |
http | Status ≠ 2xx, in status | je nach Status (429, 401/403, 404, 5xx) |
data | kein gültiges JSON oder Pflichtfelder fehlen (dataError()) | Antwort unvollständig oder fehlerhaft |
Muster für einen Loader
async function loadX() {
try {
const data = await fetchData(URL, { source: "X" });
if (!data.items) throw dataError("X", "keine Einträge");
render(data);
return true;
} catch (err) {
reportError("X", err); // console.warn mit Quelle
renderRetry(el, `X nicht verfügbar – ${describeError(err)}.`, loadX);
return false; // alte Daten bleiben stehen
}
}
refreshDashboardDatanutztPromise.allSettledund wertet die Rückgabetrue/falseaus. Fehlgeschlagene Quellen erscheinen in#refreshErrorsund bei manuellem Klick als roter Toast (showToast(text, "error")). Parallele Aufrufe werden zusammengefasst.- Die Events
offline/onlinezeigen einen Hinweis bzw. starten eine Aktualisierung. storageSet(key, value)ersetztlocalStorage.setItemund meldet einmalig, wenn Speichern nicht möglich ist.- Wirft ein Widget beim Start eine Exception, zeigt nur dieses Widget eine Fehlermeldung (
mountBoardWidget). - Ohne Leaflet (
LEAFLET_AVAILABLE) ersetzt ein PlatzhalterL, damit das restliche Skript weiterläuft. - Globale Handler für
errorundunhandledrejectionprotokollieren unerwartete Fehler und zeigen höchstens alle 15 s einen Hinweis. - Serverseitig:
api/warnings.jsantwortet mit 405 bei falscher Methode und 502 als JSON,dev-server.jsmit 400/403/404/500 statt abzustürzen.
Layout-System
Container und Elemente
Jede Seite hat eine gemeinsame Widget-Fläche: das Raster .overview-grid. Darin liegen die Standard-Kacheln der Seite und alle hinzugefügten Widgets. Verschieben und Skalieren im Modus Anordnen gilt nur innerhalb dieses Rasters.
- Reihenfolge:
saveLayoutOrderundapplySavedLayoutOrderspeichern und laden die Reihenfolge der Kacheln im Raster. - Freies Verschieben:
startRoamDragermittelt mitdocument.elementsFromPointdas Ziel im Raster. Ob das Element davor oder dahinter landet, hängt davon ab, ob der Zeiger vor oder hinter der Mitte des Ziels liegt. - Größe: Standard ist Breite nach Inhalt. Im Anordnen-Modus speichert der Griff unten rechts Pixelmaße (
data-layout-h,data-layout-w, Mindestgröße 260 × 170 px). - Zurücksetzen: Das Raster merkt sich die Standardreihenfolge (
_defaultOrder).resetPageLayoutstellt sie wieder her, löscht gespeicherte Größen und setzt auf der Übersicht die Standard-Widgets (aktuelles Wetter, Feuerwehr-Diagramm, Pegel) wieder ein statt die Fläche zu leeren.
Skalierung mit Container-Queries
Widget-Inhalte skalieren über CSS-Container-Queries statt über die Fenstergröße: .ov-body (ovbody), Kennzahl-Karten (statcard) und Diagramme (chartcard). Schriftgrößen nutzen cqh/cqw mit clamp(). Bei sehr kleinen Widgets werden Nebenelemente wie Icons, Beschriftungen oder Datumszeilen ausgeblendet.
Live-Kopien (Mirror-Widgets)
Widgets mit source klonen das komplette Panel einer anderen Seite (gleiche Überschrift und gleicher Inhalt). mirror klont nur Fragmente (z. B. Kennzahl-Reihen). IDs erhalten ein Suffix, damit sie eindeutig bleiben.
Speicherschlüssel (localStorage)
| Schlüssel | Inhalt |
|---|---|
dashboard-theme | light oder dark. Fehlt der Wert, gilt die Systemeinstellung |
dashboard-lang | Sprachcode, z. B. de oder en. Fehlt der Wert, gilt die Browsersprache |
dashboard-auto-refresh | Auto-Aktualisierung an/aus |
dashboard-overview-widgets | Widget-Typen der Übersicht |
dashboard-page-widgets-<seite> | Zusätzliche Widgets einer Unterseite |
dashboard-layout-<container> | Reihenfolge der Elemente in einem Container |
dashboard-layout-sizes | Größen (height, width, frac, ggf. älteres grow) pro Element |
dashboard-widget-places | In andere Container verschobene Elemente: { elementId: "seite:container" } |
dashboard-collapsed | IDs eingeklappter Widgets |
dashboard-cal-events | Kalendertermine |
dashboard-banner-text | Lauftext des Warn-Banners |
dashboard-shortcuts | Tastaturkürzel der fünf Hauptseiten (Standard 1–5) |
dashboard-widget-notes, -todo, -countdown, -checklist | Inhalte der jeweiligen Widgets |
dashboard-water-station | Gewählter Pegel (UUID). Standard ist Berlin-Köpenick |
Erweitern
Neues Widget
Einen Eintrag in OVERVIEW_WIDGETS (js/app.js) ergänzen und Titel und Beschreibung in jeder Sprachdatei eintragen. Das Widget erscheint dann automatisch im Katalog jeder Seite.
// js/lang/de.js (und entsprechend en.js)
"widget.mein-widget.title": "Mein Widget",
"widget.mein-widget.desc": "Kurze Beschreibung für den Katalog",
// js/app.js
"mein-widget": {
group: "calendar", // Gruppe im Katalog (Schlüssel groups.calendar)
icon: OVERVIEW_ICONS.notes,
mount: mountMeinWidget, // oder: mirror: ["#quellElement"]
wide: true, // optional: startet breiter
},
function mountMeinWidget(body) {
body.innerHTML = `<div class="mein-inhalt">${t("widget.mein-widget.empty")}</div>`;
const timer = setInterval(update, 60000);
return () => clearInterval(timer); // optional: Aufräumen beim Entfernen
}
Größen im Widget möglichst mit Container-Einheiten (cqh, cqw) innerhalb von .ov-body angeben, damit das Widget beim Ändern der Größe mitskaliert.
Neue Seite
- In
index.htmlein<div id="meinePage" class="page">mit der.overview-bar(Titel und die drei Schaltflächen) anlegen. - Direkt unter der Leiste das Widget-Raster
<div class="overview-grid" id="meinePageWidgets">anlegen und die Standard-Kacheln darin einfügen. Die ID muss<Seiten-ID>Widgetslauten, damit „+ Widget“ funktioniert. - In
NAV_CATEGORIESeinen Eintrag mittarget: "meinePage"und einem SVG-Icon ergänzen. Den Seitennamen alsnav.<id>in jede Sprachdatei eintragen, sichtbare Texte der Seite mitdata-i18nauszeichnen.
Mehrsprachigkeit
Alle sichtbaren Texte kommen aus Sprachdateien. js/i18n.js wählt die Sprache in dieser Reihenfolge: gespeicherte Wahl (dashboard-lang), Browsersprache, Deutsch. Fehlt ein Text in einer Sprache, wird der deutsche verwendet.
- In JavaScript:
t("weather.loadingFor", { place: "Berlin" }). Platzhalter stehen in geschweiften Klammern im Text. - In HTML:
data-i18n="schlüssel"setzt den Text,data-i18n-htmlerlaubt Auszeichnungen,data-i18n-attr="placeholder=schlüssel;aria-label=schlüssel2"übersetzt Attribute. - Datum und Zahlen nutzen
I18N.locale()(z. B.de-DE,en-GB) mittoLocaleStringbzw.Intl. - Beim Sprachwechsel lädt die Seite neu. Ein zweites offenes Fenster (Dashboard oder Dokumentation) übernimmt die Sprache automatisch.
Neue Sprache hinzufügen
js/lang/en.jsnach z. B.js/lang/fr.jskopieren, Code, Name und Locale anpassen und alle Texte übersetzen:I18N.register("fr", { name: "Français", locale: "fr-FR", strings: { "nav.overview": "Aperçu", … }, });- In
index.htmlunddocs.htmlunter den anderen Sprachdateien<script src="js/lang/fr.js"></script>einfügen. - Optional die Dokumentation übersetzen:
js/lang/docs.en.jsnachdocs.fr.jskopieren, übersetzen und ebenfalls indocs.htmleinbinden. Ohne diese Datei erscheint die Dokumentation auf Deutsch.
Die neue Sprache erscheint danach automatisch im Auswahlfeld.
Lizenzen & Quellen
| Quelle | Lizenz / Bedingungen |
|---|---|
| Open-Meteo | CC BY 4.0, kostenlos für nicht-kommerzielle Nutzung (Bedingungen). Ortsdaten von GeoNames (CC BY 4.0) |
| RainViewer | Kostenlose öffentliche API mit Namensnennung (Nutzungsbedingungen) |
| OpenWeather | ODbL 1.0, Namensnennung „Weather data provided by OpenWeather“ (Bedingungen) |
| Esri World Light Gray Base | Esri-Nutzungsbedingungen. Namensnennung: Esri, HERE, Garmin, FAO, NOAA, USGS |
| Berliner Feuerwehr – BF-Open-Data | CC BY 4.0, © Berliner Feuerwehr |
| PEGELONLINE (WSV / ITZBund) | Datenlizenz Deutschland – Zero – 2.0 |
| warnung.bund.de (BBK, NINA) | Keine ausdrückliche Lizenz. Quelle: BBK und die jeweils herausgebende Stelle |
| Leaflet 1.9.4 | BSD 2-Clause |
| Outfit, Source Sans 3 | SIL Open Font License 1.1 |
| Klondike (solitaire-online.com), Tic Tac Toe und Dino Game (Jotform) | Eingebettete Spiele unter „Gegen Langeweile“, Nutzungsbedingungen der jeweiligen Anbieter |