Files
SolarManager/autoActions/automatik_ausloeser.sql
adminandClaude Opus 5 09ce5c56c7 Automatiken koennen andere Automatiken ausloesen
Anlass: "zehn Minuten nach dem Wecker den Rollladen hoch, aber nur wenn
es dann schon hell ist". Als Verzoegerung an der Aktion war das nicht zu
haben - die Zusatzbedingung gilt erst zum spaeteren Zeitpunkt, und eine
verzoegerte Aktion, die selbst noch Bedingungen prueft, braeuchte ein
zweites Bedingungssystem neben dem ersten. Der zweite Schritt ist also
eine eigene Automatik; was ihr fehlte, war nur ein Bezug auf die erste.

Den gibt jetzt das gerechnete Geraet "Automatiken", Gegenstueck zum
vorhandenen "Zeitpunkt": jede Automatik ist dort ein Messwert, ihr Wert
der Zeitpunkt der letzten Ausloesung. Der Editor braucht dafuer keine
Zeile - er listet Geraete und deren Messwerte.

Der neue Datentyp `elapsed` verhaelt sich dazu wie `deltatime` zum
Sonnenaufgang: "+ 00:10", "ab + 00:10", "vor + 00:10". Ein Minus gibt es
nicht. Gerechnet wird mit dem echten Abstand statt mit der Uhrzeit
innerhalb des Tages - sonst machte ein Lauf von vorgestern die Bedingung
heute wahr. Die offene Form endet trotzdem am Tagesrand, genau wie
"ab 16:30".

Ausgewertet wird topologisch, Ausloeser vor Nachfolger; nur so wirkt ein
Versatz von null noch im selben Takt. Eine pausierte Automatik haelt ihre
Nachfolger mit an: geladen werden nur die aktiven, und der Transport
liefert fuer alle uebrigen einen leeren Wert.

Die Messwerte pflegt ausloeser_nachfuehren() - fuer JEDE Automatik, auch
fuer pausierte. Sonst loeschte ein Pausieren ueber fk_cond_state
ON DELETE CASCADE die Bedingung des Nachfolgers, still. Geloescht wird
nur, was keine Bedingung mehr benutzt.

automatik_ausloeser.sql legt Datentyp und Geraet an.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 22:51:15 +02:00

55 lines
2.6 KiB
SQL

-- ===========================================================================
-- Automatiken als Ausloeser fuer andere Automatiken
--
-- Anlass: "zehn Minuten nach dem Wecker den Rollladen hoch, aber nur wenn es
-- dann schon hell ist". Die Zusatzbedingung gilt erst zum spaeteren
-- Zeitpunkt - als blosse Verzoegerung an einer Aktion waere das nicht
-- formulierbar, dafuer braeuchte die Aktion ein eigenes Bedingungssystem.
-- Der zweite Schritt ist also eine eigene Automatik, und was ihr fehlte, war
-- nur ein Weg, sich auf die erste zu beziehen.
--
-- Dieses Skript legt dafuer zwei Dinge an:
--
-- 1. den Datentyp `elapsed` - "so lange ist es her". Er verhaelt sich zu
-- einem Zeitpunkt wie `deltatime` zum Sonnenaufgang: der Messwert ist
-- der Bezugspunkt, die Schwelle der Versatz, das Vorzeichen steckt im
-- Operator. Gerechnet wird aber mit dem echten Abstand und nicht mit
-- der Uhrzeit innerhalb des Tages - sonst machte ein Lauf von
-- vorgestern die Bedingung heute wahr.
--
-- 2. das gerechnete Geraet "Automatiken", Gegenstueck zum schon
-- vorhandenen "Zeitpunkt". Seine Messwerte legt der Runner selbst an
-- und fuehrt sie nach: je Automatik einen, benannt wie sie, mit
-- "auto:<id>" als URL. Deshalb steht hier nur der Aktor.
--
-- Der Editor braucht dafuer keine Zeile Aenderung, um das anzubieten: er
-- listet Geraete und deren Messwerte, und "Automatiken" ist dann ein Geraet
-- wie jedes andere.
--
-- Einspielen:
-- mysql -h 127.0.0.1 -P 3310 -u homeMesh -p homeMesh < automatik_ausloeser.sql
--
-- Danach den Runner neu starten (startSolarServer.sh) - die Regelwerks-
-- Nachladung holt nur Daten, keinen neuen Code.
-- ===========================================================================
-- Die IDs in state_types sind feste Kennungen, keine Auto-Increment-Werte
-- (0 = bool, 5 = time, 7 = deltatime ...). 10 ist die naechste freie.
INSERT INTO state_types (id, type)
SELECT 10, 'elapsed'
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM state_types WHERE type = 'elapsed');
-- Kein Raum und keine Etage: das Geraet steht nirgends im Haus, genau wie
-- "Zeitpunkt". Der Geraetewaehler im Editor sortiert es dadurch zu den
-- uebrigen ortlosen.
INSERT INTO actors (type, name, url, room)
SELECT 'LOGIC', 'Automatiken', 'Automatik', NULL
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM actors WHERE url = 'Automatik');
SELECT a.id AS aktor, a.name, a.url,
(SELECT id FROM state_types WHERE type = 'elapsed') AS typ_elapsed,
(SELECT COUNT(*) FROM actor_states WHERE actor_id = a.id) AS messwerte
FROM actors a WHERE a.url = 'Automatik';