├── README.md ├── image.png ├── linux ├── mqtt_config.txt ├── points.txt └── send_data_linux.py └── win ├── 10点位测.txt ├── 20点位测试.txt ├── 50点位测试 .txt └── send_data_win.py /README.md: -------------------------------------------------------------------------------- 1 | # mqtt_data_mock 2 | 将数据通过mqtt推送到服务端,支持windows及linux操作系统 3 | ![alt text](image.png) 4 | 5 | 主要功能: 6 | 1. 作为MQTT客户端,能让用户手动设置MQTT的IP 端口 用户名,并且能随机/手动输入客户端ID,默认MQTT版本5.0,连接超时时长10秒,keep alive 60秒。 7 | 2. 用户设置完后,可以点击连接按钮进行测试,测试通过后,进行连接。 8 | 3. 连接成功后,可以让用户手动选择txt文本进行导入,txt文本中包含多个点位信息,以英文逗号隔开,如: iot1,iot2,iot3 9 | 4. 导入完成后,给对应的MQTT发送消息,发送消息格式为JSON,内容如下: 10 | 5. 其中iot1、iot2等是从刚才的txt中取得,具体test1、test2,是固定的,需要从test1到test200,对应的数值随机,从-100到100,可以有两位小数。按每秒一次的频率进行数据发送。 11 | 6. 界面提供开始测试按钮,提供一个计数器,提示程序运行时间(时分秒格式) 12 | 13 | 推送数据格式: 14 | 15 | ``` 16 | { 17 | "iot1": [{ 18 | "test1": 3.8, 19 | "test2": 3.0, 20 | "test3": 3.0 21 | }], 22 | "iot2": [{ 23 | "test1": 3.8, 24 | "test2": 3.0, 25 | "test3": 3.0 26 | }], 27 | "iot3": [{ 28 | "test1": 3.8, 29 | "test2": 3.0, 30 | "test3": 3.0 31 | }] 32 | } 33 | ``` 34 | 35 | -------------------------------------------------------------------------------- /image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/l56jq/mqtt_data_mock/785a988dac1cf3677a30f3ef3b3f8294127e6ffe/image.png -------------------------------------------------------------------------------- /linux/mqtt_config.txt: -------------------------------------------------------------------------------- 1 | mqtt_ip=127.0.0.1 2 | mqtt_port=1885 3 | mqtt_username=SlIPlC12txs7HGtTuGGb 4 | topic=v1/gateway/telemetry 5 | hours=2 -------------------------------------------------------------------------------- /linux/points.txt: -------------------------------------------------------------------------------- 1 | iotFBB3EFCEEDE7731940F69A28FF464238,iot4366A9C241C4390D3978CAAE24FF38D9,tr1B91844F369C244DB513C5319DA0A53D,trE6A0D4F85269AEF8A060F2555178C0CB,tr2EC3770F5D54426992AF325D472450F9,trF44DB7D6F6E6A744CE55CAC79E624ECF,tr0177A850B16E2BFE43665FB71B942E3B,trFC6427F18B5B1D3EF78BF8D93258BD12,tr5C61774F326F60E6888FEA96142E8EE7,tr0EBE19951ABD17820D0367EB3F58A601,tr75E7602EE519D1D3EEDA91E356A06E03,trECAEE2B306F3141AFC5070C1966E63C0,tr6FD769CB2A85399CF624D86F6F9E8821,tr4EC9AEC49DFC5955CC4AEF0CB9AB5890,trD8973D6DDD9F3D25F426E56CD41FA0DD,trDFC8614143BE9EDDD8618CE4B5737673,tr10194EF97DAEE06DCC62C62D7ADAAC3B,trCBB8FE42915BE1A5FF0AF837FF134AB5,tr4DDF6B5D20CB71D6D17F511736952B9B,tr52F47708D0B976101FA7CE7E373160A8,trEE8D1EBBA8696CE360D6E2515D97824A,tr300716BA41EFB2ACB2ABC2A81661BADC,trA7A7AEDDDDAA0B74136BD497977B5625,tr7A7DF9EE7976B16619F4BB44B436360C,tr9CE9B7D984211EB4E60CC5817494605D,tr1DD56F4DB5E2694F971A21DC8ADB2B0E,tr64AA063FDD5622CCD940E7350CBB1556,tr419EAAE45EDF75D75178DD60988A37BD,trBF1EE06D48F159A1D0570CC2EA2AE2B6,trFD9D53AD7F4A8140C8769E12450F1634,trB509CCC02945B4253E464ECD4AAD8024,trB741A493225618B24121A9F2AA924614,trF4D0FD01507DFA302DF879A8A2FD3938,trDB7D26D05DBE493AC221D1C3C09F7B1E,trA044A34B40C9BC59B0A125B0B102334C,trAA32184F89CDDEB6C7AEF432AE412DA9,trF46901CC5B0350CDF6B7A9122F290E58,tr9AF57402970886C12D2EC6EAC1C5CC5D,tr18FE8D6A55FBA6B0105F4509269CEFE8,tr4F5905D9CFD76005BC03B153645FA92C,tr965DA388921655B8B21598B4C5E70193,trFCCC85510A3A6B91028BF6B813008EE2,trC34ED6352DF5B147CF7046D0573E87F2,tr725D052C26F112F8E603F7AAE1C73D71,trF224728F9B5895E921F92662D603F7C0,trBABA876CDAAEDEF9676B2E4A8832A320,trA705602CC96AA1784CDAEAB59070606C,tr2A83E904F159732F3BA3EDE466123259,tr80DFEB1ADB31A649CD5A490F43C6B86F,trBB0C176A6E64CB82DE94AC2AA6EAF988 -------------------------------------------------------------------------------- /linux/send_data_linux.py: -------------------------------------------------------------------------------- 1 | import paho.mqtt.client as mqtt 2 | import random 3 | import time 4 | import json 5 | from datetime import datetime, timedelta 6 | import threading 7 | 8 | 9 | # 加载配置文件 10 | def load_config(file_path): 11 | config = {} 12 | try: 13 | with open(file_path, 'r') as file: 14 | for line in file: 15 | key, value = line.strip().split('=') 16 | config[key.strip()] = value.strip() 17 | except FileNotFoundError: 18 | print(f"Configuration file {file_path} not found.") 19 | except Exception as e: 20 | print(f"Error reading configuration file: {e}") 21 | return config 22 | 23 | 24 | # MQTT 连接回调 25 | def on_connect(client, userdata, flags, rc): 26 | if rc == 0: 27 | print("Connected to MQTT broker.") 28 | else: 29 | print(f"Failed to connect, return code {rc}") 30 | 31 | 32 | # 发送数据的函数,每个点位单独一个线程 33 | def send_data(client, point, topic): 34 | global running 35 | while running: 36 | data = { 37 | point: [{ 38 | f"test{i}": round(random.uniform(-100, 100), 2) for i in range(1, 201) 39 | }] 40 | } 41 | payload = json.dumps(data) 42 | client.publish(topic, payload) 43 | data_sent_count[point] += 1 44 | time.sleep(1) # 每秒发送一次 45 | 46 | 47 | # 主程序 48 | if __name__ == "__main__": 49 | config_path = 'mqtt_config.txt' # 配置文件路径 50 | config = load_config(config_path) 51 | 52 | if not config: 53 | print("Configuration loading failed, exiting.") 54 | exit(1) 55 | 56 | client_id = f'client_{random.randint(1000, 9999)}' 57 | 58 | mqtt_ip = config.get("mqtt_ip", "") 59 | mqtt_port = int(config.get("mqtt_port", 1883)) 60 | mqtt_username = config.get("mqtt_username", "") 61 | topic = config.get("topic", "") 62 | hours = int(config.get("hours", 1)) 63 | 64 | points_path = 'points.txt' 65 | try: 66 | with open(points_path, 'r') as file: 67 | points = file.read().strip().split(',') 68 | except FileNotFoundError: 69 | print(f"Points file {points_path} not found.") 70 | exit(1) 71 | 72 | data_sent_count = {point: 0 for point in points} 73 | running = True 74 | 75 | mqtt_client = mqtt.Client(client_id=client_id) 76 | mqtt_client.username_pw_set(mqtt_username) 77 | mqtt_client.on_connect = on_connect 78 | 79 | try: 80 | mqtt_client.connect(mqtt_ip, mqtt_port, keepalive=120) 81 | mqtt_client.loop_start() 82 | except Exception as e: 83 | print(f"Error connecting to MQTT broker: {e}") 84 | running = False 85 | 86 | start_time = datetime.now() 87 | print(f"Start time: {start_time}") 88 | 89 | # 计算最大运行时间 90 | max_duration = timedelta(hours=hours) 91 | end_time_limit = start_time + max_duration 92 | 93 | try: 94 | # 为每个点位启动一个线程 95 | threads = [] 96 | for point in points: 97 | thread = threading.Thread(target=send_data, args=(mqtt_client, point, topic)) 98 | thread.start() 99 | threads.append(thread) 100 | 101 | while running and datetime.now() < end_time_limit: 102 | time.sleep(1) 103 | 104 | running = False # 停止所有线程 105 | for thread in threads: 106 | thread.join() 107 | except KeyboardInterrupt: 108 | running = False 109 | for thread in threads: 110 | thread.join() # 等待所有数据发送线程结束 111 | finally: 112 | mqtt_client.loop_stop() 113 | mqtt_client.disconnect() 114 | 115 | end_time = datetime.now() 116 | print(f"End time: {end_time}") 117 | 118 | duration = end_time - start_time 119 | print(f"Total running time: {duration}") 120 | print("Data sent count:", data_sent_count) 121 | -------------------------------------------------------------------------------- /win/10点位测.txt: -------------------------------------------------------------------------------- 1 | iotFBB3EFCEEDE7731940F69A28FF464238,iot4366A9C241C4390D3978CAAE24FF38D9,tr1B91844F369C244DB513C5319DA0A53D,trE6A0D4F85269AEF8A060F2555178C0CB,tr2EC3770F5D54426992AF325D472450F9,trF44DB7D6F6E6A744CE55CAC79E624ECF,tr0177A850B16E2BFE43665FB71B942E3B,trFC6427F18B5B1D3EF78BF8D93258BD12,tr5C61774F326F60E6888FEA96142E8EE7,tr0EBE19951ABD17820D0367EB3F58A601 -------------------------------------------------------------------------------- /win/20点位测试.txt: -------------------------------------------------------------------------------- 1 | iotFBB3EFCEEDE7731940F69A28FF464238,iot4366A9C241C4390D3978CAAE24FF38D9,tr1B91844F369C244DB513C5319DA0A53D,trE6A0D4F85269AEF8A060F2555178C0CB,tr2EC3770F5D54426992AF325D472450F9,trF44DB7D6F6E6A744CE55CAC79E624ECF,tr0177A850B16E2BFE43665FB71B942E3B,trFC6427F18B5B1D3EF78BF8D93258BD12,tr5C61774F326F60E6888FEA96142E8EE7,tr0EBE19951ABD17820D0367EB3F58A601,tr75E7602EE519D1D3EEDA91E356A06E03,trECAEE2B306F3141AFC5070C1966E63C0,tr6FD769CB2A85399CF624D86F6F9E8821,tr4EC9AEC49DFC5955CC4AEF0CB9AB5890,trD8973D6DDD9F3D25F426E56CD41FA0DD,trDFC8614143BE9EDDD8618CE4B5737673,tr10194EF97DAEE06DCC62C62D7ADAAC3B,trCBB8FE42915BE1A5FF0AF837FF134AB5,tr4DDF6B5D20CB71D6D17F511736952B9B,tr52F47708D0B976101FA7CE7E373160A8 -------------------------------------------------------------------------------- /win/50点位测试 .txt: -------------------------------------------------------------------------------- 1 | iotFBB3EFCEEDE7731940F69A28FF464238,iot4366A9C241C4390D3978CAAE24FF38D9,tr1B91844F369C244DB513C5319DA0A53D,trE6A0D4F85269AEF8A060F2555178C0CB,tr2EC3770F5D54426992AF325D472450F9,trF44DB7D6F6E6A744CE55CAC79E624ECF,tr0177A850B16E2BFE43665FB71B942E3B,trFC6427F18B5B1D3EF78BF8D93258BD12,tr5C61774F326F60E6888FEA96142E8EE7,tr0EBE19951ABD17820D0367EB3F58A601,tr75E7602EE519D1D3EEDA91E356A06E03,trECAEE2B306F3141AFC5070C1966E63C0,tr6FD769CB2A85399CF624D86F6F9E8821,tr4EC9AEC49DFC5955CC4AEF0CB9AB5890,trD8973D6DDD9F3D25F426E56CD41FA0DD,trDFC8614143BE9EDDD8618CE4B5737673,tr10194EF97DAEE06DCC62C62D7ADAAC3B,trCBB8FE42915BE1A5FF0AF837FF134AB5,tr4DDF6B5D20CB71D6D17F511736952B9B,tr52F47708D0B976101FA7CE7E373160A8,trEE8D1EBBA8696CE360D6E2515D97824A,tr300716BA41EFB2ACB2ABC2A81661BADC,trA7A7AEDDDDAA0B74136BD497977B5625,tr7A7DF9EE7976B16619F4BB44B436360C,tr9CE9B7D984211EB4E60CC5817494605D,tr1DD56F4DB5E2694F971A21DC8ADB2B0E,tr64AA063FDD5622CCD940E7350CBB1556,tr419EAAE45EDF75D75178DD60988A37BD,trBF1EE06D48F159A1D0570CC2EA2AE2B6,trFD9D53AD7F4A8140C8769E12450F1634,trB509CCC02945B4253E464ECD4AAD8024,trB741A493225618B24121A9F2AA924614,trF4D0FD01507DFA302DF879A8A2FD3938,trDB7D26D05DBE493AC221D1C3C09F7B1E,trA044A34B40C9BC59B0A125B0B102334C,trAA32184F89CDDEB6C7AEF432AE412DA9,trF46901CC5B0350CDF6B7A9122F290E58,tr9AF57402970886C12D2EC6EAC1C5CC5D,tr18FE8D6A55FBA6B0105F4509269CEFE8,tr4F5905D9CFD76005BC03B153645FA92C,tr965DA388921655B8B21598B4C5E70193,trFCCC85510A3A6B91028BF6B813008EE2,trC34ED6352DF5B147CF7046D0573E87F2,tr725D052C26F112F8E603F7AAE1C73D71,trF224728F9B5895E921F92662D603F7C0,trBABA876CDAAEDEF9676B2E4A8832A320,trA705602CC96AA1784CDAEAB59070606C,tr2A83E904F159732F3BA3EDE466123259,tr80DFEB1ADB31A649CD5A490F43C6B86F,trBB0C176A6E64CB82DE94AC2AA6EAF988 -------------------------------------------------------------------------------- /win/send_data_win.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter import filedialog, messagebox 3 | import json 4 | import random 5 | import time 6 | import os 7 | import threading 8 | import paho.mqtt.client as mqtt 9 | 10 | 11 | class MQTTClientApp: 12 | def __init__(self, root): 13 | self.root = root 14 | self.root.title("MQTT Client") 15 | self.root.geometry("800x600") 16 | self.root.resizable(False, False) # Disable window resizing 17 | 18 | # MQTT Configuration 19 | self.config_file = "mqtt_config.json" 20 | self.mqtt_ip = tk.StringVar() 21 | self.mqtt_port = tk.IntVar() 22 | self.mqtt_username = tk.StringVar() 23 | self.client_id = tk.StringVar() 24 | self.topic = tk.StringVar() 25 | 26 | self.load_config() 27 | 28 | if not self.client_id.get(): 29 | self.client_id.set(f'client_{random.randint(1000, 9999)}') 30 | 31 | self.mqtt_client = None 32 | self.running = False 33 | self.points = [] 34 | self.threads = [] 35 | self.data_sent_count = {point: 0 for point in self.points} 36 | 37 | # UI Elements 38 | self.create_widgets() 39 | 40 | def create_widgets(self): 41 | # 居中框架 42 | self.center_frame = tk.Frame(self.root) 43 | self.center_frame.place(relx=0.5, rely=0.5, anchor=tk.CENTER) 44 | 45 | # 输入框和标签 46 | self.add_label_entry("MQTT IP:", self.mqtt_ip, 0) 47 | self.add_label_entry("MQTT Port:", self.mqtt_port, 1) 48 | self.add_label_entry("MQTT Username:", self.mqtt_username, 2) 49 | self.add_label_entry("Client ID:", self.client_id, 3) 50 | self.add_label_entry("MQTT Topic:", self.topic, 4) 51 | 52 | # 按钮 53 | self.connect_button = tk.Button(self.center_frame, text="Connect", command=self.connect_to_mqtt) 54 | self.connect_button.grid(row=5, column=0, padx=5, pady=5, sticky='e') 55 | 56 | self.disconnect_button = tk.Button(self.center_frame, text="Disconnect", command=self.disconnect_from_mqtt, 57 | state=tk.DISABLED) 58 | self.disconnect_button.grid(row=5, column=1, padx=5, pady=5, sticky='w') 59 | 60 | self.import_button = tk.Button(self.center_frame, text="Import Points", command=self.import_points, 61 | state=tk.DISABLED) 62 | self.import_button.grid(row=6, column=0, columnspan=2, pady=10) 63 | 64 | self.start_button = tk.Button(self.center_frame, text="Start Test", command=self.start_test, state=tk.DISABLED) 65 | self.start_button.grid(row=7, column=0, padx=5, pady=5, sticky='e') 66 | 67 | self.stop_button = tk.Button(self.center_frame, text="Stop Test", command=self.stop_test, state=tk.DISABLED) 68 | self.stop_button.grid(row=7, column=1, padx=5, pady=5, sticky='w') 69 | 70 | # Status Labels 71 | self.status_label = tk.Label(self.center_frame, text="Status: Disconnected", bg="lightblue", font=('Arial', 10)) 72 | self.status_label.grid(row=8, column=0, columnspan=2, pady=10) 73 | 74 | self.time_label = tk.Label(self.center_frame, text="Time Elapsed: 00:00:00", bg="lightblue", font=('Arial', 10)) 75 | self.time_label.grid(row=9, column=0, columnspan=2, pady=10) 76 | 77 | self.points_label = tk.Label(self.center_frame, text="Imported Points: None", bg="lightblue", 78 | font=('Arial', 10)) 79 | 80 | # 停止时间标签 81 | self.stop_time_label = tk.Label(self.center_frame, text="Stop Time: Not stopped yet", bg="lightblue", font=('Arial', 10)) 82 | self.stop_time_label.grid(row=11, column=0, columnspan=2, pady=10) 83 | 84 | self.points_label.grid(row=10, column=0, columnspan=2, pady=10) 85 | 86 | def add_label_entry(self, text, var, row): 87 | label = tk.Label(self.center_frame, text=text, bg="lightblue", font=('Arial', 10)) 88 | label.grid(row=row, column=0, padx=5, pady=5, sticky='e') 89 | entry = tk.Entry(self.center_frame, textvariable=var, width=30, font=('Arial', 10)) 90 | entry.grid(row=row, column=1, padx=5, pady=5, sticky='w') 91 | 92 | def load_config(self): 93 | if os.path.exists(self.config_file): 94 | with open(self.config_file, 'r') as file: 95 | config = json.load(file) 96 | self.mqtt_ip.set(config.get("mqtt_ip", "")) 97 | self.mqtt_port.set(config.get("mqtt_port", 1883)) 98 | self.mqtt_username.set(config.get("mqtt_username", "")) 99 | self.client_id.set(config.get("client_id", "")) 100 | self.topic.set(config.get("topic", "")) 101 | 102 | def save_config(self): 103 | config = { 104 | "mqtt_ip": self.mqtt_ip.get(), 105 | "mqtt_port": self.mqtt_port.get(), 106 | "mqtt_username": self.mqtt_username.get(), 107 | "client_id": self.client_id.get(), 108 | "topic": self.topic.get() 109 | } 110 | with open(self.config_file, 'w') as file: 111 | json.dump(config, file) 112 | 113 | def connect_to_mqtt(self): 114 | try: 115 | self.mqtt_client = mqtt.Client(client_id=self.client_id.get()) 116 | self.mqtt_client.username_pw_set(self.mqtt_username.get()) 117 | self.mqtt_client.on_connect = self.on_connect 118 | self.mqtt_client.on_disconnect = self.on_disconnect 119 | # self.mqtt_client.on_log = self.on_log # Optional: log MQTT events for debugging 120 | self.mqtt_client.connect(self.mqtt_ip.get(), self.mqtt_port.get(), keepalive=120) 121 | self.mqtt_client.loop_start() 122 | self.status_label.config(text="Status: Connecting...") 123 | self.save_config() 124 | except Exception as e: 125 | messagebox.showerror("Error", f"Failed to connect to MQTT: {str(e)}") 126 | 127 | def on_connect(self, client, userdata, flags, rc): 128 | if rc == 0: 129 | self.status_label.config(text="Status: Connected") 130 | self.connect_button.config(state=tk.DISABLED) 131 | self.disconnect_button.config(state=tk.NORMAL) 132 | self.import_button.config(state=tk.NORMAL) 133 | self.start_button.config(state=tk.NORMAL) 134 | else: 135 | self.status_label.config(text=f"Status: Connection failed (rc={rc})") 136 | 137 | def on_disconnect(self, client, userdata, rc): 138 | self.status_label.config(text="Status: Disconnected") 139 | self.connect_button.config(state=tk.NORMAL) 140 | self.disconnect_button.config(state=tk.DISABLED) 141 | self.import_button.config(state=tk.DISABLED) 142 | self.start_button.config(state=tk.DISABLED) 143 | self.stop_button.config(state=tk.DISABLED) 144 | if self.running: 145 | self.connect_to_mqtt() # Attempt to reconnect if running 146 | 147 | def on_log(self, client, userdata, level, buf): 148 | print(f"Log: {buf}") 149 | 150 | def disconnect_from_mqtt(self): 151 | self.running = False 152 | if self.mqtt_client: 153 | self.mqtt_client.loop_stop() 154 | self.mqtt_client.disconnect() 155 | self.mqtt_client = None 156 | self.status_label.config(text="Status: Disconnected") 157 | self.connect_button.config(state=tk.NORMAL) 158 | self.disconnect_button.config(state=tk.DISABLED) 159 | self.import_button.config(state=tk.DISABLED) 160 | self.start_button.config(state=tk.DISABLED) 161 | self.stop_button.config(state=tk.DISABLED) 162 | 163 | def import_points(self): 164 | file_path = filedialog.askopenfilename(filetypes=[("Text files", "*.txt")]) 165 | if file_path: 166 | with open(file_path, 'r') as file: 167 | self.points = file.read().strip().split(',') 168 | # self.points_label.config(text=f"Imported Points: {', '.join(self.points)}") 169 | self.data_sent_count = {point: 0 for point in self.points} 170 | self.show_points_and_stats() 171 | 172 | def show_points_and_stats(self): 173 | stats_window = tk.Toplevel(self.root) 174 | stats_window.title("Point Information") 175 | stats_window.geometry("300x400") 176 | 177 | tk.Label(stats_window, text="Points Information:", bg="lightblue").pack(pady=10) 178 | 179 | self.points_listbox = tk.Listbox(stats_window) 180 | self.points_listbox.pack(padx=10, pady=10, fill=tk.BOTH, expand=True) 181 | 182 | self.update_points_listbox() 183 | 184 | stats_label = tk.Label(stats_window, text="Data Sent Count:", bg="lightblue") 185 | stats_label.pack(pady=10) 186 | 187 | self.stats_count_label = tk.Label(stats_window, text="", bg="lightblue") 188 | self.stats_count_label.pack(pady=10) 189 | 190 | # self.update_stats_window() 191 | 192 | def update_points_listbox(self): 193 | self.points_listbox.delete(0, tk.END) 194 | for point in self.points: 195 | self.points_listbox.insert(tk.END, point) 196 | 197 | def start_test(self): 198 | if not self.mqtt_client: 199 | messagebox.showwarning("Warning", "Please connect to MQTT first.") 200 | return 201 | if not self.points: 202 | messagebox.showwarning("Warning", "Please import points first.") 203 | return 204 | 205 | self.running = True 206 | self.data_sent_count = {point: 0 for point in self.points} 207 | self.start_time = time.time() 208 | self.update_timer() 209 | 210 | # Start a thread for each point to send data 211 | self.threads = [] 212 | for point in self.points: 213 | t = threading.Thread(target=self.send_data_for_point, args=(point,)) 214 | t.start() 215 | self.threads.append(t) 216 | 217 | self.start_button.config(state=tk.DISABLED) 218 | self.stop_button.config(state=tk.NORMAL) 219 | 220 | def stop_test(self): 221 | self.running = False 222 | for t in self.threads: 223 | t.join() # Wait for all threads to finish 224 | 225 | # 更新停止时间 226 | stop_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) 227 | self.stop_time_label.config(text=f"Stop Time: {stop_time}") 228 | 229 | self.stop_button.config(state=tk.DISABLED) 230 | self.start_button.config(state=tk.NORMAL) 231 | 232 | def update_timer(self): 233 | if self.running: 234 | elapsed_time = int(time.time() - self.start_time) 235 | hours, remainder = divmod(elapsed_time, 3600) 236 | minutes, seconds = divmod(remainder, 60) 237 | self.time_label.config(text=f"Time Elapsed: {hours:02}:{minutes:02}:{seconds:02}") 238 | self.root.after(1000, self.update_timer) 239 | 240 | def send_data_for_point(self, point): 241 | while self.running: 242 | data = { 243 | point: [{ 244 | f"test{i}": round(random.uniform(-100, 100), 2) for i in range(1, 201) 245 | }] 246 | } 247 | payload = json.dumps(data) 248 | self.mqtt_client.publish(self.topic.get(), payload) 249 | self.data_sent_count[point] += 1 250 | time.sleep(1) # Send data every second 251 | 252 | def on_closing(self): 253 | self.running = False 254 | if self.mqtt_client: 255 | self.mqtt_client.loop_stop() 256 | self.root.destroy() 257 | 258 | 259 | if __name__ == "__main__": 260 | root = tk.Tk() 261 | app = MQTTClientApp(root) 262 | root.protocol("WM_DELETE_WINDOW", app.on_closing) 263 | root.mainloop() 264 | --------------------------------------------------------------------------------