# -*- coding: utf-8 -*- import json import time from collections import defaultdict, deque import numpy as np import paho.mqtt.client as mqtt import matplotlib.pyplot as plt MQTT_BROKER = "s960411f.ala.eu-central-1.emqxsl.com" MQTT_PORT = 8883 MQTT_USER = "cma" MQTT_PASS = "testcma" TOPIC = "can/raw" history = defaultdict(lambda: deque(maxlen=200)) # ---------------------------- # decoded time series # ---------------------------- t_log = [] s1_log = [] s2_log = [] s3_log = [] # ---------------------------- # decode UVR67 frame (0x20D) # ---------------------------- def decode_20d(payload): s1 = payload[0] | (payload[1] << 8) s2 = payload[2] | (payload[3] << 8) s3 = payload[4] | (payload[5] << 8) def conv(x): if x == 0x3FFF or x == 0: return None return x / 10.0 return conv(s1), conv(s2), conv(s3) # ---------------------------- # MQTT callback # ---------------------------- def on_message(client, userdata, msg): try: data = json.loads(msg.payload.decode()) can_id = data["id"] payload = data["data"] timestamp = data.get("ts", time.time()) history[can_id].append((timestamp, payload)) # keep your debug print (but cleaner) if can_id != 0x70D and can_id != 0x1CD: print("ID:", hex(can_id), "Data:", payload) # ---------------------------- # ONLY decode UVR67 temps here # ---------------------------- if can_id == 0x20D: s1, s2, s3 = decode_20d(payload) t_log.append(timestamp) s1_log.append(s1) s2_log.append(s2) s3_log.append(s3) print(f"S1={s1}°C S2={s2}°C S3={s3}°C") except Exception as e: print("Parse error:", e) # ---------------------------- # live plot # ---------------------------- def plot_live(): plt.clf() if len(t_log) < 2: return t0 = t_log[0] t = [x - t0 for x in t_log] plt.title("UVR67 Solar Temperatures") plt.xlabel("Time (s)") plt.ylabel("Temperature (°C)") plt.plot(t, s1_log, label="S1 Collector") plt.plot(t, s2_log, label="S2 Bottom tank") plt.plot(t, s3_log, label="S3 Top tank") plt.legend() plt.grid(True) plt.pause(0.1) # ---------------------------- # MQTT setup # ---------------------------- client = mqtt.Client() client.username_pw_set(MQTT_USER, MQTT_PASS) client.on_message = on_message client.tls_set(ca_certs='./server-ca.crt') client.connect(MQTT_BROKER, MQTT_PORT, 60) client.subscribe(TOPIC, qos=1) client.loop_start() print("Listening for CAN frames...\n") plt.ion() # ---------------------------- # main loop # ---------------------------- while True: time.sleep(1) plot_live()