Bruecke faengt auch den zweiten Fehler der Wallbox ab

'lot' steht in der API-Beschreibung als jsonType integer, die Firmware
schickt aber ein Objekt. Die Bibliothek reicht es unveraendert an paho
weiter, paho nimmt nur Skalare - und die Ausnahme riss dieselbe Schleife
mit wie der KeyError auf unbekannte Felder. Im rotierten Log machte
dieser zweite Fehler 1.264.882 von 2.985.071 Zeilen aus.

mqtt_get_encoded_property wird jetzt ebenfalls ersetzt: was nach der
Kodierung kein Skalar ist, geht als JSON hinaus, einmalig mit Warnung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-03 20:42:50 +02:00
co-authored by Claude Opus 5
parent acb443e27a
commit ce2a86fa2b
2 changed files with 49 additions and 6 deletions
+7 -4
View File
@@ -272,10 +272,13 @@ Veröffentlichung, ein Update behebt das also nicht. Die Bibliothek schlug
jedes Feld ungeprüft nach und lief in einen `KeyError`, der die restliche
Schleife mitriss: alles, was in derselben Nachricht dahinter stand, wurde nie
veröffentlicht — im Dauerbetrieb alle 15 Sekunden `fhz`, `lps` und `tpcm`,
nach einem Verbindungsaufbau deutlich mehr. `wattpilot_bruecke.py` ersetzt
die betroffene Funktion zur Laufzeit und überspringt unbekannte Felder, jedes
einmal mit einer Warnung im Log. `startWattpilotMQTT.sh` startet seither die
Brücke statt der `wattpilotshell` direkt.
nach einem Verbindungsaufbau deutlich mehr. Dieselbe Ursache aus der
anderen Richtung traf `lot`: als `integer` beschrieben, als Objekt geschickt,
von paho abgelehnt — gut vier von zehn Zeilen im alten Log.
`wattpilot_bruecke.py` ersetzt beide betroffenen Funktionen zur Laufzeit,
überspringt unbekannte Felder und verschickt Werte notfalls als JSON, jedes
Feld einmal mit einer Warnung im Log. `startWattpilotMQTT.sh` startet seither
die Brücke statt der `wattpilotshell` direkt.
`fetch_calendar.py` gehört einmal jährlich in den Cron:
+42 -2
View File
@@ -22,11 +22,25 @@ alle 16 Sekunden:
ERROR:wattpilot:Error received from WebSocketApp: 'clea'
ERROR:websocket:error from callback ... Wattpilot.__on_message ...: 'clea'
Der zweite Fehler
-----------------
Dieselbe Ursache aus der anderen Richtung: 'lot' steht in der
API-Beschreibung als jsonType 'integer', die Firmware schickt aber ein
Objekt. Die Bibliothek reicht es dann unveraendert an paho weiter, und das
lehnt ab:
ERROR:wattpilot:Error received from WebSocketApp:
payload must be a string, bytearray, int, float or None
Auch dieser Fehler riss die Schleife mit. Im alten Log machte er gut vier von
zehn Zeilen aus.
Die Reparatur
-------------
Unbekannte Felder werden uebersprungen statt zu werfen, jedes einmal mit
einer Warnung im Log. Alle bekannten Felder derselben Nachricht kommen
dadurch durch.
einer Warnung im Log. Werte, die trotz Kodierung kein Skalar sind, gehen als
JSON hinaus statt als Python-Objekt. Alle uebrigen Felder derselben Nachricht
kommen dadurch durch.
Warum hier und nicht in der Bibliothek
--------------------------------------
@@ -51,6 +65,31 @@ _LOG = logging.getLogger("wattpilot.bruecke")
_gemeldet = set()
_original_kodieren = shell.mqtt_get_encoded_property
def mqtt_get_encoded_property(pd, value):
"""Ersatz fuer wattpilotshell.mqtt_get_encoded_property.
Die Bibliothek verpackt nur dann in JSON, wenn die API-Beschreibung den
Wert als Objekt, Liste oder Wahrheitswert fuehrt. Stimmt die Beschreibung
nicht mit dem ueberein, was die Firmware wirklich schickt, kommt ein
dict oder eine list bei paho an - und paho nimmt nur Skalare.
"""
kodiert = _original_kodieren(pd, value)
if kodiert is None or isinstance(kodiert, (str, bytes, bytearray, int, float)):
return kodiert
name = pd.get("key", "?")
if name not in _gemeldet:
_gemeldet.add(name)
_LOG.warning(
"Feld '%s' ist als jsonType %r beschrieben, kommt aber als %s an "
"- wird als JSON veroeffentlicht", name, pd.get("jsonType"),
type(kodiert).__name__)
return json.dumps(kodiert, cls=shell.JSONNamespaceEncoder)
def mqtt_publish_message(event, message):
"""Ersatz fuer wattpilotshell.mqtt_publish_message - siehe Modulkopf."""
wp = event["wp"]
@@ -85,6 +124,7 @@ def mqtt_publish_message(event, message):
shell.mqtt_publish_property(wp, shell.mqtt_client, beschreibung, wert)
shell.mqtt_get_encoded_property = mqtt_get_encoded_property
shell.mqtt_publish_message = mqtt_publish_message
if __name__ == "__main__":