2025-03-14 16:15:51 +08:00

134 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from datetime import datetime
import re
from PyQt5.QtWidgets import QMessageBox
class DataProcessor:
def __init__(self):
self.log_buffer = {}
self.log_time = 10
self.position = 5
self.funcode = 'F4'
@staticmethod
def encode_data(data):
"""编码数据"""
try:
encoded_data = data.encode('utf-8')
encoded_data = re.sub(b'(?<!\r)\n', b'\r\n', encoded_data) # 替换换行符
return encoded_data
except Exception as e:
return f"编码失败: {e}"
@staticmethod
def decode_data(data):
"""解码数据"""
try:
decoded_data = data.decode('utf-8', errors='replace')
return decoded_data
except Exception as e:
return f"解码失败: {e}"
@staticmethod
def format_bytes_to_hexstr_space(data_bytes):
"""格式化数据为十六进制字符串"""
out_str = ' '.join(f'{byte:02X}' for byte in data_bytes)
return out_str
@staticmethod
def format_bytes_to_hexstr(data_bytes):
"""格式化数据为十六进制字符串"""
out_str = ''.join(f'{byte:02X}' for byte in data_bytes)
return out_str
@staticmethod
def format_hexstr_space_to_bytes(hexstr_space):
"""将十六进制字符串转换为字节数组"""
send_list = []
input_s = hexstr_space.strip() # 移除所有空格
# 将输入字符串转换为十六进制数值列表
while input_s != '':
try:
# 尝试将字符串的前两个字符转换为十六进制数
num = int(input_s[0:2], 16)
except ValueError:
# 如果转换失败弹出错误提示并返回None
msg_box = QMessageBox()
msg_box.setIcon(QMessageBox.Critical)
msg_box.setWindowTitle('串口异常')
msg_box.setText('请输入规范十六进制数据,以空格分开!')
msg_box.exec_()
return None
# 更新输入字符串,移除已经处理的前两个字符,并去除前导空格
input_s = input_s[2:].strip()
# 将转换后的十六进制数添加到发送列表中
send_list.append(num)
out_bytes = bytes(send_list) # 将字符串转换为字节串
return out_bytes
@staticmethod
def crc_rtu(data):
crc = 0xFFFF
for pos in data:
crc ^= pos
for _ in range(8):
if (crc & 0x0001) != 0:
crc >>= 1
crc ^= 0xA001
else:
crc >>= 1
return crc.to_bytes(2, byteorder='little') # 返回低字节在前
def auto_save_log_asc(self, port_name, decoded_data):
# 根据功能码保存数据
line = decoded_data.split(',')
if len(line) == 2:
sav_name = line[0] + '_' + datetime.now().strftime("%Y-%m-%d") + '.txt'
sav_str = datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")[:23] + " " + line[1]
else:
sav_name = port_name + '_' + datetime.now().strftime("%Y-%m-%d") + '.log'
sav_str = datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")[:23] + " " + decoded_data
self.auto_save_Log(sav_name, sav_str)
def auto_save_log_hex(self, port_name, data_bytes):
data_hex_str = self.format_bytes_to_hexstr(data_bytes)
out_str = self.format_bytes_to_hexstr_space(data_bytes)
if data_hex_str[2 * self.position:2 * self.position + 2] == self.funcode:
sav_name = data_hex_str[0:8] + '_' + datetime.now().strftime("%Y-%m-%d") + '.txt'
sav_str = datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")[:23] + " " + out_str[12:] + "\r\n"
# 当表示浓度的字符不为0时 将数据单独记录
if data_hex_str[14:18] != '0000':
sav_name_out = 'alarm_' + data_hex_str[0:8] + '_' + datetime.now().strftime("%Y-%m-%d") + '.txt'
sav_str_out = datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")[:23] + " " + out_str[12:] + "\r\n"
with open(sav_name_out, mode='a', newline='', encoding='utf-8', errors='replace') as file:
file.writelines(sav_str_out)
else:
sav_name = port_name + '_' + datetime.now().strftime("%Y-%m-%d") + '.log'
sav_str = datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")[:23] + " " + out_str + "\r\n"
self.auto_save_Log(sav_name, sav_str)
def auto_save_Log(self, sav_name, sav_str):
# 将日志信息添加到缓冲区
if sav_name not in self.log_buffer:
self.log_buffer[sav_name] = []
self.log_buffer[sav_name].append(sav_str)
# 当缓冲区中的记录达到10条时写入文件
if len(self.log_buffer[sav_name]) >= self.log_time:
with open(sav_name, mode='a', newline='', encoding='utf-8', errors='replace') as file:
file.writelines(self.log_buffer[sav_name])
self.log_buffer[sav_name].clear()
def update_log_time(self, log_time):
self.log_time = log_time
def update_position(self, position):
self.position = position
def update_funcode(self, funcode):
self.funcode = funcode