- TypeScript 93.6%
- JavaScript 5.2%
- CSS 0.8%
- Shell 0.4%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .openai | ||
| app | ||
| db | ||
| docs/screenshots | ||
| drizzle/meta | ||
| examples/d1 | ||
| lib | ||
| public | ||
| tests | ||
| tools | ||
| worker | ||
| .env.example | ||
| .gitignore | ||
| drizzle.config.ts | ||
| eslint.config.mjs | ||
| LICENSE | ||
| next-env.d.ts | ||
| next.config.ts | ||
| package-lock.json | ||
| package.json | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| postcss.config.mjs | ||
| README.md | ||
| tsconfig.json | ||
| vite.config.ts | ||
Shelly Wall Display Dashboard
Touch-Dashboard für ShellyElevate ohne Home Assistant.
- Produktionsserver:
10.0.1.125 - Dashboard:
http://10.0.1.125:3000/ - ShellyElevate-Verwaltung:
http://10.0.1.125:3000/admin - Displayprofile:
http://10.0.1.125:3000/admin/displays - Projektverzeichnis:
/home/hubobel/shelly_test
Dashboard
Speedtest
System
Die Netzwerkdaten stammen aus dem ioBroker-Adapter unifi-network.0:
- Gesamtzahl verbundener Clients:
unifi-network.0.lan.connected_clients - WLAN-Clients:
unifi-network.0.wlan.connected_clients - LAN-Clients: Gesamtzahl minus WLAN-Clients
- Gateway CPU/RAM/Uptime: Gerät
9c:05:d6:52:52:19 - Switch CPU/Temperatur: Gerät
f4:92:bf:79:ce:8b
Die konkreten Datenpunkte können über die Variablen in .env.local
überschrieben werden.
Energie
Die Energiekacheln öffnen per Antippen Detail-Overlays. Das PV-Overlay verwendet
den Tagesertrag direkt aus dem Influx-Measurement PV_Tagesertrag. Das
Stromnetz-Overlay zeigt den Tagesgesamtverbrauch. Overlays werden ausschließlich
über das × geschlossen und kehren dabei auf die zuvor geöffnete Seite zurück.
Wetter
Die Wetterseite kombiniert folgende Influx-Measurements:
Temp_GartenundFeucht_GartenTemp_WzundFeucht_WzWindgeschwindigkeitundWindrichtungNiederschlag_Tag
Das Wetterbild stammt aus dem ioBroker-Datenpunkt
daswetter.0.NextHours.Location_1.Day_1.current.iconURL. Windgeschwindigkeit und
Windrichtung werden über die letzten fünf Minuten gemittelt; die Richtung wird
als Kreismittel berechnet. Unter 1 km/h oder bei fehlendem Windwert wird der
gesamte Windbereich vollständig ausgeblendet. Erst ab 1 km/h erscheinen
Geschwindigkeitswert und – sofern vorhanden – Windrose. Niederschlag wird nur
bei einem Wert größer als 0,0 angezeigt.
Kalender
Die Kalenderseite liest eigene und abonnierte Google-Kalender über das separat
betriebene gcalendar-gateway. Kalender können global in der
Displayverwaltung ausgewählt und zusätzlich direkt am jeweiligen Display
temporär ausgeblendet werden:
- Kalendereintrag 1,5 Sekunden halten: zugehörigen Kalender ausblenden
- farbigen Punkt 1,5 Sekunden halten: Kalender wieder einblenden
Der Screensaver berücksichtigt ausschließlich die auf dem Display sichtbaren Kalender und zeigt noch nicht beendete Termine von heute sowie eine Vorschau auf den kommenden Tag. Vergangene Termine werden nicht mehr dargestellt.
Finanzen / ING
Die Finanzseite zeigt Kontostand und ING-Logo. Ein Druck auf den Kontostand öffnet den Kontostandsverlauf des aktuellen Finanzmonats ab dem 15. zusammen mit dem Viermonatsmittel. Die Zeitachse verwendet vier chronologisch korrekte Datumsstützpunkte. Unter dem Kontostand wird die Abweichung vom Viermonatsmittel am vergleichbaren Tag angezeigt; positive Abweichungen sind grün.
9a – Rollläden, Schalter und Fenster
Die Seite ist nach Etage (EG, OG, DG) und Gerätetyp (ROLLLÄDEN,
SCHALTER, FENSTER) gegliedert. Geräte erscheinen in einem kontrastreichen
2×2-Raster. Weitere Gerätepaare werden über große Seitenpunkte gewechselt.
Längeres Halten verwendet einen gut sichtbaren Fortschrittsbalken am oberen
Displayrand. Fensterzustände werden aus Fensterstatus visualisiert:
0: geschlossen1: gekippt2: geöffnet
Benzer
Die Fahrzeugseite verwendet:
Benz_Batterie: Batteriestand in ProzentBenz_Reichweite_km: vom Fahrzeug gemeldete Restreichweitealias.0.Hintergasse.Ich.GPS: Anwesenheitsfreigabemercedesme.0.W1KFJ1DBXVJ068659.state.doorlockstatusvehicle.intValue: Verriegelungszustand (2verriegelt,0entriegelt)mercedesme.0.W1KFJ1DBXVJ068659.state.precondNow.boolValue: tatsächlicher Zustand der Vorklimatisierungjavascript.0.Variablen.Vorklimatisation: Schaltbefehl für die Vorklimatisierung
Ist der GPS-Datenpunkt false, werden die Seiten Benzer und ING auf allen
Displays vollständig aus Navigation und Seitenfolge ausgeblendet. Eine gerade
geöffnete dieser Seiten wechselt auf die erste verfügbare Seite. Die gespeicherte
Displaykonfiguration bleibt erhalten, sodass beide Seiten bei true automatisch
wieder in ihrer bisherigen Reihenfolge erscheinen.
Innerhalb der Fahrzeugkachel werden Verriegelungsstatus, Fahrzeugbild,
Fahrtenanzahl und Ladeempfehlung angezeigt. Der Ventilator oben mittig ist bei
aktiver Vorklimatisierung grün und animiert, im ausgeschalteten Zustand grau.
Ein Druck schaltet über javascript.0.Variablen.Vorklimatisation; anschließend
wird der Mercedes-IST-Datenpunkt wiederholt geprüft, bevor die Anzeige den neuen
Zustand übernimmt. Die Warnung
WI-Erreichbarkeit kritisch! erscheint bei höchstens 9 % Batterie oder höchstens
70 km gemeldeter Restreichweite.
Berechnung der möglichen Fahrten
Grundlagen:
- nutzbare Batteriekapazität: 85 kWh
- angenommener Verbrauch: 16,5 kWh/100 km
- einfacher Arbeitsweg: 50 km
- angenommener Reichweitenverlust: 10 km je Nacht
- Arbeitstage: Montag bis Freitag; geladen wird in der Firma, aber nicht automatisch bei jeder Ankunft
Aus dem Batteriestand wird zunächst eine rechnerische Reichweite bestimmt:
Reichweite aus Batterie = Batteriestand / 100 × 85 kWh / 16,5 kWh × 100
Für die weitere Planung wird konservativ der kleinere Wert aus dieser
rechnerischen Reichweite und Benz_Reichweite_km verwendet. Davon wird die
Nachtreserve abgezogen: grundsätzlich mindestens eine Nacht, freitags nach dem
morgendlichen Arbeitsweg drei Nächte bis Montag und samstags zwei Nächte. Die
verbleibende Reichweite wird durch 50 km geteilt und auf vollständige Fahrten
abgerundet.
Die Ladeanzeige oben rechts verwendet diese Logik:
- grüner Haken ohne Text: mindestens drei vollständige Fahrten; alles ist gut
- gelber Haken mit
IN FIRMA LADEN: ein oder zwei vollständige Fahrten - roter Haken mit
VORHER LADEN: keine vollständige 50-km-Fahrt gewährleistet
Fahrzeugwerte simulieren
Für Darstellungstests lassen sich Batterie und Reichweite ausschließlich im Browser überschreiben. Die echten Datenpunkte werden dabei nicht verändert:
http://10.0.1.125:3000/?simBattery=8
http://10.0.1.125:3000/?simRange=65
http://10.0.1.125:3000/?simBattery=8&simRange=65
Bei Displayprofilen bleibt der Parameter display erhalten, zum Beispiel:
http://10.0.1.125:3000/?display=OG&simBattery=25&simRange=138
Ohne simBattery und simRange werden ausschließlich die Live-Werte genutzt.
Screensaver und Bedienung
Der Screensaver zeigt Uhrzeit und Datum, Wetterwerte und – sofern vorhanden – sichtbare Kalenderereignisse von heute und morgen. Das Wetterlogo liegt zentral im Hintergrund, während Luftfeuchte und Temperatur darüber angeordnet sind. Wischen wechselt zwischen den für das Display aktivierten Seiten. Die Versionsnummer unten rechts kann etwa 1,2 Sekunden gehalten werden, um das Dashboard mit einem Cache-Busting-Parameter neu zu laden.
Installation
Voraussetzungen: Node.js ab Version 22.13.0, Corepack und Git.
sudo corepack enable
corepack prepare pnpm@11.19.0 --activate
cd ~
git clone https://git.hintergasse.de/hubobel/shelly_test.git
cd shelly_test
pnpm install --frozen-lockfile
Die nicht versionierte .env.local mit den Zugangsdaten in das Projektverzeichnis kopieren und schützen:
chmod 600 /home/hubobel/shelly_test/.env.local
pnpm build
Für die durch Authentik geschützte Energie-API muss in .env.local dasselbe
Service-Token wie im Energie-Projekt hinterlegt sein:
ENERGY_API_URL=http://10.0.1.125:8321/api/data
ENERGY_API_TOKEN=replace-with-the-same-random-token
Für die Kalenderseite werden URL und derselbe interne API-Schlüssel des
gcalendar-gateway ergänzt:
CALENDAR_GATEWAY_URL=http://127.0.0.1:8340
CALENDAR_GATEWAY_API_KEY=replace-with-the-same-random-key
systemd-Dienst einrichten
sudo tee /etc/systemd/system/shelly-dashboard.service >/dev/null <<'EOF'
[Unit]
Description=Shelly Wall Display Dashboard
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=hubobel
Group=hubobel
WorkingDirectory=/home/hubobel/shelly_test
Environment=NODE_ENV=production
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=/usr/bin/pnpm start:lan
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now shelly-dashboard
sudo systemctl status shelly-dashboard --no-pager
In ShellyElevate diese Dashboard-URL eintragen:
http://10.0.1.125:3000/
Mehrere Displays konfigurieren
Unter http://10.0.1.125:3000/admin/displays lassen sich beliebig viele
Wall Displays verwalten. Pro Display werden Geräte-IP, verfügbare Seiten,
deren Reihenfolge und die Startseite festgelegt. Die Verwaltung erzeugt eine
eindeutige URL wie http://10.0.1.125:3000/?display=EG und kann sie direkt an
ShellyElevate übertragen.
Die automatische Seitenrotation ist auf allen Displays standardmäßig aktiv. Pro Display kann eine Seitenzeit von 15, 30, 60 oder 120 Sekunden gewählt werden. Sie folgt der gespeicherten Seitenreihenfolge und überspringt deaktivierte oder dynamisch ausgeblendete Seiten. Während Screensaver, Detail-Overlay, Haltevorgang oder laufender Rollladensteuerung wird nicht weitergeschaltet.
Ein normaler Druck auf einen Reiter in der unteren Navigation öffnet die Seite, startet das Zeitintervall neu und lässt die Rotation weiterlaufen. Dabei wird kein Haltebalken eingeblendet. Bleibt der Finger mindestens 300 ms liegen, startet der 1,5-Sekunden-Balken am oberen Displayrand und zeigt den Haltevorgang, öffnet anschließend die gewählte Seite und hält die Rotation dort an. Während der Fixierung werden alle anderen Reiter deutlich ausgegraut. Ein normaler Druck auf einen beliebigen Reiter startet die Rotation wieder und stellt alle Reiter normal dar. Eine zusätzliche Textmeldung wird beim Fixieren nicht eingeblendet.
Jede Bedienung des Displays setzt bei laufender Rotation die Seitenzeit neu – insbesondere auch Rollladen-, Schalter- und Fensteraktionen, Wischgesten sowie das Öffnen oder Schließen eines Overlays. Eine per langem Druck fixierte Seite bleibt davon unberührt und weiterhin angehalten.
Ist die Kalenderseite aktiv, lässt sich zusätzlich pro Display auswählen, welche eigenen und abonnierten Google-Kalender berücksichtigt werden.
Die Profile liegen ausschließlich auf dem Dashboardserver in
data/display-profiles.json. Die Datei bleibt bei git pull erhalten und wird
nicht in Git eingecheckt. Der mit pnpm start:lan gestartete lokale
Konfigurationsdienst ist nur über 127.0.0.1 erreichbar.
Update-Script einmalig installieren
sudo install -m 755 /home/hubobel/shelly_test/tools/shelly-update /usr/local/bin/shelly-update
Danach synchronisiert jeder Lauf den Kurzbefehl automatisch mit der im
Repository gepflegten Version. Am Ende eines erfolgreichen Updates gibt er die
Adminseite http://10.0.1.125:3000/admin als anklickbaren Terminal-Link aus.
Update
Auf dem Produktionsserver genügt anschließend:
shelly-update
Danach die Versionsnummer unten rechts auf dem Shelly etwa 1,2 Sekunden gedrückt halten. Das Dashboard lädt den aktuellen Stand neu.


