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>
55 lines
2.6 KiB
SQL
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';
|