#!/usr/local/bin/python3.10 """Startet die wattpilotshell, aber mit einer Reparatur an der MQTT-Bruecke. Das Problem ----------- Die Wallbox schickt in ihren Statusnachrichten Felder, die die API-Beschreibung der Bibliothek (wattpilot 0.2, Stand 2022) nicht kennt - gemessen 34 Stueck, darunter 'clea', 'cle', 'opad' und die ganze 'ocpp*'-Familie. Die Bibliothek schlaegt jedes Feld ungeprueft in ihrem Verzeichnis nach: for prop_name, value in msg_dict["status"].items(): pd = wpdef["properties"][prop_name] # KeyError bei 'clea' mqtt_publish_property(wp, mqtt_client, pd, value) Der KeyError reisst die restliche Schleife mit. Alles, was in derselben Nachricht *hinter* dem unbekannten Feld steht, wird nie veroeffentlicht - beim Verbindungsaufbau trifft das unter anderem 'amp', 'car', 'ust', 'err', 'cbl', 'pha' und 'wh'. Sichtbar wurde das nur als Fehlerpaar im Log, etwa alle 16 Sekunden: ERROR:wattpilot:Error received from WebSocketApp: 'clea' ERROR:websocket:error from callback ... Wattpilot.__on_message ...: 'clea' Die Reparatur ------------- Unbekannte Felder werden uebersprungen statt zu werfen, jedes einmal mit einer Warnung im Log. Alle bekannten Felder derselben Nachricht kommen dadurch durch. Warum hier und nicht in der Bibliothek -------------------------------------- Die Bibliothek liegt unter ~/.local/lib/python3.10/site-packages und damit ausserhalb dieses Repositorys; eine Neuinstallation wuerde eine Aenderung dort spurlos zurueckdrehen. wattpilot 0.2 ist seit Mai 2022 die letzte Veroeffentlichung, ein Update behebt es also nicht. Deshalb steht die Reparatur hier, unter Versionskontrolle, und ersetzt die Funktion zur Laufzeit. mqtt_setup() schlaegt den Namen erst beim Registrieren nach, so dass unsere Fassung greift. """ import json import logging import sys from wattpilot import wattpilotshell as shell _LOG = logging.getLogger("wattpilot.bruecke") # Jedes unbekannte Feld soll genau einmal auffallen, nicht bei jeder Nachricht. _gemeldet = set() def mqtt_publish_message(event, message): """Ersatz fuer wattpilotshell.mqtt_publish_message - siehe Modulkopf.""" wp = event["wp"] if shell.mqtt_client is None: return nachricht = json.loads(message) typ = nachricht["type"] if shell.MQTT_PUBLISH_MESSAGES == "true" and ( shell.MQTT_MESSAGES in ([], [""]) or typ in shell.MQTT_MESSAGES): thema = shell.mqtt_subst_topic(shell.MQTT_TOPIC_MESSAGES, { "baseTopic": shell.MQTT_TOPIC_BASE, "serialNumber": wp.serial, "messageType": typ, }) shell.mqtt_client.publish(thema, message) if shell.MQTT_PUBLISH_PROPERTIES != "true" or typ not in ("fullStatus", "deltaStatus"): return eigenschaften = shell.wpdef["properties"] for name, wert in nachricht["status"].items(): beschreibung = eigenschaften.get(name) if beschreibung is None: if name not in _gemeldet: _gemeldet.add(name) _LOG.warning( "Feld '%s' steht nicht in der API-Beschreibung der " "Bibliothek - wird uebersprungen (Wert: %.80s)", name, repr(wert)) continue shell.mqtt_publish_property(wp, shell.mqtt_client, beschreibung, wert) shell.mqtt_publish_message = mqtt_publish_message if __name__ == "__main__": try: sys.exit(shell.main()) except KeyboardInterrupt: sys.exit(0)