Discovery: alle Geraete finden und stabil ablegen
Ein Lauf mit allen Modulen brachte 54 Geraete und 441 Messwerte - und fuenf Fehler ans Licht, die vorher niemand sehen konnte, weil clear_tables die Tabellen bei jedem Lauf geleert hat. Vier davon sind Schluessel- und Upsert-Fehler derselben Familie: * command_parameters war ueber (command_id, url) eindeutig. WLED-Parameter haben keine URL - ihr Name ist der Platzhalter in der Kommando-Vorlage -, und eine NULL kollidiert in MySQL nie. ON DUPLICATE KEY UPDATE griff also nicht, und jeder Lauf legte dieselben Parameter erneut an: aus 18 wurden nach drei Laeufen 54. Schluessel jetzt (command_id, parameter_name). * actor_states war ueber (actor_id, url) eindeutig. Umgekehrtes Problem: Messwerte, die sich ein Topic teilen, ueberschrieben einander. Der go-eCharger schickt sechzehn Werte als JSON-Feld auf einem Topic - von denen kam genau einer in der Datenbank an. Schluessel jetzt (actor_id, state_name), das bringt 50 verlorene Messwerte zurueck. * Kommandos, Messwerte und Parameter aktualisierten ihre URL beim Wiederholungslauf nicht - sie stand nicht im UPDATE-Teil. Eine Korrektur in einem Modul kam damit nie in einer bestehenden Datenbank an. * Der Typ eines Kommando-Parameters wurde als Text in eine int-Spalte geschrieben. MariaDB macht daraus stillschweigend 0, und 0 ist "bool" - deshalb bot der Editor fuer die WLED-Helligkeit (0..255) ein Ja/Nein an. Der fuenfte: die Shelly-Gen1-Relais hatten weder eine Kommando-URL noch eine URL am Zustand. Ohne die weiss niemand, was zu schicken und wo nachzusehen ist. Gen1 schaltet ueber ?turn=on|off|toggle und meldet sich in "ison". Damit entfaellt auch die Uebersetzungstabelle im HTTPTransport: die Zuordnung gehoert ins Geraetemodell, nicht in den Runner. Zwei Luecken auf der Runner-Seite, die derselbe Lauf gezeigt hat: * WLED liess sich gar nicht ansteuern - es gab keinen Transport dafuer. Der neue nutzt die JSON-Vorlage aus command_url, fuellt die Platzhalter und schickt sie am Stueck an /json/state. * Tahoma wurde am Schema "io://" erkannt. Das Schema beschreibt aber die Funkart: dieselbe Box liefert rts:// fuer die Dachfenster und internal:// fuer die Alarmanlage. Drei von 22 Geraeten fielen durch. Erkannt wird jetzt an der Box-Kennung in der URL. Nachgemessen: zwei Laeufe hintereinander aendern keine einzige Zeile mehr, die Geraete-IDs bleiben ueber Laeufe stabil (Voraussetzung fuer die Fremdschluessel der Automatiken), alle 54 Geraete finden genau einen Transport, und 440 der 441 Messwerte sind tatsaechlich lesbar. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -365,13 +365,13 @@ class DatabaseManager:
|
||||
INSERT INTO actor_commands (actor_id, command_name, command_url)
|
||||
VALUES (%s, %s, %s)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
command_name = VALUES(command_name)
|
||||
command_url = VALUES(command_url)
|
||||
"""
|
||||
cursor.execute(cmd_query, (actor_id, command_name, command_url))
|
||||
query = """
|
||||
SELECT ID FROM actor_commands where actor_id = %s and command_url = %s
|
||||
SELECT ID FROM actor_commands where actor_id = %s and command_name = %s
|
||||
"""
|
||||
cursor.execute(query, (actor_id, command_url))
|
||||
cursor.execute(query, (actor_id, command_name))
|
||||
command_id = cursor.fetchone()[0]
|
||||
|
||||
# Parameter einfügen
|
||||
@@ -381,14 +381,14 @@ class DatabaseManager:
|
||||
(command_id, parameter_name, parameter_type, min_value, max_value, possible_values, url)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
parameter_name = VALUES(parameter_name),
|
||||
parameter_type = VALUES(parameter_type),
|
||||
min_value = VALUES(min_value),
|
||||
max_value = VALUES(max_value),
|
||||
possible_values = VALUES(possible_values)
|
||||
possible_values = VALUES(possible_values),
|
||||
url = VALUES(url)
|
||||
"""
|
||||
param_name = param.get('name', '')
|
||||
param_type = param.get('type', '')
|
||||
param_type = self.PARAMETER_TYPES_MAPPING.get(param.get('type', ''), 4)
|
||||
min_val = param.get('min')
|
||||
max_val = param.get('max')
|
||||
possible_vals = json.dumps(param.get('values')) if 'values' in param else ""
|
||||
@@ -404,11 +404,11 @@ class DatabaseManager:
|
||||
(actor_id, state_name, state_type, current_value, unit, url, possible_values)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
state_name = VALUES(state_name),
|
||||
state_type = VALUES(state_type),
|
||||
current_value = VALUES(current_value),
|
||||
possible_values = VALUES(possible_values),
|
||||
unit = VALUES(unit)
|
||||
unit = VALUES(unit),
|
||||
url = VALUES(url)
|
||||
"""
|
||||
state_name = state.get('name', '')
|
||||
state_type = self.PARAMETER_TYPES_MAPPING.get(state.get('type', 0), 4)
|
||||
@@ -474,10 +474,10 @@ class DatabaseManager:
|
||||
(actor_id, state_name, state_type, current_value, unit, url)
|
||||
VALUES (%s, %s, %s, %s, %s, %s)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
state_name = VALUES(state_name),
|
||||
state_type = VALUES(state_type),
|
||||
current_value = VALUES(current_value),
|
||||
unit = VALUES(unit)
|
||||
unit = VALUES(unit),
|
||||
url = VALUES(url)
|
||||
"""
|
||||
state_name = state.get('name', '')
|
||||
state_type = self.PARAMETER_TYPES_MAPPING.get(state.get('type', 0), 4)
|
||||
|
||||
Reference in New Issue
Block a user