Releases: Blogshot/ha-openscale-card
Release list
v0.9.6
Fixed
- Trend arrows without a configured goal no longer look identical to "nothing happened": a genuine value change now shows a blue "moved" color, distinct from neutral gray for an actually-unchanged reading. Colors turn green/red only once a goal is set, as before.
- Fixed the history-based trend baseline picking up a duplicate republish of the current value instead of the real prior reading. openScale-sync entities briefly go
unknownand re-publish their last known value on every sync heartbeat, not just on a real weigh-in — this could make a genuine change show as a false "flat" right after a fresh dashboard load. Confirmed and covered with a regression test against real recorder history.
🤖 Generated with Claude Code
v0.9.5 — Callouts mode: enlarge label/value text to match the grid mode
Verbesserung
Der Text im Callouts-Diagramm war deutlich kleiner als im Grid-Modus, obwohl die Font-Size-Werte (11/13) ähnlich aussahen — als SVG-Wert skaliert die Schriftgröße mit der viewBox, daher übersetzten sich diese Zahlen nie in echte HTML-große Schrift.
Die Vergrößerung ist bewusst nur auf den Callouts-Modus beschränkt (nicht die Donut-Ring-Beschriftungen, die deutlich weniger Platz haben).
Das Vergrößern der viewBox hatte einen Nebeneffekt: Alles andere in derselben Koordinatenfläche — auch die Silhouette — wurde dadurch kleiner. Das wurde kompensiert, indem die Silhouette (und die Ansatzpunkte ihrer Linien) um denselben Faktor mitskaliert wurde, um ihre ursprüngliche Größe zu behalten.
Auf dem Weg zwei echte Clipping-Bugs gefunden und behoben: Texte liefen zunächst über den linken/rechten Rand hinaus (Ränder waren noch auf die alte, kleine Schrift ausgelegt), und die letzte Zeile lief unten leicht aus der viewBox heraus.
Verifiziert per Pixel-Vergleich gegen die "Weight"-Zeile im Grid-Modus bei gleichem Zoom — vergleichbare Textgröße, kein Clipping mehr in irgendeiner Zeile.
Baut auf v0.9.4 auf.
Siehe README für Installation und Konfiguration.
v0.9.4 — Callouts/donut right side: arrow first, value trailing
Fix
Auch nach der festen Pfeilbreite aus v0.9.3 stand die rechte Spalte (Callouts, Donut-Ring) noch nicht bündig: Der Pfeil sitzt dort am Ende von "Wert Einheit Pfeil" — und diese Zeichenkette ist je nach Metrik unterschiedlich lang (17,7 % vs. 2734 kcal), wodurch der Pfeil trotz fester Breite an unterschiedlicher Stelle landete.
Fix: Rechte Seite zeigt jetzt "Pfeil Wert Einheit" — der Pfeil sitzt direkt am linksbündigen Ankerpunkt, der (unterschiedlich lange) Wert läuft dahinter. Genau spiegelbildlich zur linken Seite, die durch ihre Rechtsbündigkeit bereits so funktioniert hat. Gleich in beiden betroffenen Stellen behoben (Callouts-Modus und die Ring-Beschriftungen im Donut-Modus, da beide dieselbe Struktur teilen).
Verifiziert mit erzwungenen unterschiedlich langen Werten und gemischten Richtungen auf der rechten Seite — alle Pfeile beginnen jetzt an derselben Stelle, unabhängig von der Textlänge dahinter.
Baut auf v0.9.3 auf.
Siehe README für Installation und Konfiguration.
v0.9.3 — Fix trend-arrow alignment: pin glyphs to a fixed width
Fix
↑/↓/→ sind in keiner Schriftart gleich breit — dadurch verschob sich bei linksbündigem Text (Callouts/Donut-Ring, text-anchor="end") der Wert je nach angezeigter Richtung nach links oder rechts, und bei rechtsbündigem Text landete der Pfeil an unterschiedlichen Positionen. Nichts stand mehr sauber in einer Spalte.
Fix: Die SVG-Pfeile (Callouts, Donut-Ring) bekommen jetzt textLength/lengthAdjust="spacingAndGlyphs", wodurch das Zeichen immer exakt gleich breit gerendert wird, unabhängig davon welches der drei es ist. Der HTML-Pfeil (Grid-Modus, Zeilen unter dem Donut-Ring) bekommt das Äquivalent per CSS (feste Breite, zentriert).
Verifiziert mit erzwungenen unterschiedlichen Richtungen pro Zeile (Weight rauf, Body Fat runter, Muscle Mass unverändert, Water rauf) — beide Spalten stehen jetzt sauber untereinander, unabhängig vom jeweils angezeigten Pfeil.
Baut auf v0.9.2 auf.
Siehe README für Installation und Konfiguration.
v0.9.2 — Make trend arrows bigger and bold for visibility
Verbesserung
Die Trend-Pfeile (↑/↓/→) sind jetzt deutlich größer und fett — auf Wunsch, für bessere Sichtbarkeit.
- Grid-Modus und die Zeilen unter dem Donut-Ring (HTML-basiert): echte 32px, Schriftschnitt 700.
- Callouts- und Donut-Ring-Beschriftungen (SVG-basiert): dort skaliert die Schriftgröße mit der
viewBox, ein direkter "32px"-Wert wäre kaum sichtbar größer gewesen. Nach Testen und Verwerfen eines zu großen Werts (der bei linksbündigem Text Ziffern aus dem sichtbaren Bereich schob) auf einen Wert eingependelt, der deutlich fetter wirkt, ohne etwas abzuschneiden.
Nebenbei: Zeilen im Grid-/Donut-Extra-Bereich zentrieren Label und Wert jetzt vertikal zueinander, da die Werte durch den größeren Pfeil höher geworden sind.
Baut auf v0.9.1 auf.
Siehe README für Installation und Konfiguration.
v0.9.1 — Group the Goals editor by category, with a unit hint per field
Fix
Mit mehreren aktivierten berechneten Metriken listete die Goals-Sektion z. B. "Body Fat" und "Fat Mass" als zwei scheinbar unabhängige Zeilen auf — dieselbe Sache (Fett) in zwei Einheiten, ohne erkennbaren Zusammenhang und ohne Hinweis, welche Einheit erwartet wird.
Zielwert-Felder sind jetzt nach Kategorie gruppiert (Weight, Fat, Muscle, Water, Bone, Other), sodass Prozent- und kg-Variante derselben Metrik zusammenstehen statt alphabetisch verstreut. Innerhalb einer Kategorie heißen die Felder nur noch "Percentage"/"Mass" — die Überschrift liefert den Kontext, statt "Fat" doppelt zu nennen.
Jedes Zahlenfeld zeigt außerdem die passende Einheit direkt im Feld an — die echte Einheit des zugrunde liegenden Sensors bei Rohwerten (funktioniert also auch mit einer Waage in lb), sonst die feste Einheit der berechneten Metrik (%, kg, kcal).
Baut auf v0.9.0 auf.
Siehe README für Installation und Konfiguration.
v0.9.0 — Color trend arrows by progress toward a goal, not raw direction
Neu: zielbewusste Pfeilfarben
Bisher war die Pfeilfarbe hart an die Richtung gekoppelt (rauf = rot, runter = grün) — das ist für viele Metriken schlicht falsch: steigende Muskelmasse ist erwünscht, steigender Körperfettanteil meist nicht, und Wasser schwankt aus Gründen, die für sich genommen kaum etwas aussagen.
Metriken akzeptieren jetzt ein optionales goal (Zielwert):
metrics:
weight:
entity: sensor.openscale_weight
goal: 73Mit gesetztem Ziel wird der Pfeil grün, wenn sich der neue Wert dem Ziel angenähert hat, und rot, wenn er sich entfernt hat — unabhängig davon, ob das technisch ein Anstieg oder Rückgang ist. Ohne Ziel bleiben alle Pfeile neutral/grau, ganz gleich in welche Richtung sie zeigen — ein Pfeil unterstellt nie mehr "gut"/"schlecht", ohne dass du ein Ziel angegeben hast. Der visuelle Editor bekommt dafür eine neue "Goals"-Sektion mit einem Zahlenfeld pro aktuell konfigurierter Metrik.
Nebenbei behoben: Im Donut-Ring hatte der Pfeil neben Fat/Muscle/Water nie eine Farb-Klasse bekommen (reiner Text statt farbigem Element) — daher sah er unabhängig vom Ergebnis immer grau/neutral aus, während die Zeilen unter dem Ring korrekt eingefärbt wurden. Beide Stellen nutzen jetzt denselben Mechanismus.
Sichtbare Verhaltensänderung: Pfeile, die bisher rot/grün waren, zeigen jetzt grau, bis du für die jeweilige Metrik ein Ziel setzt.
Baut auf v0.8.5 auf.
Siehe README für Installation und Konfiguration.
v0.8.5 — Fix trend flashing back to flat on the very next unrelated render
Fix
Der eigentliche, letzte Baustein im "Trend-Pfeil bleibt neutral"-Fall. Gefunden über einen echten DOM-Snapshot: Weight zeigte trend-flat, obwohl der Sensor sich nachweislich geändert hatte (74.95 → 75.2 kg) und die History-Anfrage korrekt formatiert war und echte Daten zurückgab.
Ursache: update() hat bei jedem Aufruf den Vergleichswert bedingungslos auf den aktuellen Wert überschrieben — auch in genau dem Render, der gerade "up" berechnet hatte. Home Assistant ruft den hass-Setter (und damit ein Re-Render dieser Karte) ständig für Entitäten auf, die mit dieser Karte nichts zu tun haben — deutlich häufiger, als openScale-sync neue Werte veröffentlicht. Der nächste dieser fremden Re-Renders verglich den (unveränderten) Wert mit sich selbst und bekam "flat" — der "up"-Pfeil war binnen Sekundenbruchteilen wieder weg.
Fix: Der Vergleichswert wird nur noch bei einer echten Änderung weitergerückt; ein berechneter Trend wird zwischengespeichert und bei unverändertem Wert einfach wiederverwendet, statt neu (und falsch) gegen sich selbst berechnet zu werden.
Verifiziert mit einer Headless-Chrome-Reproduktion der echten Kartenkonfiguration, die 30 zusätzliche, fremde hass-Re-Renders auslöst (vor und nach Auflösen der History-Abfrage) — genau das reale Verhalten einer belebten Home-Assistant-Instanz. Weight und Water bleiben jetzt durchgehend bei ↑/↓ stehen, statt auf → zu verfallen.
Baut auf v0.8.4 auf.
Siehe README für Installation und Konfiguration.
v0.8.4 — Fix history lookup returning empty (missing end_time)
Fix
Die Trend-Pfeile blieben in v0.8.3 weiterhin bei "neutral" hängen — dieses Mal ein echter Bug, gefunden über einen realen Netzwerk-Request im Browser: 200 OK, aber leere Antwort [].
Ursache: Home Assistants history/period-Endpunkt setzt end_time standardmäßig auf einen Tag nach dem übergebenen Start-Zeitpunkt, wenn es fehlt — nicht auf "jetzt". Jede Seed-Anfrage fragte einen 30 Tage alten Start ohne end_time ab und landete damit tatsächlich in einem Ein-Tage-Fenster vor 29–30 Tagen — lange bevor die Sensoren überhaupt Daten hatten. Ergebnis: immer eine leere Antwort, die stillschweigend wie "keine Historie verfügbar" behandelt wurde.
Fix: end_time (jetzt) wird jetzt explizit mitgesendet. Ein neuer Test sichert das ab; verifiziert gegen einen Mock, der exakt das reale Verhalten von ha.knott.ac nachbildet (leer ohne end_time, echte Historie damit).
Zur Einordnung: Body Fat und Muscle Mass zeigten in der Praxis weiterhin korrekt "→", weil sich diese Werte tatsächlich nicht verändert hatten — das war nie der Bug.
Baut auf v0.8.3 auf.
Siehe README für Installation und Konfiguration.
v0.8.3 — Drop the localStorage layer, history is now the only seed source
Vereinfachung
Auf Wunsch: Statt zuerst im Browser-localStorage nach dem letzten Trend-Basiswert zu suchen und erst danach bei Home Assistants History nachzufragen, greift die Karte jetzt direkt und ausschließlich auf die History zu, sobald eine frische Karten-Instanz (Reload/View-Wechsel) einen Messwert zum ersten Mal sieht.
Weniger Code, weniger Sonderfälle:
- Keine
storageId-Ableitung aus den konfigurierten Entity-IDs mehr - Kein try/catch mehr um einen möglicherweise deaktivierten oder werfenden
localStorage - Keine separate "übersteht das einen Reload"-Logik neben der History-Abfrage, die das ohnehin schon abdeckt
Funktional identisch zu v0.8.2 für alle vier openScale-sync-Rohsensoren; berechnete Metriken (BMI, BMR, TDEE, …) verhalten sich unverändert. Verifiziert mit einem echten Headless-Chrome-Rendering sowie 21 grünen Unit-Tests (4 localStorage-spezifische Tests entfielen ersatzlos).
Baut auf v0.8.2 auf.
Siehe README für Installation und Konfiguration.