清华园镜像地址: -i https://pypi.tuna.tsinghua.edu.cn/simple
在实际工作中,串口采集数据后,还需要对数据进行整理分析,比如说查找想要的数据,对收到的数据进行校验、加解密,时间间隔等分析操作。因此该工具对这点需求进行了整合,将数据筛选与校验等融入了进来。
一、筛选:
使用步骤是,将想要筛选的内容,输入筛选框,点筛选后,将筛选结果显示在分析窗口中。
程序执行时,将所有接收框的数据,存入文件中,然后用筛选框的内容比对文件的每一行内容,记录行号及结果,并将改行显示在分析窗口中。
def data_ellis(self):
find_content = self.ui.lineEdit_find.text()
file_content = self.ui.textBrowserRev.toPlainText()
with open("ellis_data.txt","w",encoding="utf_8") as fw:
fw.write(file_content)
if find_content != "":
n = 0
m = 0
lists = []
self.tool_receive_timer.stop()
find_content = find_content.strip()
self.ui.textBrowser_Ellis.setText("")
self.ui.pushButton_open.setText("打开串口")
self.serialTool.close()
with open("ellis_data.txt", "r", encoding="utf_8") as fr:
lines = fr.readlines()
for line in lines:
n = n + 1
if find_content in line:
m = m+1
list = f"搜索到了第{str(n)}行,第{str(m)}个结果"+"\r\n"+line+"\r\n"
lists.append(list)
else:
pass
if len(lists) == 0 :
self.ui.textBrowser_Ellis.setText("没有找到想要的内容!")
self.ui.textBrowser_Ellis.moveCursor(QTextCursor.End)
else:
self.ui.textBrowser_Ellis.setText("".join(lists))
self.ui.textBrowser_Ellis.moveCursor(QTextCursor.End)
with open("elis_reasult.txt","w",encoding="utf-8") as fz:
fz.write(self.ui.textBrowser_Ellis.toPlainText())
else:
QMessageBox.critical(self,"提示","请输入查找内容!")
- crc8(8005) 、CRC16(modbus)校验:
数据校验部分,采用了CRC标准库,实现了 crc8 和 crc16 常用的两种校验方式。
使用时,将需要分析的数据放入校验框中,点对应校验,结果展示在分析数据框中,这样就可以和收到的校验进行对比。
def data_crc8(self):
dv = self.ui.lineEdit_crc8.text()
dv.strip()
dat = []
while dv != "" :
try:
sub_number = int(dv[0:2], 16)
except ValueError:
QMessageBox.critical(self, "提示", "校验内容不是16进制!")
return None
else:
dv = dv[2:].strip()
dat.append(sub_number)
cfg = crc.Configuration(
width=8,
polynomial=0x1D,
init_value=0xFF,
final_xor_value=0xFF,
reverse_input=False,
reverse_output=False
)
print(dat)
print(bytes(dat))
code = crc.Calculator(cfg).checksum(bytes(dat))
self.ui.textBrowser_Ellis.setText(f"{hex(code)}")
def data_crc16(self):
dv = self.ui.lineEdit_crc16.text()
dv.strip()
numlist = []
while dv != "":
try:
subdata = int(dv[:2],16)
except ValueError:
QMessageBox.critical(self, "提示", "校验内容不是16进制!")
return None
else:
dv = dv[2:].strip()
numlist.append(subdata)
cfg = crc.Configuration(
width=16,
polynomial=0x8005,
init_value=0xFFFF,
final_xor_value=0x0000,
reverse_input=True,
reverse_output=True,
)
res = crc.Calculator(cfg).checksum(bytes(numlist))
self.ui.textBrowser_Ellis.setText(f"{hex(res)}")
- 时间间隔的计算
在接收和发送数据时,都将实时时间记录了下来,有时候为了看两端数据的间隔,现在只需要将想分析的内容选中,就可以直接算出间隔时间,同时支持手动输入时间计算。
def data_interval(self):
par = re.compile(r'\d{4}-\d{1,2}-\d{1,2} \d{2}:\d{2}:\d{2}.\d*')
con = self.ui.textBrowserRev.textCursor().selectedText()
# print(con)
# print(par.findall(con))
rest = par.findall(con)
self.tool_receive_timer.stop()
self.ui.pushButton_open.setText("打开串口")
self.serialTool.close()
sts = self.ui.lineEdit_time_start.text()
ste = self.ui.lineEdit_time_end.text()
sts = sts.strip()
ste = ste.strip()
if (len(par.findall(sts)) != 0) and (len(par.findall(ste)) != 0):
tsss = datetime.datetime.strptime(sts, "%Y-%m-%d %H:%M:%S.%f")
tsse = datetime.datetime.strptime(ste, "%Y-%m-%d %H:%M:%S.%f")
intv = (tsss - tsse).total_seconds()
tstring = f"时间间隔:{intv}秒"
self.ui.textBrowser_Ellis.setText(tstring)
elif len(rest) != 0:
string = "\r\n".join(rest)
self.ui.textBrowser_Ellis.setText(string)
self.ui.lineEdit_time_start.setText(rest[-1])
self.ui.lineEdit_time_end.setText(rest[0])
print(rest[-1])
print(rest[0])
tsf = datetime.datetime.strptime(rest[-1], "%Y-%m-%d %H:%M:%S.%f")
tef = datetime.datetime.strptime((rest[0]), "%Y-%m-%d %H:%M:%S.%f")
intv = (tsf - tef).total_seconds()
tstring = f"时间间隔:{intv}秒"
self.ui.textBrowser_Ellis.setText(tstring)
else:
QMessageBox.critical(self, "提示",
"起始时间时间格式不正确,请按2024-12-12 18:18:18.9999....格式填写时间或在接收框选择")
return None
至此,我们主体功能全部完成,并且全部测试正常,现在还剩下关闭窗口时,保存设置及保存接收发送的数据。实现如下:
def closeEvent(self, event):
reply = QMessageBox.question(self, 'Message', "确定要退出吗?",
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
# 判断返回值,如果点击的是Yes按钮,我们就关闭组件和应用,否则就忽略关闭事件
if reply == QMessageBox.Yes:
self.save_cfg()
with open("recevie.txt",mode="w+",encoding="utf-8") as f:
f.write(self.ui.textBrowserRev.toPlainText())
event.accept()
else:
event.ignore()
经过几天的完善,我们的工具算是正式完成了。