Setup-Menue: Sensorkennung ohne installationsspezifisches Praefix, Einheit statt Live-Wert
Korrektur zur letzten Aenderung, vom Nutzer live erkannt:
- "fmm003_" war hart einprogrammiert und liess trotzdem noch
installationsspezifisches Rauschen stehen (Geraete-Slug, Instanzname der
Integration). Jetzt wird das laengste gemeinsame Praefix ueber alle
aktuell zugeordneten Sensoren berechnet (setupGemeinsamesPraefix()) -
nichts mehr hartkodiert. Faellt bei einer einzelnen Entitaet aus
anderer Quelle korrekt auf die volle ID zurueck, statt falsch zu kuerzen
(live bestaetigt: TANK_DISTANZ_SENSOR zeigte den vollen Namen, weil er
auf eine andere Integration zeigte).
- Der Live-Wert des Sensors gehoert nicht mehr neben die ID - stattdessen
zeigt das Label selbst jetzt die ERWARTETE Art des Werts an
("Tankfuellstand [%]", "12V-Batteriespannung [V]"), statisch aus dem
FELDER-Katalog abgeleitet, unabhaengig von einer aktuellen Zuordnung.
Version 2026.8.28.5, live im Testcontainer verifiziert (acht echte
Setup-Zeilen gegen die Nutzerbeispiele geprueft).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -4061,40 +4061,77 @@ function sheetMarkup() {
|
||||
/* ------------------------------------------------------------ Setup-Popup */
|
||||
const LUPE_SVG = `<svg viewBox="0 0 20 20" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"><circle cx="8.5" cy="8.5" r="6"/><path d="m17 17-4.3-4.3"/></svg>`;
|
||||
|
||||
/* Nur der Teil der Entity-ID nach "fmm003_" - die tatsächliche, technische
|
||||
Kennung des zugeordneten Sensors, kürzer und aussagekräftiger als der
|
||||
volle "binary_sensor.testcar_b9_fmm003_..."-Pfad. Ohne "fmm003_" im Namen
|
||||
(z. B. eine andere Marke/Integration) bleibt der Domain-freie Rest
|
||||
stehen, statt nichts anzuzeigen. */
|
||||
/* Das gemeinsame Präfix aller aktuell zugeordneten Sensoren (domain-frei),
|
||||
bis zum letzten gemeinsamen "_" - z. B. "testcar_b9_fmm003_testintegratoin_".
|
||||
NICHT hart auf "fmm003_" verdrahtet: sowohl der Geräte-Slug
|
||||
("testcar_b9") als auch der Instanzname der Integration
|
||||
("testintegratoin") sind installationsspezifisch, vom Nutzer beim
|
||||
Einrichten seines eigenen flespi-Kanals selbst vergeben - bei ihm heißt
|
||||
das anders. Nur was WIRKLICH von allen zugeordneten Sensoren geteilt
|
||||
wird, ist reines Rauschen; alles danach ist die eigentliche, stabile
|
||||
Signalbezeichnung. Mit weniger als zwei zugeordneten Sensoren (nichts zum
|
||||
Vergleichen) oder wenn Sensoren aus zwei erkennbar verschiedenen Quellen
|
||||
kommen (kein gemeinsames Präfix), liefert das null - dann zeigt
|
||||
entitaetIdKurz() lieber die volle, ungekürzte ID als eine geratene,
|
||||
möglicherweise falsche Kürzung. */
|
||||
function setupGemeinsamesPraefix() {
|
||||
const ids = [];
|
||||
for (const feld of setupKatalog()) {
|
||||
const wert = setupZuordnung[feld.key];
|
||||
if (feld.liste) { for (const w of (wert || [])) if (w) ids.push(w); }
|
||||
else if (wert) ids.push(wert);
|
||||
}
|
||||
const ohneDomain = ids.map((id) => id.includes(".") ? id.split(".").slice(1).join(".") : id);
|
||||
if (ohneDomain.length < 2) return null;
|
||||
let praefix = ohneDomain[0];
|
||||
for (const s of ohneDomain.slice(1)) {
|
||||
let i = 0;
|
||||
while (i < praefix.length && i < s.length && praefix[i].toLowerCase() === s[i].toLowerCase()) i++;
|
||||
praefix = praefix.slice(0, i);
|
||||
if (!praefix) return null;
|
||||
}
|
||||
const idxUnter = praefix.lastIndexOf("_");
|
||||
return idxUnter > 0 ? praefix.slice(0, idxUnter + 1) : null;
|
||||
}
|
||||
|
||||
/* Die Entity-ID ohne Domain und ohne das gemeinsame, installationsspezifische
|
||||
Präfix (siehe setupGemeinsamesPraefix()) - die tatsächliche, stabile
|
||||
Kennung des zugeordneten Sensors, unabhängig davon, wie Geräte-Slug und
|
||||
Integrationsinstanz beim jeweiligen Nutzer heißen. Passt das gemeinsame
|
||||
Präfix nicht auf DIESE Entität (z. B. eine einzelne Entität aus einer
|
||||
anderen Quelle als der Rest), bleibt die volle domain-freie ID stehen. */
|
||||
function entitaetIdKurz(entityId) {
|
||||
if (!entityId) return null;
|
||||
const ohneDomain = entityId.includes(".") ? entityId.split(".").slice(1).join(".") : entityId;
|
||||
const idx = ohneDomain.toLowerCase().indexOf("fmm003_");
|
||||
return idx >= 0 ? ohneDomain.slice(idx + "fmm003_".length) : ohneDomain;
|
||||
const praefix = setupGemeinsamesPraefix();
|
||||
if (praefix && ohneDomain.toLowerCase().startsWith(praefix.toLowerCase())) {
|
||||
return ohneDomain.slice(praefix.length);
|
||||
}
|
||||
return ohneDomain;
|
||||
}
|
||||
|
||||
/* Aktueller Wert + Einheit einer Entität, oder null ohne brauchbaren
|
||||
Zustand (nicht zugeordnet, unavailable/unknown) - dieselbe Zustandslogik
|
||||
wie in entitaetZeilenMarkup() unten, hier für eine einzelne Entität statt
|
||||
einer ganzen Kandidatenliste. */
|
||||
function entitaetWertKurz(entityId) {
|
||||
if (!entityId || !HASS.states[entityId]) return null;
|
||||
const zustand = HASS.states[entityId].state;
|
||||
if (zustand === "unavailable" || zustand === "unknown") return null;
|
||||
const einheit = HASS.states[entityId].attributes && HASS.states[entityId].attributes.unit_of_measurement;
|
||||
return `${zustand}${einheit ? " " + einheit : ""}`;
|
||||
}
|
||||
|
||||
/* Ersetzt den bisherigen statischen Beschreibungstext im Setup ("on = Fahrt
|
||||
läuft", "Optional, vom CAN...") - Nutzerwunsch: statt einer generischen
|
||||
Erklärung zeigt die Kopfzeile jetzt die Kennung UND die aktuelle Meldung
|
||||
des tatsächlich zugeordneten Sensors, direkt neben der Feld-Überschrift.
|
||||
Ohne Zuordnung (leer) gibt es nichts zu zeigen. */
|
||||
function setupErwarteterSensor(entityId) {
|
||||
const kurz = entitaetIdKurz(entityId);
|
||||
if (!kurz) return "";
|
||||
const wert = entitaetWertKurz(entityId);
|
||||
return wert != null ? `${kurz} · ${wert}` : kurz;
|
||||
/* Die Art des erwarteten Werts, als kurzes Klammer-Etikett direkt neben der
|
||||
Feld-Überschrift ("Tankfüllstand [%]", "12V-Batteriespannung [V]") - eine
|
||||
feste Eigenschaft der FELD-ROLLE selbst (aus dem FELDER-Katalog,
|
||||
einstellungen.py), unabhängig davon, ob und welcher Sensor gerade
|
||||
zugeordnet ist. Bewusst NICHT der Live-Wert eines Sensors - der gehört
|
||||
nirgends mehr hin, siehe entitaetIdKurz()'s eigenen Kommentar zur
|
||||
Kopfzeile. binary_sensor liefert immer den Rohzustand "on"/"off"
|
||||
(unabhängig von device_class - die beeinflusst nur, wie ANDERE
|
||||
HA-Oberflächen ihn anzeigen, nicht den Rohwert, den diese App liest).
|
||||
Bei mehreren möglichen Einheiten (z. B. "L"/"l") die klein geschriebene
|
||||
Variante bevorzugt, sonst die erste genannte. Ohne passenden Fall (Knopf,
|
||||
GPS-Koordinate) kein Etikett. */
|
||||
function feldEinheitAnzeige(feld) {
|
||||
if (feld.domains && feld.domains.includes("binary_sensor")) return "on/off";
|
||||
if (feld.domains && feld.domains.includes("button")) return null;
|
||||
if (feld.units && feld.units.length) {
|
||||
return feld.units.find((u) => u === u.toLowerCase() && u !== u.toUpperCase()) || feld.units[0];
|
||||
}
|
||||
if (feld.device_classes && (feld.device_classes.includes("date") || feld.device_classes.includes("timestamp"))) {
|
||||
return "Datum";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function entitaetZeilenMarkup(feldId, key, suchtext, aktuellerWert) {
|
||||
@@ -4133,11 +4170,14 @@ function entitaetCombo(key, idx) {
|
||||
|
||||
function setupFeldzeile(feld) {
|
||||
// Bei einem Listenfeld (vier Positionen wie Tür-/Fenstersensoren) gibt es
|
||||
// keinen EINEN zugeordneten Sensor für die Kopfzeile - jede Position hat
|
||||
// ihre eigene Zuordnung, siehe die Unterfelder unten.
|
||||
const erwartet = feld.liste ? "" : setupErwarteterSensor(setupZuordnung[feld.key]);
|
||||
// keinen EINEN zugeordneten Sensor, dessen Kennung sich anzeigen ließe -
|
||||
// jede Position hat ihre eigene Zuordnung, siehe die Unterfelder unten.
|
||||
// Das Einheiten-Etikett neben dem Label gilt dagegen für die ganze Rolle
|
||||
// und wird auch dort gezeigt.
|
||||
const einheit = feldEinheitAnzeige(feld);
|
||||
const erwartet = feld.liste ? "" : entitaetIdKurz(setupZuordnung[feld.key]);
|
||||
const kopf = `<div class="setup-feld-kopf">
|
||||
<span class="setup-feld-label">${esc(feld.label)}</span>
|
||||
<span class="setup-feld-label">${esc(feld.label)}${einheit ? ` <span class="setup-feld-einheit">[${esc(einheit)}]</span>` : ""}</span>
|
||||
${erwartet ? `<span class="setup-feld-hinweis">${esc(erwartet)}</span>` : ""}
|
||||
</div>`;
|
||||
if (feld.liste) {
|
||||
|
||||
@@ -1255,12 +1255,14 @@ button.leaf:active { background: var(--tile-2); }
|
||||
.setup-gruppe-titel { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--fg3); margin-bottom: 6px; }
|
||||
.setup-feldzeile { padding: 12px 0; border-bottom: 1px solid var(--line); }
|
||||
.setup-feldzeile:last-child { border-bottom: none; }
|
||||
/* Nutzerwunsch: der zugeordnete Sensor (Kennung + aktueller Wert, siehe
|
||||
setupErwarteterSensor() in audi-dashboard-app.js) steht NEBEN der
|
||||
Feld-Überschrift, nicht mehr wie die frühere statische Beschreibung
|
||||
darunter - deshalb Zeile statt Spalte. */
|
||||
/* Nutzerwunsch: die Kennung des zugeordneten Sensors (entitaetIdKurz() in
|
||||
audi-dashboard-app.js) steht NEBEN der Feld-Überschrift, nicht mehr wie
|
||||
die frühere statische Beschreibung darunter - deshalb Zeile statt Spalte.
|
||||
Die erwartete Einheit (feldEinheitAnzeige()) hängt direkt am Label selbst
|
||||
("Tankfüllstand [%]"), losgelöst davon, ob/welcher Sensor zugeordnet ist. */
|
||||
.setup-feld-kopf { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
|
||||
.setup-feld-label { font-size: 14.5px; color: var(--fg); flex: 0 1 auto; }
|
||||
.setup-feld-einheit { color: var(--fg3); font-size: 12.5px; }
|
||||
.setup-feld-hinweis {
|
||||
font-size: 12.5px; color: var(--fg2); line-height: 1.4; text-align: right;
|
||||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 55%;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"domain": "audi_dashboard",
|
||||
"name": "Audi Dashboard",
|
||||
"version": "2026.8.28.4",
|
||||
"version": "2026.8.28.5",
|
||||
"documentation": "https://gitea.nothaft.cloud/paul/audi-app/src/branch/main/README.md",
|
||||
"issue_tracker": "https://gitea.nothaft.cloud/paul/audi-app/issues",
|
||||
"codeowners": ["@paul"],
|
||||
|
||||
Reference in New Issue
Block a user