diff --git a/autoActions/README.md b/autoActions/README.md index e47f6fe..a7123db 100644 --- a/autoActions/README.md +++ b/autoActions/README.md @@ -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: diff --git a/wattpilot_bruecke.py b/wattpilot_bruecke.py index 04f7a93..9d78084 100755 --- a/wattpilot_bruecke.py +++ b/wattpilot_bruecke.py @@ -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__":