利用python进行mqtt数据存储并绘图制excel表
因为毕设在做医疗类产品,想着拓展功能方面想要实现记录先前治疗数据。先前想着用小程序可视化,但无奈前端难度还是有些大,小程序一下想上手发现没那么容易,而后发现python这个好工具。(但想更加方便,家用医疗可能还是小程序方便得多,日后定学!)
存储数据功能实现
首先现在官网下载下python,他的安装有些不一样,在程序窗口里而且全英,可以跟着教程安装。随后安装完成后,先按win+R,输入cmd再按回车进入界面,输入pip install paho-mqtt,安装相应库让电脑具备 MQTT 通信能力。随后开始编写代码把对电脑通过mqtt协议接收到的数据进行监视存储。
先新建一个文件夹(往后存储数据.db形式也会自动放在文件夹中),新建一个文本txt文件,将其改名为save_data.py,后缀需要改为.py。后续打开用继续用记事本打开改代码。代码如下:
import paho.mqtt.client as mqtt
import json
import sqlite3
import time
db_file = 'medical_wave_data.db'
last_save_time = "" # 放在最顶格
def on_message(client, userdata, msg):
global last_save_time # 缩进 4 个空格
try:
data = json.loads(msg.payload.decode())
current_time = time.strftime('%Y-%m-%d %H:%M:%S')
# 防止 1 秒内重复存入
if current_time == last_save_time:
return
last_save_time = current_time
conn = sqlite3.connect(db_file)
cursor = conn.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS wave_records (id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp DATETIME, freq INTEGER, wave TEXT)")
cursor.execute("INSERT INTO wave_records (timestamp, freq, wave) VALUES (?, ?, ?)",
(current_time, data['freq'], json.dumps(data['data'])))
cursor.execute("DELETE FROM wave_records WHERE timestamp < datetime('now', 'localtime', '-1 minutes')")
conn.commit()
cursor.execute("SELECT COUNT(*) FROM wave_records")
count = cursor.fetchone()[0]
conn.close()
print(f"[{current_time}] 备份成功!当前总数: {count}")
except Exception as e:
print(f"处理数据时出错: {e}")
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
client.on_message = on_message
client.connect("broker.emqx.io", 1883, 60)
client.subscribe("gdut/test/wave")
print("服务已重新启动,正在监听...")
client.loop_forever()
这里我代码是只保存1min内的数据,到一定数据量后开始删最旧的数据,防止数据太大。进行数据量控制。改时间直接把cursor.execute("DELETE FROM wave_records WHERE timestamp < datetime('now', 'localtime', '-1 minutes')")的'-1 minutes'改成'-1 days'即可。
而后按win+R,输入cmd再按回车进入界面。输入盘的位置,我的是D,所以输入D:然后按回车。然后在输入cd "D:\desktop\新建文件夹\datasaving",引号内为我存储py的文件夹位置,而后在输入python save_data.py,后面为自设的文件名。再按回车就跳至存储模式。

实时数据折线图可视化
先按照先前流程,进入界面直接输入pip install matplotlib回车,安装库。
然后在先前新建的文件夹下再新建一个txt,将其改名为draw_wave.py。
输入代码如下
import sqlite3
import json
import matplotlib.pyplot as plt
# 1. 连接数据库
conn = sqlite3.connect('medical_wave_data.db')
cursor = conn.cursor()
# 2. 取出最新的一条记录
try:
cursor.execute("SELECT timestamp, wave FROM wave_records ORDER BY id DESC LIMIT 1")
row = cursor.fetchone()
except Exception as e:
print(f"数据库读取失败: {e}")
row = None
conn.close()
if row:
timestamp, wave_str = row
wave_data = json.loads(wave_str) # 把存进去的文本转回数字列表
# 3. 开始绘图
plt.figure(figsize=(10, 5))
plt.plot(wave_data, marker='o', linestyle='-', color='r', markersize=4)
plt.title(f"Latest Pulse Waveform ({timestamp})")
plt.xlabel("Sample Points (0-49)")
plt.ylabel("ADC Value / Current")
plt.grid(True)
# 4. 展示图片
print(f"正在显示时间点 {timestamp} 的波形...")
plt.show()
else:
print("数据库还是空的,请先运行 save_data.py 存入一些数据!")
再按先前步骤,按win+R,输入cmd再按回车进入界面。输入你的盘的位置,我的是D,所以输入D:然后按回车。然后在输入cd "D:\desktop\新建文件夹\datasaving",引号内为我存储py的文件夹位置,而后在输入draw_wave.py,再回车即可得到下图。

然后可以发现,现在的图是具体时刻的一组数据,并非先前的数据全部一起显示出来。这里我一组数据是一个有50个数的数组,所以显示比较多,但实际上只是一组数据,所以这才又引入新的excel整合可视化先前所有数据。
将数据以excel形式表现
这里需要安装两个库,pip install pandas,pip install openpyxl,其中pandas负责数据处理,并整理成csv格式的50列数据,openpyxl负责将其整理转化成xlsx格式。
然后再在那个新文件夹下,在新建个txt文本,改后缀为excel_history.py,再像先前一样运行,即可形成excel表格。代码如下:
import sqlite3
import pandas as pd
import json
# 1. 配置参数
db_name = 'medical_wave_data.db'
excel_name = '医疗波形历史数据导出.xlsx'
def export():
try:
# 2. 连接数据库并读取
conn = sqlite3.connect(db_name)
# 获取所有数据
df = pd.read_sql_query("SELECT * FROM wave_records ORDER BY timestamp ASC", conn)
conn.close()
if df.empty:
print("数据库目前是空的,没有数据可以导出。")
return
# 3. 处理波形数据(把字符串变成 Excel 的多列)
print("正在解析波形点,请稍候...")
# 定义一个函数:把 JSON 字符串转为 Series (多列)
def parse_wave(wave_str):
points = json.loads(wave_str)
# 给这 50 个点取名:点1, 点2...
return pd.Series(points, index=[f'Point_{i+1}' for i in range(len(points))])
# 执行拆分:把原来的 'wave' 列拆掉,变成 50 列新数据
wave_columns = df['wave'].apply(parse_wave)
# 把时间戳、频率和拆分后的波形拼在一起
final_df = pd.concat([df[['timestamp', 'freq']], wave_columns], axis=1)
# 4. 保存为 Excel 文件
final_df.to_excel(excel_name, index=False)
print("-" * 30)
print(f"导出成功!")
print(f"文件名:{excel_name}")
print(f"总计导出记录数:{len(final_df)} 条")
print("-" * 30)
except Exception as e:
print(f"导出失败,错误原因: {e}")
if __name__ == "__main__":
export()
生成表格如下:
更多推荐

所有评论(0)