diff --git a/autoActions/autoaction_runner.py b/autoActions/autoaction_runner.py index 3533884..9fec062 100644 --- a/autoActions/autoaction_runner.py +++ b/autoActions/autoaction_runner.py @@ -138,16 +138,50 @@ class Regelwerk: @staticmethod def signatur_lesen(db): """ - Woran der Runner merkt, dass er neu laden muss. `changed` allein - genuegt nicht: eine geloeschte Automatik veraendert den groessten - Zeitstempel nicht. Deshalb zaehlen die Zeilen mit - auch die der - Geraetetabellen, damit ein Discovery-Lauf ebenfalls durchschlaegt. + Woran der Runner merkt, dass er neu laden muss. + + `changed` allein genuegt nicht: eine geloeschte Automatik veraendert + den groessten Zeitstempel nicht. Die Zeilen zu zaehlen genuegt aber + auch nicht - die Weboberflaeche speichert eine Automatik, indem sie + deren Bedingungen und Aktionen loescht und gleich wieder einfuegt. Wer + nur die Uhrzeit einer Bedingung verstellt, aendert damit weder die + Zeilenzahl noch `changed`: ON UPDATE stoesst nur an, wenn sich in + automations wirklich eine Spalte aendert, und Name, Stockwerk und + Zeitfenster stehen ja noch genauso da. Der Runner lief dann bis zum + naechsten Neustart mit der alten Uhrzeit weiter, ohne dass irgendwo + etwas schieflief - er wusste es schlicht nicht besser. + + Deshalb geht jetzt der Inhalt mit ein, als Summe der CRC32 je Zeile. + Das ist kein Hash mit Sicherheitsanspruch, sondern ein billiger + Fingerabdruck - er wird alle paar Sekunden gebildet und darf nichts + kosten. Zwei Aenderungen, die sich in der Summe gegenseitig aufheben, + sind theoretisch denkbar und praktisch nicht zu erwarten. Die + Zeilenzahl steht trotzdem daneben, damit eine geloeschte und eine neu + angelegte Zeile nicht zufaellig gleich viel ergeben. + + Neu dabei sind die Aktionsparameter. Sie standen vorher gar nicht + drin: eine geaenderte Zielhoehe einer Jalousie schlug also ebenso + wenig durch. + + Die Zeilenzahlen der Geraetetabellen bleiben, damit ein + Discovery-Lauf weiterhin ein Neuladen ausloest. """ with db.cursor() as c: c.execute("""SELECT (SELECT COUNT(*) FROM automations) AS a, (SELECT UNIX_TIMESTAMP(MAX(changed)) FROM automations) AS t, (SELECT COUNT(*) FROM automation_conditions) AS b, + (SELECT COALESCE(SUM(CRC32(CONCAT_WS(':', + id, automation_id, group_no, position, + state_id, operator, value))), 0) + FROM automation_conditions) AS bs, (SELECT COUNT(*) FROM automation_actions) AS c, + (SELECT COALESCE(SUM(CRC32(CONCAT_WS(':', + id, automation_id, position, command_id))), 0) + FROM automation_actions) AS cs, + (SELECT COUNT(*) FROM automation_action_params) AS p, + (SELECT COALESCE(SUM(CRC32(CONCAT_WS(':', + action_id, parameter_id, value))), 0) + FROM automation_action_params) AS ps, (SELECT COUNT(*) FROM actor_states) AS d, (SELECT COUNT(*) FROM actor_commands) AS e""") return tuple(sorted(c.fetchone().items()))