NEWS
Google Material 3 / Material You - Vis2
-
Ich habe mich mal ordentlich mit den Designrichtlinien von Google Material You oder auch Material 3 auseinandergesetzt. https://m3.material.io/
Meine letzte Visualisierung hatte auch schon anleihen von diesem Design, aber damals hatte ich den ganzen Look in Photoshop gestaltet. Das war natürlich sehr unflexibel. https://forum.iobroker.net/topic/51388/vorstellung-vis-in-materialyou-less-is-more
Jetzt habe ich mit Hilfe von Gemini und claude.ai das ganze auf Vis2 neu aufgebaut. Wie schon bei meinen letzten Visualisierungen, ging es mir auch dieses Mal nicht darum möglichst viele meiner drölfmilliarden Datenpunkte aufs Tablet zu bringen. Ich wollte mich vielmehr die am häufigsten genutzen Elemente beschränken. Am beliebtesten ist in meiner Familie übrigens die Uhrzeit und das Wetter. Aber das ist erstmal egal. :-)
Ich habe einen Bereich mit Wetter, Uhrzeit und Warnungen, die sind am rechten Bildrand immer zu sehen. Der Rest des Bildes wechselt wenn man oben ein Tab auswählt. Unten Links sind die anwesenden Personen zu sehen und ein Taster für Gäste.
Die Farben werden entweder über ein JSON von https://material-foundation.github.io/material-theme-builder/ eingestellt, oder man aktiviert einfach ein beliebiges Hintergrundbild und dann werden die Farben nach dem gleichen Verfahren wie beim material-theme-builder generiert. Es gibt auch einen Nachmodus, der sich nach Sonnenuntergang aktiviert.
Alle besteht nur aus HTML-widgets. Manche habe direkt den korrekten Inhalt (z.B. das Wetter-Widget), andere bekommen über einen TypeScript-File den korrekte Inhalt in einen Datenpunkt gelegt.
Weil ich selber nur in sehr begrenztem Umfang programmieren kann, hat das ganze auch fast eine Woche gedauert. Immer wieder musste ich warten, weil die Tokens für die genannten AI-Dienste verbraucht waren. Aber ich bin mit dem Ergebnis sehr zufrieden.


(

-
Hier habe ich noch mal eine etwas ausführlichere, technischere Erklärung:
Material You (M3) Theme Engine für ioBroker vis-2 — Technik-Deep-Dive
Ich möchte hier meine Erfahrungen teilen, wie ich ein vollständig dynamisches Material Design 3 (Material You) Dashboard in ioBroker vis-2 umgesetzt habe. Das Ganze besteht aus einem zentralen Theme Master und mehreren HTML-Renderern, die als TypeScript-Skripte im JavaScript-Adapter laufen und ihr fertiges HTML in Datenpunkte schreiben. vis-2 zeigt diese dann über
basic-htmlWidgets an.Vielleicht hilft es dem einen oder anderen, der auch ein modernes, einheitliches Dashboard bauen möchte.
1. Die Grundidee: CSS-Variablen als zentrale Farbquelle
Der wichtigste Baustein des gesamten Systems ist ein einziger Datenpunkt (
0_userdata.0.dashboard.themeCSS), der ein<style>-Tag mit CSS Custom Properties enthält. Dieser Datenpunkt wird von einem zentralen Skript — dem Theme Master — befüllt und von allen anderen Renderern konsumiert.Das CSS sieht so aus:
:root { --m3-primary: #3d6838; --m3-on-primary: #ffffff; --m3-primary-container: #bef0b2; --m3-surface-container-low: #f3f4ed; /* ... ca. 25 weitere M3-Tokens ... */ --m3-bg-image: url('/vis.0/main/img/wallpaper.jpg'); }Warum das so mächtig ist: Jeder Renderer referenziert ausschließlich
var(--m3-primary)etc. — nie feste Farbwerte. Wenn der Theme Master die Variablen ändert, passt sich alles sofort an. Dark Mode, Farbwechsel, Wallpaper — ein einziger Datenpunkt steuert das komplette Look & Feel.Tipp für Nachbauer
In vis-2 bindet ihr das CSS über ein
basic-htmlWidget ein, das den DatenpunktthemeCSSanzeigt. Das Widget kann unsichtbar sein — es injiziert nur das<style>-Tag in den DOM.
2. Der Theme Master — Drei Wege zur Farbe
Der Theme Master (V7) unterstützt drei Farbquellen mit einer klaren Prioritätskette:
Priorität 1 — JSON-Import (Google Material Theme Builder):
Man kann auf material-foundation.github.io ein Theme zusammenklicken und das JSON exportieren. Das Skript liestschemes.darkbzw.schemes.lightaus und generiert daraus die CSS-Variablen. Das ist der schnellste Weg zu einem professionellen Farbschema.Priorität 2 — Bildanalyse (Monet-Algorithmus):
Wenn kein JSON aktiv ist, aber ein Hintergrundbild gesetzt wurde, wird die Dominant-Farbe aus dem Bild extrahiert — genau wie Android es bei Material You macht. Dafür werden zwei NPM-Pakete verwendet:jimp— Bild laden und auf 128px verkleinern (Performance!)@material/material-color-utilities— Die offizielle Google-Library mitQuantizerCelebiundScorezur Farbextraktion, undthemeFromSourceColorzur Generierung aller M3-Tonal-Paletten
Das Bild wird pixelweise gescannt, die Farben quantisiert, und die beste Farbe wird als Seed für das gesamte M3-Schema verwendet. Das ist exakt der gleiche Algorithmus, den Android 12+ nutzt.
Ein entscheidender Punkt, der in vielen Tutorials fehlt: Die Surface-Container-Farben (die 5 Abstufungen von
surfaceContainerLowestbissurfaceContainerHighest) werden vonthemeFromSourceColornicht korrekt für alle Abstufungen geliefert. Deshalb werden die Tonal Palettes manuell mit den korrekten M3-Tone-Werten überschrieben:// Dark Mode Surface Tones (aus der M3-Spezifikation) scheme.surfaceContainerLowest = neutralPalette.tone(4); scheme.surfaceContainerLow = neutralPalette.tone(10); scheme.surfaceContainer = neutralPalette.tone(12); scheme.surfaceContainerHigh = neutralPalette.tone(17); scheme.surfaceContainerHighest = neutralPalette.tone(22);Priorität 3 — Hardcoded Fallback:
Wenn weder JSON noch Bild verfügbar sind, greift ein eingebautes Default-Theme (ein dezentes Grün).Tipp für Nachbauer
Die NPM-Module müssen im JavaScript-Adapter unter Zusätzliche NPM-Module eingetragen werden:
@material/material-color-utilities@0.2.7, jimp@0.22.10. Neuere Versionen von Jimp haben eine andere API — bei der Version bleiben!
3. Automatischer Dark/Light-Mode via Astro
Der Theme Master kann den Dark Mode automatisch nach Sonnenstand umschalten. Dafür wird die ioBroker-eigene Astro-Funktion genutzt:
schedule({astro: "sunrise"}, checkAstro); schedule({astro: "sunset"}, checkAstro);Die Funktion
isAstroDay()prüft, ob die Sonne über dem Horizont steht, und setzt dendarkMode-Datenpunkt entsprechend. Das Schöne: Man kann den Auto-Modus per Schalter deaktivieren und manuell umschalten — z.B. wenn man abends im Hellen auf der Terrasse sitzt.
4. Das Renderer-Pattern — HTML in Datenpunkte
Jeder Bereich des Dashboards (Licht, Heizung, Beschattung, Favoriten, Anwesenheit, Alerts…) hat ein eigenes TypeScript-Skript, das nach dem gleichen Muster arbeitet:
- M3-Farbobjekt definieren — aber nur mit
var()-Referenzen, nie mit festen Farben - HTML als String zusammenbauen — mit Inline-Styles, die die CSS-Variablen nutzen
- In einen Datenpunkt schreiben (
setState(DP_HTML, html, true)) - Auf Änderungen der Geräte-Datenpunkte subscriben und bei Änderung neu rendern
const M3 = { primary: 'var(--m3-primary)', onPrimary: 'var(--m3-on-primary)', primaryContainer: 'var(--m3-primary-container)', surfaceContainerLow: 'var(--m3-surface-container-low)', // ... };Warum Inline-Styles und kein Stylesheet?
Weil vis-2 die HTML-Widgets als isolierte Fragmente rendert. Ein zentrales Stylesheet wäre schwierig zu managen. Mit Inline-Styles, dievar()nutzen, bekommt man das Beste aus beiden Welten: Die Farben sind zentral gesteuert (über die CSS-Variablen im:root), aber die Styles sind im HTML-Fragment selbst enthalten.Tipp für Nachbauer
Jeder Renderer hat ein
const M3 = { ... }Objekt am Anfang. Wenn ihr neue Renderer baut, kopiert dieses Objekt einfach — es ist bei allen gleich. So habt ihr automatisch die Theme-Anbindung.
5. Clevere UI-Tricks im Detail
5.1 Live Color-Mix bei Slidern
Die Licht- und Beschattungs-Karten werden beim Dimmen dynamisch eingefärbt. Das funktioniert mit CSS
color-mix():const mixPct = Math.round(20 + (percentage * 0.8)); const bg = active ? `color-mix(in srgb, ${M3.primaryContainer} ${mixPct}%, ${M3.surfaceContainerLow})` : M3.surfaceContainerLow;Bei 0% ist die Karte grau (Surface), bei 100% in der Akzentfarbe (Primary Container). Der Übergang ist fließend. Das gibt ein haptisches Feedback, das man sonst nur von nativen Apps kennt.
5.2 M3 Ripple-Effekt
Jede klickbare Karte hat einen Material-Ripple-Effekt — komplett in Vanilla JS, ohne Framework:
const rippleJS = `(function(e,el){ var d = Math.max(el.clientWidth, el.clientHeight); var rect = el.getBoundingClientRect(); var c = document.createElement('span'); c.style.width = c.style.height = d + 'px'; c.style.left = (e.clientX - rect.left - d/2) + 'px'; c.style.top = (e.clientY - rect.top - d/2) + 'px'; c.style.position = 'absolute'; c.style.borderRadius = '50%'; c.style.backgroundColor = '${rippleColor}'; c.style.opacity = '0.15'; c.style.transform = 'scale(0)'; c.style.animation = 'm3-ripple-anim 0.5s linear'; el.appendChild(c); setTimeout(function(){c.remove()}, 500); })(event, this)`;Das wird als
onmousedownundontouchstartdirekt in den HTML-String geschrieben. Kein externen JS nötig.5.3 Filled/Outlined Icon-Umschaltung
Die Tab-Navigation nutzt ein Konzept aus Material You: Aktive Tabs zeigen ein gefülltes Icon, inaktive ein Outline-Icon. Das wird mit zwei übereinander liegenden SVG-Pfaden gelöst, deren
fillper vis-Binding umgeschaltet wird:<!-- Gefüllter Pfad: nur sichtbar wenn aktiv --> <path fill="{a:active_tab; a === 0 ? 'var(--m3-on-tertiary-container)' : 'transparent'}" d="M12 17.27L18.18 21..."/> <!-- Outline-Pfad: nur sichtbar wenn inaktiv --> <path fill="{a:active_tab; a === 0 ? 'transparent' : 'var(--m3-on-surface-variant)'}" d="M22 9.24l-7.19..."/>Das ist eine elegante Lösung ohne JavaScript — rein über vis-Bindings.
5.4 Heizungs-Karten mit Amber-Logik
Die Heizungskarten haben drei Zustände: inaktiv (grau), aktiv (Primary), und „Ventil offen, aber Heizung aus" (Amber/Warning). Das gibt sofortiges visuelles Feedback, ob die Heizung auch wirklich heizt oder nur das Ventil offen steht.
5.5 Circadian-Flurbeleuchtung
Ein separates Skript berechnet anhand der Astro-Daten (Sonnenaufgang, Golden Hour, Sonnenuntergang, Dämmerung) die passende Farbtemperatur und Helligkeit für das Flurlicht. Tagsüber: 6000K bei 70%. Nachts: 2200K bei 6%. Dazwischen wird linear gefaded. Getriggert wird durch Präsenz-, Tür- und Bewegungssensoren.
6. Wallpaper als Hintergrund — vis-2 überschreiben
vis-2 setzt seinen eigenen Hintergrund. Um ein dynamisches Wallpaper zu nutzen, überschreibt der Theme Master aggressiv alle möglichen Container:
body, html, #root, #vis_container, .vis-view, .app-container { background-image: var(--m3-bg-image) !important; background-size: cover !important; background-position: center center !important; background-attachment: fixed !important; background-color: transparent !important; }Das Wallpaper wird als Pfad im Datenpunkt
themeImagePathgesetzt (z.B.vis.0/main/img/wallpaper.jpg). Es wird unabhängig von der Farbquelle angezeigt — man kann also ein JSON-Theme haben und trotzdem ein Wallpaper.
7. Weitere Automatisierungen rund ums Dashboard
- Dashboard Auto-Return: Nach 5 Minuten Inaktivität springt der Tab automatisch zurück auf die Favoriten-Seite (Kiosk-Modus).
- Gute-Nacht-Routine: Ein Button-Taster löst eine Routine aus, die alle Lichter aus, das Flurlicht an und die Haustür verriegelt. Geräte werden zeitversetzt geschaltet (
setStateDelayedmit 150ms Abstand), um den Duty Cycle der Funk-Bridges zu schonen. - Alert-System: Warnungen (Sicherheit, Komfort, Info) werden über einen zentralen Datenpunkt getriggert, mit Prefix-Codierung für Typ und Dismiss-Verhalten (
EM:= Error/Manuell,CT:= Comfort/Timeout, etc.).
8. Zusammenfassung — Was braucht man?
Komponente Zweck Theme Master (JS-Skript) Erzeugt CSS-Variablen aus JSON, Bild oder Fallback themeCSSDatenpunktEnthält das <style>-Tag, wird von vis-2 angezeigtPro Bereich ein Renderer (JS/TS) Erzeugt HTML mit var()-ReferenzenPro Bereich ein basic-htmlWidgetZeigt den HTML-Datenpunkt an NPM: @material/material-color-utilitiesM3-Farbberechnung NPM: jimpBildanalyse für Monet-Algorithmus Die Architektur in einem Satz: Ein zentrales Skript schreibt CSS-Variablen in einen Datenpunkt, alle anderen Skripte rendern HTML, das diese Variablen nutzt, und vis-2 zeigt das Ganze an.
Ich hoffe, das hilft jemandem weiter! Bei Fragen gerne melden.
-
Hier habe ich noch mal eine etwas ausführlichere, technischere Erklärung:
Material You (M3) Theme Engine für ioBroker vis-2 — Technik-Deep-Dive
Ich möchte hier meine Erfahrungen teilen, wie ich ein vollständig dynamisches Material Design 3 (Material You) Dashboard in ioBroker vis-2 umgesetzt habe. Das Ganze besteht aus einem zentralen Theme Master und mehreren HTML-Renderern, die als TypeScript-Skripte im JavaScript-Adapter laufen und ihr fertiges HTML in Datenpunkte schreiben. vis-2 zeigt diese dann über
basic-htmlWidgets an.Vielleicht hilft es dem einen oder anderen, der auch ein modernes, einheitliches Dashboard bauen möchte.
1. Die Grundidee: CSS-Variablen als zentrale Farbquelle
Der wichtigste Baustein des gesamten Systems ist ein einziger Datenpunkt (
0_userdata.0.dashboard.themeCSS), der ein<style>-Tag mit CSS Custom Properties enthält. Dieser Datenpunkt wird von einem zentralen Skript — dem Theme Master — befüllt und von allen anderen Renderern konsumiert.Das CSS sieht so aus:
:root { --m3-primary: #3d6838; --m3-on-primary: #ffffff; --m3-primary-container: #bef0b2; --m3-surface-container-low: #f3f4ed; /* ... ca. 25 weitere M3-Tokens ... */ --m3-bg-image: url('/vis.0/main/img/wallpaper.jpg'); }Warum das so mächtig ist: Jeder Renderer referenziert ausschließlich
var(--m3-primary)etc. — nie feste Farbwerte. Wenn der Theme Master die Variablen ändert, passt sich alles sofort an. Dark Mode, Farbwechsel, Wallpaper — ein einziger Datenpunkt steuert das komplette Look & Feel.Tipp für Nachbauer
In vis-2 bindet ihr das CSS über ein
basic-htmlWidget ein, das den DatenpunktthemeCSSanzeigt. Das Widget kann unsichtbar sein — es injiziert nur das<style>-Tag in den DOM.
2. Der Theme Master — Drei Wege zur Farbe
Der Theme Master (V7) unterstützt drei Farbquellen mit einer klaren Prioritätskette:
Priorität 1 — JSON-Import (Google Material Theme Builder):
Man kann auf material-foundation.github.io ein Theme zusammenklicken und das JSON exportieren. Das Skript liestschemes.darkbzw.schemes.lightaus und generiert daraus die CSS-Variablen. Das ist der schnellste Weg zu einem professionellen Farbschema.Priorität 2 — Bildanalyse (Monet-Algorithmus):
Wenn kein JSON aktiv ist, aber ein Hintergrundbild gesetzt wurde, wird die Dominant-Farbe aus dem Bild extrahiert — genau wie Android es bei Material You macht. Dafür werden zwei NPM-Pakete verwendet:jimp— Bild laden und auf 128px verkleinern (Performance!)@material/material-color-utilities— Die offizielle Google-Library mitQuantizerCelebiundScorezur Farbextraktion, undthemeFromSourceColorzur Generierung aller M3-Tonal-Paletten
Das Bild wird pixelweise gescannt, die Farben quantisiert, und die beste Farbe wird als Seed für das gesamte M3-Schema verwendet. Das ist exakt der gleiche Algorithmus, den Android 12+ nutzt.
Ein entscheidender Punkt, der in vielen Tutorials fehlt: Die Surface-Container-Farben (die 5 Abstufungen von
surfaceContainerLowestbissurfaceContainerHighest) werden vonthemeFromSourceColornicht korrekt für alle Abstufungen geliefert. Deshalb werden die Tonal Palettes manuell mit den korrekten M3-Tone-Werten überschrieben:// Dark Mode Surface Tones (aus der M3-Spezifikation) scheme.surfaceContainerLowest = neutralPalette.tone(4); scheme.surfaceContainerLow = neutralPalette.tone(10); scheme.surfaceContainer = neutralPalette.tone(12); scheme.surfaceContainerHigh = neutralPalette.tone(17); scheme.surfaceContainerHighest = neutralPalette.tone(22);Priorität 3 — Hardcoded Fallback:
Wenn weder JSON noch Bild verfügbar sind, greift ein eingebautes Default-Theme (ein dezentes Grün).Tipp für Nachbauer
Die NPM-Module müssen im JavaScript-Adapter unter Zusätzliche NPM-Module eingetragen werden:
@material/material-color-utilities@0.2.7, jimp@0.22.10. Neuere Versionen von Jimp haben eine andere API — bei der Version bleiben!
3. Automatischer Dark/Light-Mode via Astro
Der Theme Master kann den Dark Mode automatisch nach Sonnenstand umschalten. Dafür wird die ioBroker-eigene Astro-Funktion genutzt:
schedule({astro: "sunrise"}, checkAstro); schedule({astro: "sunset"}, checkAstro);Die Funktion
isAstroDay()prüft, ob die Sonne über dem Horizont steht, und setzt dendarkMode-Datenpunkt entsprechend. Das Schöne: Man kann den Auto-Modus per Schalter deaktivieren und manuell umschalten — z.B. wenn man abends im Hellen auf der Terrasse sitzt.
4. Das Renderer-Pattern — HTML in Datenpunkte
Jeder Bereich des Dashboards (Licht, Heizung, Beschattung, Favoriten, Anwesenheit, Alerts…) hat ein eigenes TypeScript-Skript, das nach dem gleichen Muster arbeitet:
- M3-Farbobjekt definieren — aber nur mit
var()-Referenzen, nie mit festen Farben - HTML als String zusammenbauen — mit Inline-Styles, die die CSS-Variablen nutzen
- In einen Datenpunkt schreiben (
setState(DP_HTML, html, true)) - Auf Änderungen der Geräte-Datenpunkte subscriben und bei Änderung neu rendern
const M3 = { primary: 'var(--m3-primary)', onPrimary: 'var(--m3-on-primary)', primaryContainer: 'var(--m3-primary-container)', surfaceContainerLow: 'var(--m3-surface-container-low)', // ... };Warum Inline-Styles und kein Stylesheet?
Weil vis-2 die HTML-Widgets als isolierte Fragmente rendert. Ein zentrales Stylesheet wäre schwierig zu managen. Mit Inline-Styles, dievar()nutzen, bekommt man das Beste aus beiden Welten: Die Farben sind zentral gesteuert (über die CSS-Variablen im:root), aber die Styles sind im HTML-Fragment selbst enthalten.Tipp für Nachbauer
Jeder Renderer hat ein
const M3 = { ... }Objekt am Anfang. Wenn ihr neue Renderer baut, kopiert dieses Objekt einfach — es ist bei allen gleich. So habt ihr automatisch die Theme-Anbindung.
5. Clevere UI-Tricks im Detail
5.1 Live Color-Mix bei Slidern
Die Licht- und Beschattungs-Karten werden beim Dimmen dynamisch eingefärbt. Das funktioniert mit CSS
color-mix():const mixPct = Math.round(20 + (percentage * 0.8)); const bg = active ? `color-mix(in srgb, ${M3.primaryContainer} ${mixPct}%, ${M3.surfaceContainerLow})` : M3.surfaceContainerLow;Bei 0% ist die Karte grau (Surface), bei 100% in der Akzentfarbe (Primary Container). Der Übergang ist fließend. Das gibt ein haptisches Feedback, das man sonst nur von nativen Apps kennt.
5.2 M3 Ripple-Effekt
Jede klickbare Karte hat einen Material-Ripple-Effekt — komplett in Vanilla JS, ohne Framework:
const rippleJS = `(function(e,el){ var d = Math.max(el.clientWidth, el.clientHeight); var rect = el.getBoundingClientRect(); var c = document.createElement('span'); c.style.width = c.style.height = d + 'px'; c.style.left = (e.clientX - rect.left - d/2) + 'px'; c.style.top = (e.clientY - rect.top - d/2) + 'px'; c.style.position = 'absolute'; c.style.borderRadius = '50%'; c.style.backgroundColor = '${rippleColor}'; c.style.opacity = '0.15'; c.style.transform = 'scale(0)'; c.style.animation = 'm3-ripple-anim 0.5s linear'; el.appendChild(c); setTimeout(function(){c.remove()}, 500); })(event, this)`;Das wird als
onmousedownundontouchstartdirekt in den HTML-String geschrieben. Kein externen JS nötig.5.3 Filled/Outlined Icon-Umschaltung
Die Tab-Navigation nutzt ein Konzept aus Material You: Aktive Tabs zeigen ein gefülltes Icon, inaktive ein Outline-Icon. Das wird mit zwei übereinander liegenden SVG-Pfaden gelöst, deren
fillper vis-Binding umgeschaltet wird:<!-- Gefüllter Pfad: nur sichtbar wenn aktiv --> <path fill="{a:active_tab; a === 0 ? 'var(--m3-on-tertiary-container)' : 'transparent'}" d="M12 17.27L18.18 21..."/> <!-- Outline-Pfad: nur sichtbar wenn inaktiv --> <path fill="{a:active_tab; a === 0 ? 'transparent' : 'var(--m3-on-surface-variant)'}" d="M22 9.24l-7.19..."/>Das ist eine elegante Lösung ohne JavaScript — rein über vis-Bindings.
5.4 Heizungs-Karten mit Amber-Logik
Die Heizungskarten haben drei Zustände: inaktiv (grau), aktiv (Primary), und „Ventil offen, aber Heizung aus" (Amber/Warning). Das gibt sofortiges visuelles Feedback, ob die Heizung auch wirklich heizt oder nur das Ventil offen steht.
5.5 Circadian-Flurbeleuchtung
Ein separates Skript berechnet anhand der Astro-Daten (Sonnenaufgang, Golden Hour, Sonnenuntergang, Dämmerung) die passende Farbtemperatur und Helligkeit für das Flurlicht. Tagsüber: 6000K bei 70%. Nachts: 2200K bei 6%. Dazwischen wird linear gefaded. Getriggert wird durch Präsenz-, Tür- und Bewegungssensoren.
6. Wallpaper als Hintergrund — vis-2 überschreiben
vis-2 setzt seinen eigenen Hintergrund. Um ein dynamisches Wallpaper zu nutzen, überschreibt der Theme Master aggressiv alle möglichen Container:
body, html, #root, #vis_container, .vis-view, .app-container { background-image: var(--m3-bg-image) !important; background-size: cover !important; background-position: center center !important; background-attachment: fixed !important; background-color: transparent !important; }Das Wallpaper wird als Pfad im Datenpunkt
themeImagePathgesetzt (z.B.vis.0/main/img/wallpaper.jpg). Es wird unabhängig von der Farbquelle angezeigt — man kann also ein JSON-Theme haben und trotzdem ein Wallpaper.
7. Weitere Automatisierungen rund ums Dashboard
- Dashboard Auto-Return: Nach 5 Minuten Inaktivität springt der Tab automatisch zurück auf die Favoriten-Seite (Kiosk-Modus).
- Gute-Nacht-Routine: Ein Button-Taster löst eine Routine aus, die alle Lichter aus, das Flurlicht an und die Haustür verriegelt. Geräte werden zeitversetzt geschaltet (
setStateDelayedmit 150ms Abstand), um den Duty Cycle der Funk-Bridges zu schonen. - Alert-System: Warnungen (Sicherheit, Komfort, Info) werden über einen zentralen Datenpunkt getriggert, mit Prefix-Codierung für Typ und Dismiss-Verhalten (
EM:= Error/Manuell,CT:= Comfort/Timeout, etc.).
8. Zusammenfassung — Was braucht man?
Komponente Zweck Theme Master (JS-Skript) Erzeugt CSS-Variablen aus JSON, Bild oder Fallback themeCSSDatenpunktEnthält das <style>-Tag, wird von vis-2 angezeigtPro Bereich ein Renderer (JS/TS) Erzeugt HTML mit var()-ReferenzenPro Bereich ein basic-htmlWidgetZeigt den HTML-Datenpunkt an NPM: @material/material-color-utilitiesM3-Farbberechnung NPM: jimpBildanalyse für Monet-Algorithmus Die Architektur in einem Satz: Ein zentrales Skript schreibt CSS-Variablen in einen Datenpunkt, alle anderen Skripte rendern HTML, das diese Variablen nutzt, und vis-2 zeigt das Ganze an.
Ich hoffe, das hilft jemandem weiter! Bei Fragen gerne melden.
vis 2 nutzt ja eigentlich die mui bibliothek, welche react komponenten auf basis des google material konzepts anbietet.
das mit dem farbschema war hier auch immer wieder mal ein thema.
ich weiß du nutzt das eher mit server side rendering,
aber wenn du magst kannst du die lösung mal liken,
dann stehen die cssVariablen (mit prefix mui-) auch im vis-2 mit zur Verfügung.https://github.com/ioBroker/ioBroker.vis-2/issues/581
damit könnte dann jeder sein eigenes theme zusammenbauen und müsste nicht in allen einstellungen immer wieder die farben neu definieren, bzw kommt man an manche einstellungen da nicht dran.
-
Freut mich, dass es euch gefällt. Aber mein Wissen ist tatsächlich hier mehr konzeptionell: ich habe das ganze ja von Gemini schreiben lassen. Ich habe einfach beschrieben was ich haben möchte, welche Datenpunkte ich dazu habe (am besten natürlich alles über alias und userdata) und dann wieder korrigieren lassen. Immer wieder musste ich auch bereits fertiggestellte Scripte wieder hochladen, damit Gemini die Zusammenhänge nicht vergisst, aber so hat es langsam funktioniert. Auch die Material 3 Unterlagen von Google habe ich mir recht ausführlich angeschaut, damit ich Gemini auf Fehler aufmerksam machen konnte.
Also viel so in dem Stil "So, dass ist der Skript meiner Heizungsseite, jetzt füge bitte noch die Funktion XY ein." - "der neue Skript hat noch nicht funktioniert, ich habe folgenden Fehler: ..." - "jetzt klappts. bitte ergänze noch diese Funktion"...Wobei man natürlich schon ein bisschen verstehen muss, wie TS und JS Dateien aufgebaut sind, wie der Vis-Editor bedient wird etc. Aber letztlich kann einem die KI natürlich auch bei fast allen Problemen helfen.