Runner merkt jetzt, wenn eine Bedingung geaendert wurde
Die Signatur, an der er ein Neuladen festmacht, bestand aus Zeilenzahlen und MAX(changed). Beides bleibt gleich, wenn in der Weboberflaeche nur die Uhrzeit einer Bedingung verstellt wird: gespeichert wird durch Loeschen und Neueinfuegen, und automations.changed ruehrt sich nicht, weil sich in der Zeile selbst nichts aendert. Der Runner lief dann bis zum naechsten Neustart mit der alten Uhrzeit weiter - ohne dass irgendwo etwas schieflief, er wusste es schlicht nicht besser. Jetzt geht der Inhalt mit ein, als Summe der CRC32 je Zeile. Billig genug fuer die Pruefung alle 30 Sekunden. Neu dabei sind die Aktionsparameter, die vorher gar nicht drinstanden - eine geaenderte Zielhoehe einer Jalousie schlug also ebenso wenig durch. Nachgestellt mit einer Automatik ohne Aktionen: vorher blieb eine reine Bedingungsaenderung wirkungslos, danach loeste sie zwei Sekunden nach der Zielminute aus. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -138,16 +138,50 @@ class Regelwerk:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def signatur_lesen(db):
|
def signatur_lesen(db):
|
||||||
"""
|
"""
|
||||||
Woran der Runner merkt, dass er neu laden muss. `changed` allein
|
Woran der Runner merkt, dass er neu laden muss.
|
||||||
genuegt nicht: eine geloeschte Automatik veraendert den groessten
|
|
||||||
Zeitstempel nicht. Deshalb zaehlen die Zeilen mit - auch die der
|
`changed` allein genuegt nicht: eine geloeschte Automatik veraendert
|
||||||
Geraetetabellen, damit ein Discovery-Lauf ebenfalls durchschlaegt.
|
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:
|
with db.cursor() as c:
|
||||||
c.execute("""SELECT (SELECT COUNT(*) FROM automations) AS a,
|
c.execute("""SELECT (SELECT COUNT(*) FROM automations) AS a,
|
||||||
(SELECT UNIX_TIMESTAMP(MAX(changed)) FROM automations) AS t,
|
(SELECT UNIX_TIMESTAMP(MAX(changed)) FROM automations) AS t,
|
||||||
(SELECT COUNT(*) FROM automation_conditions) AS b,
|
(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 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_states) AS d,
|
||||||
(SELECT COUNT(*) FROM actor_commands) AS e""")
|
(SELECT COUNT(*) FROM actor_commands) AS e""")
|
||||||
return tuple(sorted(c.fetchone().items()))
|
return tuple(sorted(c.fetchone().items()))
|
||||||
|
|||||||
Reference in New Issue
Block a user