-- --------------------------------------------------------------------------- -- 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 '' COMMENT 'Reiter in der Uebersicht', `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', `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 -- restricted/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;