Commit Graph
18 Commits
Author SHA1 Message Date
adminandClaude Opus 5 b607d4a064 Automatiken als Ausloeser: Editor, Uebersicht, Loeschen
Gegenstueck zur Runner-Seite. Der Editor selbst braucht nichts: das
gerechnete Geraet "Automatiken" fuehrt jede Automatik als Messwert, und
der Geraetewaehler listet ohnehin Geraete und deren Messwerte. Neu sind
nur die Operatoren des Datentyps `elapsed` ("+", "ab +", "vor +") und
sein Eingabefeld.

Drei Stellen wissen trotzdem davon:

pruefeKreis() lehnt beim Speichern ab, was sich mittelbar selbst
ausloesen wuerde. Im Betrieb waere ein Kreis kaum zu bemerken - die
Sperrzeit begrenzt ihn auf eine Ausloesung je lockout_secs, und im
Protokoll sieht das aus wie eine Automatik, die halt oft laeuft.

deleteAutomation() fragt vorher. fk_cond_state steht auf ON DELETE
CASCADE, mit dem Messwert verschwaende also still die Bedingung des
Nachfolgers: aus "zehn Minuten nach dem Wecker UND es ist hell" wuerde
ein blosses "es ist hell", und der Rollladen fuehre ab morgen jeden Tag
bei Sonnenaufgang hoch. Bei der letzten Bedingung faengt der Runner das
ab, bei einer von zweien niemand. Zur Wahl stehen Abhaengen (Bedingung
raus, Nachfolger pausiert) und Mitloeschen; automatisch mitzuloeschen
waere die falsche Vorgabe.

Die Uebersicht rueckt Nachfolger unter ihren Ausloeser ein und zeigt sie
eingeklappt. Das ist nur die Darstellung - jeder Nachfolger bleibt eine
vollwertige Automatik mit eigener Pause, eigenen Rahmenbedingungen und
eigener Zeile im Protokoll. Sobald "gruppiert" auch "gehoert dazu"
hiesse, waere zu klaeren, wem die Pause gehoert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 22:51:42 +02:00
adminandClaude Opus 5 07bca5104e Einstellungsseite: Reiter, Kachelwerte und Geraeteliste
Die Einstellungen bestanden aus einer einzigen langen Spalte mit den
Preistabellen. Sie bekommt Reiter, und darin zwei neue Flaechen: was die
Kacheln der Startseite anzeigen, und welche Geraete es ueberhaupt gibt.

Reiter gab es vorher dreimal in drei Ausfuehrungen - die Etagen ueber den
Automatismen mit eigenem switchTab(), die Geraetegruppen im Raum-Modal mit
eigener CSS-Klasse, und die Einstellungsseite noch einmal anders. Jetzt baut
restricted/reiter.php alle drei; umgeschaltet wird von Bootstrap, den offenen
Reiter merkt reiterMerken() in der Adresse.

Kachelwerte: was auf einer Kachel steht, stand fest in rooms.php. Die neue
Tabelle kachelWerte (solarLog_kacheln.sql) ueberschreibt das je Raum, die
Maske waehlt die Messwerte aus demselben Katalog wie der Automatik-Editor -
nach Etage sortiert, die Geraete des eigenen Raums oben. Fehlt die Tabelle,
zeigt jede Kachel weiter ihre Vorgabe.

Geraete: die Zuordnung Geraet -> Raum war ein Modal, erreichbar ueber ein
Zahnrad neben den Automatismen. Sie ist eine Einstellung und steht jetzt dort,
zusammen mit dem, was fehlte: seit wann ein Geraet nichts mehr meldet, in
welchen Automatiken es steckt, und ein Loeschknopf. Letzterer ist noetig, weil
der Suchlauf nichts loescht - er legt an und frischt auf, damit die Automatiken
ihre Zustands-Ids behalten; ein abgebautes Geraet bliebe sonst fuer immer
stehen. Geloescht wird nur, was in keiner Automatik vorkommt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-08 22:45:24 +02:00
adminandClaude Opus 5 958408eba9 Etagenwechsel im Automatik-Editor sah wie eine Kopie aus
Wer im Editor die Etage aenderte, fand die Automatik danach unter beiden
Reitern. In der Datenbank stand sie nur einmal - saveAutomation() macht
bei bekannter id ein UPDATE samt floor, einen INSERT gibt es auf dem Weg
gar nicht. Nachgeladen wurde nach dem Speichern aber nur die Liste der
neuen Etage; die alte behielt ihre Zeile, bis jemand die Seite neu lud.

Der Editor merkt sich jetzt die Etage, mit der er aufgemacht wurde, und
holt bei einem Wechsel beide Listen neu. Ohne Wechsel bleibt es bei der
einen Anfrage.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 12:02:20 +02:00
adminandClaude Opus 5 93fb054b66 Zeilenenden vereinheitlichen: LF ueberall ausser im Fremdcode
Bisher entschied jede Arbeitsstation fuer sich, welche Zeilenenden ein
Commit bekommt: Git fuer Windows setzt core.autocrlf=input in seiner
System-Konfiguration, die NAS setzt nichts. Weil der Bestand ausserdem in
sich gemischt war - 34 PHP-Dateien mit LF, 30 mit CRLF -, gab es gar kein
richtiges Zeilenende, an das ein Werkzeug sich haette halten koennen. Jede
Ergaenzung mit LF in einer CRLF-Datei ergab eine gemischte Datei; helper.php
und js/solar/homeMQTT.js waren bereits so entstanden.

.gitattributes macht die Zeilenenden zur Eigenschaft des Repositorys. LF,
weil dieses Verzeichnis der Web-Ordner der NAS ist und von Linux
ausgeliefert wird - und weil Git fuer Windows mit "input" ohnehin schon
dorthin zeigt.

restricted/WebAuthn bleibt ausgenommen und damit byteweise so, wie die
Bibliothek geliefert wurde; darunter liegen 292 Zertifikate.

Von den 47 geaenderten Dateien wurde nachgerechnet keine einzige im Inhalt
angefasst - der Vergleich HEAD-ohne-CR gegen Index ist ueberall gleich.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 23:04:00 +02:00
adminandClaude Opus 5 d3c1cb4682 Aussengelaende wird die vierte Etage AG
Was draussen haengt, stand als Pseudo-Raum "aussen" in automations.php:
"Geraete, die zu keinem Raum der Wohnung gehoeren - Carport, Garage,
Regensensor". Das waren inzwischen sechzehn Geraete in einem einzigen Topf,
der groesste ueberhaupt - in der Geraeteauswahl des Editors standen die fuenf
Carport-Wechselrichter, das Sonnensegel und das Garagentor unsortiert
nebeneinander.

Jetzt ist das Aussengelaende eine Etage wie OG, EG und UG, mit eigenen
Raeumen: Carport, Veranda, Pergola, Terrasse, Garage und Garten. Die Namen
stammen von den Geraeten selbst - die Hoymiles heissen seit jeher "Carport
1-6" und "Veranda OG2-4". Die achtzehn Geraete sind verteilt (die beiden
Ventilsteuerungen hatten noch gar keinen Raum und stehen jetzt im Garten,
zusammen mit dem Regensensor, der ihre Automatiken ausloest); "Ohne Raum"
faellt damit von acht auf sechs, und die sind es zu Recht.

AG ist eine Etage ohne Grundriss. Ihre Raeume haben kein x/y, es gibt ja
kein Bild, auf das eine Kachel zeigen koennte - ein Raum ohne Position war
schon immer vorgesehen. Das Menue und das SVG richten sich deshalb nach der
neuen floorsWithPlan(), die Zuordnung und die Automatiken nach $floors.
Bekommt der erste AG-Raum eine Kachel, erscheint die Etage von selbst auch
im Menue; es gibt keine zweite Liste, die man nachziehen muesste.

Die Etagen standen bisher an sechs Stellen noch einmal im Code. Jetzt gibt
es genau eine Liste, $floors in rooms.php, und alles andere leitet sich ab:

  * automations.php prueft gegen $floors statt gegen eine eigene Whitelist
  * ajax/AutoAction.php baut seine Etagen-Auswahl daraus
  * home.php baut Reiter und Inhaltsbereiche in einer Schleife statt
    dreimal fast dasselbe HTML
  * header.php baut die Menuepunkte daraus
  * switchTab() in homeMQTT.js liest die Reiter aus der Seite, statt OG, EG
    und UG sechsmal aufzuzaehlen
  * refreshAutomations() ebenso - eine feste Liste haette die vierte Etage
    still ausgelassen, die Tabelle waere ohne Fehlermeldung leer geblieben

Dazu die ausgeschriebenen Namen in $floorLabels: das Kuerzel steht in URLs,
SVG-Ids und im MQTT-Baum, "Aussengelaende" nur als Titel am Menuepunkt und
am Reiter.

In der Datenbank ist das Enum um 'AG' erweitert; header.php laedt rooms.php
jetzt selbst, weil es vor home.php eingebunden wird.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 17:55:11 +02:00
adminandClaude Opus 5 37962224c1 Geraeteauswahl im Automatik-Editor gruppiert nach Etage
Bisher stand ueber jedem Raum eine eigene Ueberschrift - bei neunzehn
Raeumen aus rooms.php also neunzehn Stueck, jede mit der Etage davor:
"OG - Bad", "EG - Bad", "UG - Bad". In einer Liste, die fuenfzehn Zeilen
hoch ist, sah man dadurch mehr Ueberschrift als Geraet.

Jetzt gruppiert nur die Etage, und der Raum steht klein und rechtsbuendig
an jeder Zeile. Sortiert wird innerhalb der Etage nach Raum (Reihenfolge
wie in rooms.php), sodass die Geraete eines Raums trotzdem beisammen
stehen; aus zwanzig Ueberschriften werden fuenf. Ein Raum, den es in
rooms.php nicht mehr gibt, bekommt eine eigene Ueberschrift, statt
stillschweigend unter den Unzugeordneten zu verschwinden.

Die Suche laeuft zusaetzlich ueber den Raum: "bad" findet damit auch den
Handtuchtrockner, der im Bad haengt, ohne es im Namen zu tragen. In der
Trefferliste steht keine Ueberschrift darueber, deshalb traegt dort jede
Zeile die volle Angabe "OG - Bad".

Dafuer nennt raumListe() Etage und Raum jetzt auch einzeln, und der
Geraetekatalog reicht beides durch - der Schluessel "Etage/Raum" muss so
nicht im JavaScript wieder auseinandergenommen werden.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 13:37:25 +02:00
adminandClaude Opus 5 08e8e68a61 Raum-Modal: Solltemperatur wirkt sofort, kein Speichern-Knopf mehr
Im Raum-Modal wirkt jedes Bedienelement sofort - der Rollladen faehrt, der
Schalter schaltet, die Lampe leuchtet. Nur die Solltemperatur wartete auf
"Save changes". Sie schickt jetzt beim Loslassen des Reglers, wie die
Rollladenregler daneben, und der Knopf ist im Raum-Modal weg. Einer, der
nur fuer einen der Reiter gilt, waere in allen anderen eine Falle.

Das Modal bleibt nach dem Schicken offen; frueher schloss es sich, weil
der Knopf das Ende der Bedienung war. Wer dreimal nachjustiert, will nicht
dreimal neu aufmachen. Die Heizungskarte traegt dafuer dieselbe Sperre wie
die Geraetekarten - waehrend das Kommando unterwegs ist, ist sie gesperrt.

Dabei einen Fehler mitgenommen: der Speichern-Knopf gehoert allen Modals
gemeinsam, und wer ihn versteckt, versteckt ihn fuer alle. Ein Raum ohne
Thermostat liess ihn schon bisher verschwinden - danach hatten der
AutoAction-Editor und die Raumzuordnung bis zum Neuladen keinen
Speichern-Knopf mehr. Beide holen ihn jetzt wieder hervor. Nachgemessen:
im Raum-Modal versteckt, im Editor und in der Raumzuordnung sichtbar.

Die Fahrknoepfe sind von 34 auf 50 Pixel gewachsen - sie sind das, was man
im Vorbeigehen antippt, die Regler daneben braucht man seltener.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 22:20:15 +02:00
adminandClaude Opus 5 4b47372015 Geraete den Raeumen zuordnen
Beim Anlegen einer Automatik denkt man in Raeumen ("im Bad soll ..."), nicht
in Geraetearten. Ein Raummodell gibt es schon - restricted/rooms.php, die
einzige Quelle fuer die Home-Ansicht -, nur fehlte die Zuordnung Geraet ->
Raum.

Die neue Spalte actors.room haelt sie als "Etage/Raum" (OG/Bad), dazu
"aussen" fuer Carport, Garage und Regensensor. Etage und Raum zusammen,
weil "Bad" allein auf drei Etagen vorkommt. Discovery fasst die Spalte nicht
an - der Upsert setzt nur type und name -, die Zuordnung ueberlebt also
jeden Suchlauf.

Zugeordnet wird ueber das Haus-Symbol in der Karte "Automatismen". Wo der
Raum aus dem MQTT-Topic hervorgeht ("Raumtemp/OG/Bad/Temp[degC]"), schlaegt
die Ansicht ihn vor und uebernimmt ihn auf Knopfdruck - das sind die
dreizehn Thermostate, ohne jedes Raten. Bei allen anderen wird bewusst nicht
geraten: "Bad Links" sagt nichts darueber, auf welcher der drei Etagen
dieses Bad liegt. Noch nicht zugeordnete Geraete stehen in der Tabelle oben.

Die Geraeteauswahl im Editor gruppiert danach nach Raum, in der Reihenfolge
aus rooms.php. Solange niemand zugeordnet hat, bleibt es bei der Gruppierung
nach Geraeteart - eine einzige Gruppe "Nicht zugeordnet" waere ein
Rueckschritt. Und weil auch nach der ersten Zuordnung noch viel ohne Raum
ist, wird dieser Rest weiter nach Geraeteart unterteilt ("Ohne Raum ·
Aussenjalousie (11)").

Anders als bei den Gerätearten behalten Raeume mit nur einem Geraet ihre
Ueberschrift: "OG · Bad" ist auch mit einem einzigen Thermostat genau die
Zeile, die man sucht - und mehr als eines haengt selten in einem Raum.

Die dreizehn Thermostate sind bereits zugeordnet, weil das ihre eigenen
Topics hergeben; alles andere steht auf "-" und will von Hand vergeben
werden.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 16:16:48 +02:00
adminandClaude Opus 5 2ac504ca29 Geraeteauswahl: Suchfeld statt Auswahlliste
Die Gruppierung nach Geraeteart hat die Liste geordnet, aber nicht kuerzer
gemacht: elf Jalousien bleiben elf Zeilen. Statt der Auswahlliste steht
jetzt ein Knopf in der Zeile, der eine durchsuchbare Liste ueber die volle
Breite aufklappt.

Gesucht wird ueber Beschriftung UND Geraeteart zugleich, also quer zur
Gruppierung: "bad" findet die drei Thermostate im Bad und die zwei
Jalousien "Bad Links"/"Bad Rechts", "jalousie" alle elf auf einmal. Ohne
Suchtext bleiben die Zwischenueberschriften stehen; sobald gefiltert wird,
faellt die Gruppierung weg, weil die Treffer dann quer ueber alle Arten
stehen und die Art ohnehin an jeder Zeile mitlaeuft.

Die aufgeklappte Liste haengt unter der ganzen Zeile und nicht in ihr - in
einer input-group stuende sie sonst als weitere Spalte daneben. Escape
schliesst, Enter nimmt den ersten Treffer, ein Klick daneben schliesst
ebenfalls. Es ist immer hoechstens eine offen.

Dabei zwei Sachen mitgenommen:

Eine neue Zeile beginnt jetzt ohne Geraet ("Gerät wählen …"). Bisher stand
dort das erste Geraet mit seinem ersten Messwert - nach dem
Geraete-Discovery also "Bad Links: Gesperrt = ", eine Bedingung, die
niemand gemeint hat und die man erst wegklicken musste. Der Satz darunter
sagt in dem Fall "Noch kein Ausloeser", und der Server lehnt eine
unvollstaendige Bedingung ohnehin ab.

Auf dem Handy quetschten sich Geraet, Messwert, Vergleich, Wert, Einheit
und Papierkorb in eine Zeile - uebrig blieben "Therm OG Bad" und "te".
Unter 576 px bekommen Geraet und Messwert jetzt je eine eigene Zeile. Die
Regel braucht die input-group-Klasse im Selektor: solar.css wird vor
AdminLTE geladen, und Bootstraps ".input-group > .form-select" haette sonst
dasselbe Gewicht und wuerde als spaeteres Blatt gewinnen.

Geprueft bei 375 px und am Rechner.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 16:10:59 +02:00
adminandClaude Opus 5 00f5944a7a Geraeteauswahl: nach Art gruppiert, Namen geputzt
Nach dem Discovery-Lauf stehen 51 Geraete in der Ausloeser-Liste und 40 in
der Aktions-Liste, flach und alphabetisch. Dreizehn Thermostate und elf
Jalousien sind darin vierundzwanzig gleich aussehende Zeilen.

Die Liste ist jetzt nach Geraeteart gruppiert (optgroup, das koennen auch
die Handy-Browser nativ). Arten mit nur einem Geraet bekommen keine eigene
Ueberschrift - fuenfzehn Gruppen mit je einem Eintrag waeren
unuebersichtlicher als die flache Liste -, sie sammeln sich am Ende unter
"Einzelne".

Dazu ein Namensputz fuer die Anzeige, ohne die Datenbank anzufassen: das
u_-Praefix aus den Tahoma-Beschriftungen faellt weg, ebenso eine
angehaengte einstellige Kanalnummer, und Unterstriche werden zu Leerzeichen.
Aus "u_Wozi Terrassentuer" wird "Wozi Terrassentuer", aus "Power_EG_EM_0"
wird "Power EG EM". Bewusst nur die einstellige Endung - "go-eCharger_270003"
traegt seine Seriennummer und behaelt sie.

Beschriftungen, die danach doppelt waeren, bekommen die Geraeteart dazu: die
Tahoma-Box nennt sowohl den Rollladen als auch den Sonnenenergie-Sensor
"Terasse", in der Liste untereinander waren sie nicht zu unterscheiden.
Daraus wird "Terasse (Rollladen)" und "Terasse (Licht)".

Die Beschriftung entsteht an einer Stelle und wird von Editor und
Uebersicht geteilt - sonst stuende in der Auswahlliste "Wozi Terrassentuer"
und im Satz darunter weiter "u_Wozi Terrassentuer".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 16:02:49 +02:00
adminandClaude Opus 5 17678da824 Zahlencodes als Klartext
Manche Geraete schicken eine Zahl und meinen einen Zustand - der
go-eCharger etwa 2 fuer "Charging". Welche Zahl welchen Namen hat, steht im
value_template der Home-Assistant-Discovery als Werttabelle:

    {{ ['Unknown','Idle','Charging','WaitCar','Complete','Error'][value_json|int] }}

Das ist kein Pfad in die Nutzlast, sondern eine Uebersetzung, und sie wurde
bisher verworfen. Jetzt landet sie in possible_values - in derselben
Schreibweise, die WLED fuer seine Effektliste schon benutzt, naemlich einer
Liste aus {Wert: Bezeichnung}. Damit versteht der Editor sie ohne
Zusatzarbeit und macht eine Auswahlliste daraus. Ein Versatz im Ausdruck
wandert in die Schluessel: aus [value_json|int-3] wird {"3":"Default"}.

Der Runner uebersetzt beim Lesen, eine Bedingung vergleicht also den
Klartext. Steht die Zahl nicht in der Tabelle, bleibt sie stehen - ein
erfundener Name waere schlimmer als ein roher Wert.

Dabei ist ein Folgefehler aufgefallen: Auswahlwerte in dieser Schreibweise
kamen im Editor als "[object Object]" an. Die alte addOptions kannte die
Form, der neue Modell-Aufbau nicht - aufgefallen ist es nie, weil WLED beim
Umbau abgeschaltet war. Der Katalog liefert Auswahlwerte jetzt einheitlich
als {value, label}, und zwar seitenrichtig:

    Messwert   angezeigt Charging, gespeichert Charging
               (der Runner hat schon uebersetzt)
    Parameter  angezeigt Blink,    gespeichert 1
               (das Geraet will die Zahl)

Die Uebersicht loest die Bezeichnung ebenfalls auf: "Effekt (Blink)" statt
"Effekt (1)".

Nachgemessen: alle fuenf Werttabellen auf dem Broker richtig erkannt,
einschliesslich des Versatzes, kein Fehltreffer unter den 35 uebrigen
Vorlagen. Live liefert der go-eCharger jetzt Idle, Neutral, Auto, Eco und
None statt 1, 0, 0, 4, 0. Ein weiterer Discovery-Lauf aendert keine Zeile.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 15:44:39 +02:00
adminandClaude Opus 5 0cb1fc635e Etage ist Pflicht
Die Auswahlliste im Editor bot ein "-" an. Eine Automatik ohne Etage taucht
aber in keinem der drei Reiter auf und ist danach nur noch in der Datenbank
zu finden - anlegen und sofort verlieren.

Der Eintrag ist weg, und der Zustand ist jetzt an drei Stellen unmoeglich
statt nur unwahrscheinlich: die Liste kennt nur noch OG, EG und UG,
saveAutomation lehnt alles andere mit einer Meldung ab statt still auf ""
zurueckzufallen, und im Enum der Spalte gibt es den leeren Wert nicht mehr.

Die Reihenfolge in der Liste ist jetzt OG, EG, UG wie bei den Reitern -
damit trifft der Rueckfall auf den ersten Eintrag dieselbe Etage wie die
Startseite. Kennt die Liste die Etage eines Datensatzes nicht, faellt sie
darauf zurueck, statt leer stehen zu bleiben und beim Speichern "" zu
schicken.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 13:32:58 +02:00
adminandClaude Opus 5 27e5c0d331 Sperrzeit je Automatik in drei Stufen
Die steigende Flanke allein schuetzt nicht gegen einen Messwert, der um die
Schwelle pendelt: "Temperatur > 22" bei 22,1 / 21,9 / 22,1 Grad ist jedes
Mal eine echte Flanke, und ueber MQTT koennen die Werte im Sekundentakt
hereinkommen. Gemessen: fuenf Kommandos in einer halben Minute.

automations.lockout_secs sagt jetzt, wie lange nach einer Ausloesung nicht
wieder geschaltet wird. Der Editor bietet drei Stufen an - ohne, eine
Minute, eine Viertelstunde -, weil die passende Wahl am Geraet haengt und
nicht an einer Zahl: ein Rollladen soll nicht alle zwanzig Sekunden
losfahren, eine Lichtfarbe darf das. Gespeichert werden Sekunden, damit eine
vierte Stufe eine Zeile in lockoutChoices() ist und keine Wanderung durch
die Datenbank. Vorbelegt ist eine Minute.

Eine Flanke in der Sperrzeit wird verworfen, nicht aufgehoben. Ein
Rollladen, der eine Viertelstunde spaeter doch noch losfaehrt, weil vor
langer Zeit einmal eine Schwelle gestreift wurde, waere unangenehmer als
einer, der gar nicht faehrt - und der naechste echte Anlass nach Ablauf der
Sperre kommt ohnehin durch. Verworfene Flanken stehen auf DEBUG und nicht in
automation_log, sonst waere die Tabelle bei einem zappelnden Sensor voll
davon.

force_once bleibt unberuehrt: es greift nur, wenn im Fenster gar nichts
gelaufen ist - dann ist auch keine Sperre aktiv.

Nachgemessen am pendelnden Sensor: mit 60 s Sperre ein Kommando, ohne Sperre
fuenf.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 13:26:18 +02:00
adminandClaude Opus 5 5f643b9844 AutoAction-Runner: Automatiken ausfuehren
Bisher konnte man Automatiken nur anlegen - ausgefuehrt hat sie niemand.
restricted/autoActions/autoaction_runner.py holt das nach.

Dauerlaeufer statt Cronjob, aus zwei Gruenden: Schwellwert-Ausloeser sollen
greifen, wenn die MQTT-Nachricht hereinkommt, und actor_states.current_value
wird sonst von niemandem fortgeschrieben - beim Discovery einmal gesetzt und
danach nie wieder. Ein zustandsloser Lauf haette gar nichts, womit er
vergleichen koennte. Der Runner pflegt den Wert nebenbei mit, wovon auch der
Editor profitiert: er zeigt neben jedem Messwert den aktuellen Stand.

Ausgeloest wird nur auf der steigenden Flanke (automations.cond_met), sonst
wuerde "Temperatur ueber 22 Grad" bei jedem Takt erneut feuern. Aus
demselben Grund heissen Zeit-Ausloeser jetzt "ab 16:30" statt "gleich
16:30": ein Gleichheitsvergleich waere nur in einer einzigen Minute wahr,
und ein Ausfall in genau dieser Minute kostet den ganzen Tag. Dieselbe
Ueberlegung steht hinter den breiten Zeitfenstern in auto_watering.py.

Der Weg zum Geraet haengt an der URL des Aktors: mqtt:// abonniert und
publiziert, http:// pollt und haengt Parameter an, io:// spricht mit der
Tahoma-Box, Logic rechnet Uhrzeit, Datum und Sonnenzeiten. Alle vier stehen
in transports.py; eine fuenfte Geraeteart ist eine weitere Klasse mit
passt(), zustaende_lesen() und senden().

fetch_calendar.py fuellt calendar_days aus openholidaysapi.org, damit "in
den Ferien" und "an Feiertagen" eine Grundlage haben. Einmal jaehrlich per
Cron.

Die Uebersicht blendet auf schmalen Schirmen Spalten aus, statt sie
wegzuschieben - auf dem Handy waren die Knoepfe zum Pausieren und Loeschen
sonst nur per Seitwaertsscrollen erreichbar.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-30 19:21:07 +02:00
adminandClaude Opus 5 eee3a89b4e AutoAction-Editor: Speichern, Laden und Loeschen
Der Editor las seine Geraete aus homeMesh, schrieb aber nach solarLog in
Tabellen, deren Fremdschluessel auf solarLog.actors/sensors zeigten. Jedes
INSERT lief damit gegen den Fremdschluessel - autoactionsSensors und
autoactionsActors sind deshalb leer geblieben, und die Aktor-Schleife war
ohnehin nie geschrieben worden.

Die Automatiken liegen jetzt in homeMesh neben dem Geraetemodell
(homeMesh_automations.sql). Eine Bedingung verweist mit einem einzigen
Fremdschluessel auf actor_states statt auf Geraet, State-URL und ein
unklares valID; Kommandoparameter stehen zeilenweise statt in vier festen
Spalten "Wert 1" bis "Wert 4". Verknuepft wird ueber group_no: gleiche
Nummer UND, verschiedene ODER, ausgewertet als any(all(gruppe)).

Im Editor ist eine Gruppe ein gerahmter Block mit eigenem "+ Bedingung",
dazwischen steht ODER - die Klammerung ist damit gezeichnet und nicht
vereinbart, und darunter steht derselbe Satz noch einmal in Worten. Die
Uebersicht zeigt ihn in der Spalte "Ausloeser" und ersetzt die bisher fest
verdrahtete Beispielzeile.

Nebenbei behoben: die Operator-Knoepfe schickten ihr innerHTML ("≠",
"&gt;") an eine Whitelist, die "!=" erwartete - jede Bedingung "ungleich"
wurde still zu "gleich". Ausgeblendete Wertfelder sendeten ihren Inhalt
trotzdem mit. Beides entfaellt, weil der Editor jetzt JSON aus einem
Modell schickt statt durchnummerierter Formularfelder.

Die vier Endpunkte fillSensorDD, fillActorDD, sensorDetails und
actorDetails entfallen: der Geraetekatalog reist einmal mit dem Editor
mit, statt je Bedingungszeile zwei Anfragen nachzuladen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-30 19:07:29 +02:00
adminandClaude Sonnet 5 29f752eafe Regenbasierte automatische Gartenbewässerung + homeMesh-Anbindung für AutoAction-Regeleditor
- Neues stündliches Python-Script (restricted/gartenbewaesserung/auto_watering.py): holt Niederschlags-
  und Sonnenuntergangsdaten von Open-Meteo, wertet je Zone (Hochbeete/Tröge/Garten vorn) individuelle
  Regen-Schwellenwerte und Mindest-Bewässerungsdauern aus und startet bei Bedarf per MQTT den passenden
  Automatik-Modus der Ventilsteuerung im Zeitraum vor Sonnenuntergang; veröffentlicht den Regen-Status
  zusätzlich stündlich als retained MQTT-Nachricht je Zone.
- Web-UI: neue Bewässerungs-Steuerung/-Anzeige (ajax/watering.php, js/solar/solarMQTT.js,
  assets/img/realtime.svg) inkl. Live-Status-Icons (aus/geplant/pausiert/aktiv per Farbe und Symbol).
- AutoAction-Regeleditor (ajax/actorDetails.php, sensorDetails.php, fillActorDD.php, fillSensorDD.php,
  tahoma.php, AutoAction.php) liest Actor-/Sensor-Parameter jetzt live aus der homeMesh-Datenbank statt
  aus stark vereinfachten Altfeldern, inkl. zugehöriger Anpassungen am Device-Discovery-Tooling
  (restricted/deviceDiscovery/*, neues logic_module.py).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 20:19:27 +02:00
admin ae455dba20 modify filemode for linux 2026-02-14 20:08:34 +01:00
admin 0e78302640 Initial commit 2026-02-14 19:47:21 +01:00