import sys import dataclasses import logging import json sys.path.append("./") import paho.mqtt.client as mqtt logging.config.fileConfig('./logging.ini') _LOGGER = logging.getLogger() class EnhancedJSONEncoder(json.JSONEncoder): def default(self, o): if dataclasses.is_dataclass(o): return dataclasses.asdict(o) return super().default(o) unacked_publish = set() mqttClient=mqtt.Client(mqtt.CallbackAPIVersion.VERSION2) #mqttClient.on_publish = on_publish mqttClient.user_data_set(unacked_publish) logging.basicConfig( format="%(asctime)s %(message)s", level=logging.WARN, ) def publish(dict,topic="solarManager"): if dataclasses.is_dataclass(dict): for field in dataclasses.fields(dict): key = field.name value = getattr(dict, field.name) if hasattr(value, '__len__') and (not isinstance(value, str)): if dataclasses.is_dataclass(value): #make subtopics of dataclasses publish(value,topic+"/"+key) else: #try: #make subtopics of dataclass arrays if len(value): if dataclasses.is_dataclass(value[0]): i=0 for d in value: publish(d,topic+"/"+key+str(i)) i=i+1 #except: else: mqttClient.publish(topic+"/"+key,json.dumps(value, cls=EnhancedJSONEncoder)) else: #output empty array anyway to keep data consistent mqttClient.publish(topic+"/"+key,json.dumps(value, cls=EnhancedJSONEncoder)) else: try: flt = float(value) mqttClient.publish(topic+"/"+key,round(flt,2)) except ValueError: mqttClient.publish(topic+"/"+key,value) else: for key, value in dict.items(): # Ein einzelnes Dataclass-Objekt (z.B. rtData["byd"]) hat keine # Laenge und fiel frueher in den Zahlenzweig - "value is no number". if dataclasses.is_dataclass(value) and not isinstance(value, type): publish(value,topic+"/"+key) elif hasattr(value, '__len__') and (not isinstance(value, str)): if dataclasses.is_dataclass(value): #make subtopics of dataclasses publish(value,topic+"/"+key) else: #try: #make subtopics of dataclass arrays if len(value): if dataclasses.is_dataclass(value[0]): i=0 for d in value: publish(d,topic+"/"+key+str(i)) i=i+1 #except: else: mqttClient.publish(topic+"/"+key,json.dumps(value, cls=EnhancedJSONEncoder)) else: #output empty array anyway to keep data consistent mqttClient.publish(topic+"/"+key,json.dumps(value, cls=EnhancedJSONEncoder)) else: try: flt = float(value) mqttClient.publish(topic+"/"+key,round(flt,2)) except ValueError: mqttClient.publish(topic+"/"+key,value) except: _LOGGER.error(f"value is no number") #print(message) def startMqttClient(): mqttClient.connect("localhost", 1883, 60) mqttClient.loop_start() #await asyncio.Future() # run forever def closeMqttClient(): mqttClient.disconnect()