From b5fdbcaf65571846a5a5f7f31339cfe95a6315ff Mon Sep 17 00:00:00 2001 From: "m0@nas" Date: Tue, 22 Sep 2026 07:36:58 +0200 Subject: [PATCH] Editor: Datumsbedingungen jetzt bewertet statt dauerhaft "offen" Der Punkt neben einer Datumsbedingung ("Zeitpunkt" -> "Datum") stand bisher immer gestrichelt, nie gruen - der Editor zaehlte den Typ "date" bewusst zu den ZEITARTEN, die er nicht selbst bewertet, um keine zweite Wahrheit neben dem Runner zu pflegen. Fuer Uhrzeit, Sonnenstand und Verkettung ist das richtig: die haengen an Nachholfenster, Haltezeit oder echtem Zeitabstand - Zustand, den nur der Runner fuehrt. Das Datum ist die Ausnahme: seit autoaction_runner.py nur noch Monat und Tag vergleicht (Jahr wird ignoriert), ist die Regel ein zustandsloser Vergleich zweier Zahlenpaare - dieselbe Zeile laesst sich im Editor gefahrlos ein zweites Mal schreiben, siehe datumErfuellt(). Ausdruecklich nur fuer das gerechnete Geraet "Zeitpunkt" (device.url === "Logic"), damit ein kuenftiges, echt gemessenes "date" nicht denselben, dann falschen Vergleich bekaeme. Wirkung: die Kopfzeile "gerade X von Y" erreicht jetzt "alles erfuellt", wenn es wirklich zutrifft, statt an einer Datumsbedingung dauerhaft zu scheitern - live an der Frostwarnung geprueft (22.09., 3,6 Grad): "alles erfuellt" mit gruenem Punkt. Co-Authored-By: Claude Sonnet 5 --- js/solar/autoActionFuncs.js | 39 +++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/js/solar/autoActionFuncs.js b/js/solar/autoActionFuncs.js index 31ffc85..d156f1d 100644 --- a/js/solar/autoActionFuncs.js +++ b/js/solar/autoActionFuncs.js @@ -484,13 +484,35 @@ function werteTaktStoppen() { autoWerteTakt = null; } +/** + * Datumsbedingung wie im Runner: nur Monat und Tag zaehlen, das Jahr der + * Eingabe wird ignoriert (autoaction_runner.py, uhrzeit_erfuellt). Anders + * als bei Uhrzeit, Sonnenstand und Verkettung braucht das Datum weder + * Nachholfenster noch Haltezeit noch Laufzustand - ein reiner Vergleich + * zweier (Monat, Tag)-Paare, gefahrlos ein zweites Mal geschrieben. + * + * Liefert null, wenn sich `soll` nicht als Datum lesen laesst - dann bleibt + * die Bedingung wie zuvor ungewertet, statt mit einem falschen Ergebnis zu + * antworten. + */ +function datumErfuellt(op, soll) { + const d = new Date(String(soll) + "T00:00:00"); + if (isNaN(d.getTime())) return null; + const jetzt = new Date(); + const ist = jetzt.getMonth() * 100 + jetzt.getDate(); + const will = d.getMonth() * 100 + d.getDate(); + if (op === "=") return ist === will; + if (op === "<") return ist < will; + return ist >= will; +} + /** * Was sagt dieser Messwert gerade, und trifft die Bedingung damit zu? * * `kennt` ist falsch, wenn wir es nicht entscheiden koennen - siehe * ZEITARTEN oben - oder wenn noch gar kein Wert vorliegt. */ -function zustandVon(state, bed) { +function zustandVon(state, bed, device) { const roh = autoWerte[bed.state_id]; const wert = roh ? roh.value : (state ? state.value : null); const einheit = (roh && roh.unit) || (state && state.unit) || ""; @@ -499,6 +521,19 @@ function zustandVon(state, bed) { return { text: "–", kennt: false }; } const text = wertText(state, wert) + (einheit ? " " + einheit : ""); + + // Das Datum des gerechneten Geraets "Zeitpunkt" wertet der Editor selbst + // aus (device.url === "Logic" grenzt es von einem denkbaren, echt + // gemessenen "date"-Wert ab, der im Runner das volle Datum vergliche). + // Alle uebrigen ZEITARTEN bleiben ungewertet: ihre Regeln haengen an + // Zustand, den nur der Runner fuehrt. + if (state && state.type === "date" && device && device.url === "Logic") { + const erfuellt = datumErfuellt(bed.operator, bed.value); + if (erfuellt !== null) { + return { text: text, kennt: true, erfuellt: erfuellt }; + } + } + if (!state || ZEITARTEN.indexOf(state.type) >= 0) { return { text: text, kennt: false }; } @@ -572,7 +607,7 @@ function segmente(zustaende) { function zustaendeVon(gruppe) { return gruppe.map(bed => { const treffer = stateById(bed.state_id); - return zustandVon(treffer ? treffer.state : null, bed); + return zustandVon(treffer ? treffer.state : null, bed, treffer ? treffer.device : null); }); }