Die Pfade in commands.php und homeMesh_automations.sql zeigten noch ins Web-Verzeichnis. Dazu die Beschreibung der Zeit-Operatoren im Kopf von automations.php: "um 16:30" gilt jetzt ab dieser Minute und noch catchup_minutes lang, damit ein Neustart oder ein langsamer Durchlauf den Termin nicht mehr verschluckt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
135 lines
9.1 KiB
SQL
135 lines
9.1 KiB
SQL
-- ---------------------------------------------------------------------------
|
|
-- Automatiken (AutoActions) fuer die Datenbank `homeMesh`
|
|
-- ---------------------------------------------------------------------------
|
|
-- Bewusst hier und nicht in `solarLog`: der Editor liest Geraete, Messwerte
|
|
-- und Kommandos ohnehin aus homeMesh, und nur innerhalb einer Datenbank
|
|
-- koennen Fremdschluessel greifen. Die alten Tabellen autoActions,
|
|
-- autoactionsSensors und autoactionsActors in solarLog zeigten auf
|
|
-- solarLog.actors bzw. solarLog.sensors, waehrend das Formular homeMesh-IDs
|
|
-- lieferte - jedes INSERT lief gegen den Fremdschluessel, deshalb sind die
|
|
-- beiden Kindtabellen dort leer geblieben.
|
|
--
|
|
-- Ein Geraetebegriff: device_discovery.py legt auch reine Sensoren in
|
|
-- `actors`/`actor_states` ab (siehe insert_sensor()), die Tabellen
|
|
-- `sensors`/`sensor_states` sind unbenutzt. `actor_states` ist damit alles
|
|
-- Lesbare, `actor_commands` alles Schaltbare.
|
|
--
|
|
-- Voraussetzung: in restricted/deviceDiscovery/config.ini muss
|
|
-- clear_tables = false stehen. Discovery schreibt mit ON DUPLICATE KEY UPDATE
|
|
-- auf den URLs, das Leeren ist unnoetig - ein TRUNCATE wuerde dagegen die
|
|
-- Geraete-IDs neu vergeben und alle Regeln auf falsche Geraete zeigen lassen.
|
|
-- ---------------------------------------------------------------------------
|
|
|
|
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
|
|
SET NAMES utf8mb4;
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Die Automatik selbst: der Rahmen, in dem sie ueberhaupt greifen darf.
|
|
-- ---------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS `automations` (
|
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
|
`name` varchar(100) NOT NULL COMMENT 'Anzeigename, z.B. Kinder zu',
|
|
`floor` enum('UG','EG','OG') NOT NULL DEFAULT 'OG' COMMENT 'Reiter in der Uebersicht. Ohne Etage waere die Automatik in keinem davon zu sehen, deshalb gibt es keinen leeren Wert',
|
|
`enabled` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Aktiv oder pausiert',
|
|
`window_from` time NOT NULL DEFAULT '00:00:00' COMMENT 'Aktiver Zeitraum, Beginn',
|
|
`window_to` time NOT NULL DEFAULT '23:59:00' COMMENT 'Aktiver Zeitraum, Ende. Kleiner als window_from = ueber Mitternacht',
|
|
`weekdays` tinyint(3) unsigned NOT NULL DEFAULT 127 COMMENT 'Bitmaske: Bit 0 = Montag ... Bit 6 = Sonntag',
|
|
`on_vacation` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Auch in den Ferien ausfuehren',
|
|
`on_holiday` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Auch an Feiertagen ausfuehren',
|
|
`force_once` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Am Ende des Zeitraums auf jeden Fall ausfuehren',
|
|
`lockout_secs` int(11) NOT NULL DEFAULT 60 COMMENT 'Sperrzeit: so lange nach einer Ausloesung wird nicht erneut geschaltet. Gegen Messwerte, die um die Schwelle pendeln - jedes Ueberschreiten waere sonst eine echte Flanke. Der Editor bietet 0, 60 und 900 an',
|
|
`cond_met` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'War die Bedingung beim letzten Durchlauf erfuellt? Nur die steigende Flanke loest aus, sonst wuerde Temperatur groesser 22 im Sekundentakt feuern',
|
|
`last_run` datetime DEFAULT NULL COMMENT 'Zuletzt ausgeloest, NULL = noch nie',
|
|
`changed` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp() COMMENT 'Signal an den Runner, das Regelwerk neu zu laden',
|
|
PRIMARY KEY (`id`),
|
|
KEY `idx_automations_floor` (`floor`),
|
|
KEY `idx_automations_changed` (`changed`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Ausloeser. Eine Zeile ist ein Vergleich auf genau einen Messwert.
|
|
--
|
|
-- `state_id` zeigt direkt auf actor_states und traegt damit Geraet, Messwert,
|
|
-- Datentyp, Einheit und MQTT-Topic in einem Feld - frueher war das auf
|
|
-- sensorID, eine state-URL und ein unklares valID verteilt.
|
|
--
|
|
-- Verknuepft wird ueber `group_no`: gleiche Nummer = UND, verschiedene
|
|
-- Nummern = ODER. Ausgewertet wird also any(all(gruppe)). Im Editor ist eine
|
|
-- Gruppe ein gerahmter Block und zwischen den Bloecken steht ein ODER - die
|
|
-- Klammerung ist damit gezeichnet und nicht bloss vereinbart. Innerhalb einer
|
|
-- Gruppe wie zwischen den Gruppen ist die Reihenfolge fuer das Ergebnis egal,
|
|
-- `position` ist reine Lesehilfe.
|
|
-- ---------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS `automation_conditions` (
|
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
|
`automation_id` int(11) NOT NULL,
|
|
`group_no` int(11) NOT NULL DEFAULT 0 COMMENT 'UND-Block. Gleiche Nummer = UND, verschiedene Nummern = ODER',
|
|
`position` int(11) NOT NULL DEFAULT 0 COMMENT 'Reihenfolge innerhalb des Blocks, nur Darstellung',
|
|
`state_id` int(11) NOT NULL COMMENT 'Referenz auf actor_states: Geraet und Messwert in einem',
|
|
`operator` enum('=','!=','>','<','>=','<=','+','-','>=+','>=-','<+','<-') NOT NULL DEFAULT '=' COMMENT 'Immer ASCII, die Beschriftung macht erst die Anzeige daraus. Bei Zeit und Datum: = um, >= ab, < vor. Beim Sonnenstand traegt der Operator zusaetzlich das Vorzeichen des Versatzes: + genau danach, >=- ab davor, <+ bis danach',
|
|
`value` varchar(255) NOT NULL DEFAULT '' COMMENT 'Schwelle als Text, der Datentyp steckt im Messwert',
|
|
PRIMARY KEY (`id`),
|
|
KEY `idx_cond_automation` (`automation_id`,`group_no`,`position`),
|
|
KEY `idx_cond_state` (`state_id`),
|
|
CONSTRAINT `fk_cond_automation` FOREIGN KEY (`automation_id`) REFERENCES `automations` (`id`) ON DELETE CASCADE,
|
|
CONSTRAINT `fk_cond_state` FOREIGN KEY (`state_id`) REFERENCES `actor_states` (`id`) ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Aktionen: ein Kommando eines Aktors, das bei Ausloesung geschickt wird.
|
|
-- ---------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS `automation_actions` (
|
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
|
`automation_id` int(11) NOT NULL,
|
|
`position` int(11) NOT NULL DEFAULT 0 COMMENT 'Ausfuehrungsreihenfolge',
|
|
`command_id` int(11) NOT NULL COMMENT 'Referenz auf actor_commands: Geraet und Kommando in einem',
|
|
PRIMARY KEY (`id`),
|
|
KEY `idx_action_automation` (`automation_id`,`position`),
|
|
KEY `idx_action_command` (`command_id`),
|
|
CONSTRAINT `fk_action_automation` FOREIGN KEY (`automation_id`) REFERENCES `automations` (`id`) ON DELETE CASCADE,
|
|
CONSTRAINT `fk_action_command` FOREIGN KEY (`command_id`) REFERENCES `actor_commands` (`id`) ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Werte fuer die Parameter eines Kommandos. Eine Zeile je Parameter statt
|
|
-- fester Spalten Wert 1 bis Wert 4: wie viele es sind, sagt
|
|
-- command_parameters, nicht die Tabellenbreite.
|
|
-- ---------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS `automation_action_params` (
|
|
`action_id` int(11) NOT NULL,
|
|
`parameter_id` int(11) NOT NULL COMMENT 'Referenz auf command_parameters',
|
|
`value` varchar(255) NOT NULL DEFAULT '',
|
|
PRIMARY KEY (`action_id`,`parameter_id`),
|
|
KEY `idx_actionparam_parameter` (`parameter_id`),
|
|
CONSTRAINT `fk_actionparam_action` FOREIGN KEY (`action_id`) REFERENCES `automation_actions` (`id`) ON DELETE CASCADE,
|
|
CONSTRAINT `fk_actionparam_parameter` FOREIGN KEY (`parameter_id`) REFERENCES `command_parameters` (`id`) ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Lauf-Protokoll. Speist die Spalte "zuletzt ausgeloest" in der Uebersicht
|
|
-- und macht Fehlschlaege sichtbar, die sonst still blieben. Der Runner
|
|
-- raeumt Eintraege aelter als 30 Tage selbst weg.
|
|
-- ---------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS `automation_log` (
|
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
|
`automation_id` int(11) NOT NULL,
|
|
`ts` datetime NOT NULL DEFAULT current_timestamp(),
|
|
`result` enum('fired','forced','error') NOT NULL DEFAULT 'fired',
|
|
`detail` varchar(255) NOT NULL DEFAULT '',
|
|
PRIMARY KEY (`id`),
|
|
KEY `idx_log_automation` (`automation_id`,`ts`),
|
|
CONSTRAINT `fk_log_automation` FOREIGN KEY (`automation_id`) REFERENCES `automations` (`id`) ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Ferien und Feiertage. Nur besondere Tage stehen drin, ein fehlendes Datum
|
|
-- ist ein gewoehnlicher Tag. Gefuellt von
|
|
-- SolarManager/autoActions/fetch_calendar.py, einmal jaehrlich per Cron.
|
|
-- ---------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS `calendar_days` (
|
|
`date` date NOT NULL,
|
|
`holiday` varchar(80) DEFAULT NULL COMMENT 'Name des Feiertags, NULL = keiner',
|
|
`vacation` varchar(80) DEFAULT NULL COMMENT 'Name der Ferien, NULL = keine',
|
|
PRIMARY KEY (`date`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|