134 lines
5.2 KiB
Python
134 lines
5.2 KiB
Python
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
|