Kacheln nicht abrufbar: '
@@ -715,6 +769,17 @@ function kachelnBinden() {
}
});
+ /*
+ * Die Vorschau folgt dem Tippen. Neu gezeichnet wird dafuer nicht - das
+ * naehme dem Feld nach jedem Buchstaben den Cursor.
+ */
+ liste.addEventListener("input", function (ereignis) {
+ const feld = ereignis.target.closest('[data-feld="icon"]');
+ if (!feld) return;
+ const schau = feld.parentElement.querySelector(".kw-symbol-schau");
+ if (schau) schau.innerHTML = kachelSymbolVorschau(feld.value.trim());
+ });
+
const neuLaden = document.getElementById("kachelNeuLaden");
if (neuLaden) neuLaden.addEventListener("click", kachelnHolen);
}
diff --git a/restricted/kacheln.php b/restricted/kacheln.php
index e013db4..3654b95 100644
--- a/restricted/kacheln.php
+++ b/restricted/kacheln.php
@@ -18,7 +18,10 @@
* einheit sonst die Einheit, die hinter der Zahl steht
* stellen Nachkommastellen (0-3)
* gross die Zahl steht gross auf der Kachel
- * icon Symbol vor der Zahl, siehe kachelIcon() in rooms.php
+ * icon Symbol vor der Zahl: der Name eines Bootstrap-Icons ohne
+ * das "bi-" davor ("thermometer-half"). Erlaubt ist jedes,
+ * das im Stylesheet steht - siehe bootstrapIcons() in
+ * rooms.php; kachelSymbole() ist nur die Vorschlagsliste.
*
* Die Tabelle darf fehlen. Ist sie nicht angelegt (solarLog_kacheln.sql), so
* verhält sich alles wie vorher, statt dass die Startseite mit einem
@@ -38,17 +41,97 @@ require_once(__DIR__ . "/costs.php"); // solarDb()
/** Höchstens drei Werte je Kachel - mehr passt nicht auf 24 x 19 Einheiten. */
const KACHEL_MAX = 3;
-/** Symbole, die vor einer Zahl stehen dürfen. Schlüssel wie in kachelIcon(). */
+/**
+ * Vorschläge für das Symbol vor einer Zahl.
+ *
+ * Erlaubt ist jedes Bootstrap-Icon (bootstrapIcons() in rooms.php liest sie
+ * aus dem Stylesheet, es sind gut zweitausend). Diese Liste ist deshalb keine
+ * Beschränkung, sondern eine Abkürzung: sie steht in der Maske obenan, damit
+ * man für die üblichen Messwerte nicht erst einen Namen suchen muss.
+ *
+ * Gruppiert nach dem, was auf den Kacheln steht - nicht nach dem, wie die
+ * Symbole heißen.
+ */
function kachelSymbole()
{
return [
- "" => "ohne",
- "ev-station" => "Ladesäule",
- "cloud-rain" => "Regen",
- "sun" => "Sonne",
+ "Klima" => [
+ "thermometer-half" => "Temperatur",
+ "thermometer-sun" => "Temperatur draußen",
+ "thermometer-snow" => "Kälte",
+ "droplet-half" => "Feuchte",
+ "moisture" => "Luftfeuchte",
+ "fan" => "Lüftung",
+ "fire" => "Heizung",
+ "wind" => "Wind",
+ ],
+ "Strom" => [
+ "lightning-charge-fill" => "Leistung",
+ "plug-fill" => "Verbrauch",
+ "sun" => "Erzeugung",
+ "battery-half" => "Speicher",
+ "battery-charging" => "Ladung",
+ "ev-station" => "Wallbox",
+ "car-front" => "Fahrzeug",
+ "speedometer2" => "Zähler",
+ "graph-up-arrow" => "Ertrag",
+ "arrow-down-up" => "Bezug und Einspeisung",
+ ],
+ "Wasser und Wetter" => [
+ "cloud-rain" => "Regen",
+ "cloud-sun" => "Wetter",
+ "snow" => "Schnee",
+ "water" => "Wasserstand",
+ "bucket" => "Menge",
+ "tree" => "Garten",
+ ],
+ "Haus" => [
+ "lightbulb" => "Licht",
+ "door-open" => "Tür",
+ "window" => "Fenster",
+ "house-door" => "Haus",
+ "clock-history" => "Zeit",
+ "wifi" => "Verbindung",
+ ],
];
}
+/** Die Vorschläge flach, wie die Maske sie braucht: Name => Beschriftung. */
+function kachelSymboleFlach()
+{
+ $flach = [];
+ foreach (kachelSymbole() as $gruppe) {
+ foreach ($gruppe as $name => $titel) {
+ $flach[$name] = $titel;
+ }
+ }
+ return $flach;
+}
+
+/**
+ * Alle Symbolnamen für die Vorschlagsliste der Maske.
+ *
+ * Die Vorschläge zuerst und mit ihrer Beschriftung, danach der ganze Rest
+ * alphabetisch: so steht das Übliche oben, und wer etwas anderes will, tippt
+ * los und bekommt es angeboten.
+ */
+function kachelIconNamen()
+{
+ $vorschlag = kachelSymboleFlach();
+ $liste = [];
+ foreach ($vorschlag as $name => $titel) {
+ if (isset(bootstrapIcons()[$name])) {
+ $liste[] = ["name" => $name, "titel" => $titel];
+ }
+ }
+ foreach (array_keys(bootstrapIcons()) as $name) {
+ if (!isset($vorschlag[$name])) {
+ $liste[] = ["name" => $name, "titel" => ""];
+ }
+ }
+ return $liste;
+}
+
/**
* Alle Kacheln mit ihrem aktuellen Stand, für die Einstellungsseite.
*
@@ -262,10 +345,15 @@ function kachelWertPruefen($wert, $nummer)
}
}
- $icon = (string)($wert["icon"] ?? "");
+ // Jedes Bootstrap-Icon darf es sein; geprüft wird gegen dieselbe Liste,
+ // aus der die Anzeige später das Zeichen holt. Ein Tippfehler faellt so
+ // beim Speichern auf und nicht erst als leere Stelle auf der Kachel.
+ $icon = trim((string)($wert["icon"] ?? ""));
if ($icon !== "") {
- if (!array_key_exists($icon, kachelSymbole())) {
- throw new InvalidArgumentException("Wert " . $nummer . ": unbekanntes Symbol.");
+ if (!isset(bootstrapIcons()[$icon])) {
+ throw new InvalidArgumentException(
+ "Wert " . $nummer . ": das Symbol \"" . $icon . "\" gibt es nicht. "
+ . "Die Namen stehen auf icons.getbootstrap.com, ohne das \"bi-\" davor.");
}
$sauber["icon"] = $icon;
}
diff --git a/restricted/rooms.php b/restricted/rooms.php
index 45c404e..de1115b 100644
--- a/restricted/rooms.php
+++ b/restricted/rooms.php
@@ -202,25 +202,55 @@ function floorLabel($floor)
}
/**
- * Codepunkt eines Bootstrap-Icons für die Kacheln.
+ * Alle Bootstrap-Icons als Name => Codepunkt.
+ *
+ * Die Zahlen standen früher als Handabschrift hier - drei Stück, und jedes
+ * weitere Symbol war eine Codeänderung. Sie stehen aber ohnehin schon im
+ * Haus: css/bootstrap-icons.min.css führt sie unter .bi-
::before, das
+ * ist die Quelle, aus der auch der Browser liest. Also wird sie gelesen,
+ * statt sie abzuschreiben; damit steht jedes der gut zweitausend Symbole zur
+ * Verfügung, und ein Wechsel der Icon-Version zieht von selbst mit.
+ *
+ * Einmal je Anfrage - das Auslesen kostet rund eine Millisekunde, und die
+ * Startseite fragt für jede Kachel nach.
+ */
+function bootstrapIcons()
+{
+ static $icons = null;
+ if ($icons !== null) {
+ return $icons;
+ }
+ $icons = [];
+ $css = @file_get_contents(__DIR__ . "/../css/bootstrap-icons.min.css");
+ if ($css === false) {
+ return $icons; // ohne Datei eben ohne Symbole
+ }
+ // Im CSS steht content:"\f5a2" - der Backslash gehoert zum Inhalt, im
+ // Muster ist er deshalb doppelt.
+ if (preg_match_all('/\.bi-([a-z0-9-]+)::before\{content:"\\\\([0-9a-f]+)"\}/',
+ $css, $treffer, PREG_SET_ORDER)) {
+ foreach ($treffer as $t) {
+ $icons[$t[1]] = hexdec($t[2]);
+ }
+ }
+ return $icons;
+}
+
+/**
+ * Das Zeichen eines Bootstrap-Icons für die Kacheln.
*
* Die Icons kommen als Schrift, nicht als Pfad: css/bootstrap-icons.min.css
* ist ohnehin eingebunden (restricted/header.php), und SVG-Text darf dieselbe
* Schriftfamilie benutzen wie HTML. Ein eingebettetes je Symbol wäre
* dieselbe Wirkung mit mehr Zeilen.
*
- * Die Zahlen stehen in genau dieser CSS unter .bi-::before und sind von
- * dort abgeschrieben - deshalb steht der Name daneben, sonst prüft das nie
- * wieder jemand nach.
+ * Ein unbekannter Name gibt einen leeren Text - die Kachel zeigt dann die
+ * Zahl ohne Symbol, statt ein leeres Kästchen anzuzeigen.
*/
function kachelIcon($name)
{
- $icons = [
- "ev-station" => "F83A", // Wallbox, Ladeleistung
- "cloud-rain" => "F2B6", // Regenmenge
- "sun" => "F5A2", // PV-Erzeugung
- ];
- return isset($icons[$name]) ? mb_chr(hexdec($icons[$name]), "UTF-8") : "";
+ $icons = bootstrapIcons();
+ return isset($icons[$name]) ? mb_chr($icons[$name], "UTF-8") : "";
}
/**