2025-06-21 10:36:45 +08:00
|
|
|
|
import csv
|
2025-04-08 16:47:59 +08:00
|
|
|
|
import os
|
2025-06-21 10:36:45 +08:00
|
|
|
|
import sys
|
|
|
|
|
import time
|
2025-04-15 14:18:19 +08:00
|
|
|
|
from time import sleep
|
2025-06-21 10:36:45 +08:00
|
|
|
|
from typing import Tuple, Optional
|
2025-04-15 14:18:19 +08:00
|
|
|
|
|
2025-06-21 10:36:45 +08:00
|
|
|
|
import matplotlib
|
2025-02-22 13:55:58 +08:00
|
|
|
|
import matplotlib.pyplot as plt
|
2025-06-21 10:36:45 +08:00
|
|
|
|
from PyQt5.QtCore import QTimer
|
2025-06-21 17:24:51 +08:00
|
|
|
|
from PyQt5.QtWidgets import QFrame, QStatusBar, QSizePolicy, QFileDialog, QApplication, QMainWindow, QWidget
|
2025-02-22 13:55:58 +08:00
|
|
|
|
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas, NavigationToolbar2QT
|
2025-06-21 10:36:45 +08:00
|
|
|
|
from scipy.fft import fft, fftfreq
|
|
|
|
|
|
2025-05-26 20:31:47 +08:00
|
|
|
|
from SamplingDialog import *
|
2025-06-21 10:36:45 +08:00
|
|
|
|
from feauture_calculate import *
|
2025-05-26 20:31:47 +08:00
|
|
|
|
|
2025-02-22 13:55:58 +08:00
|
|
|
|
# 启用高DPI支持
|
|
|
|
|
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
|
|
|
|
|
QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
|
|
|
|
|
|
|
|
|
|
# 强制使用 Qt5Agg 后端
|
|
|
|
|
matplotlib.use('Qt5Agg')
|
|
|
|
|
|
|
|
|
|
plt.rcParams['font.sans-serif'] = ['SimHei'] # Windows 中文字体
|
|
|
|
|
plt.rcParams['axes.unicode_minus'] = False # 解决负号 '-' 显示问题
|
|
|
|
|
|
2025-04-08 16:47:59 +08:00
|
|
|
|
HEADER_MAGIC = bytes([0xAA, 0x55, 0xAA])
|
|
|
|
|
HEADER_SIZE = 6 # PackgeHead除去data字段的大小(3+1+1+1)
|
2025-02-22 13:55:58 +08:00
|
|
|
|
|
2025-05-26 20:31:47 +08:00
|
|
|
|
|
|
|
|
|
class Eigenvalue:
|
|
|
|
|
def __init__(self, temp1, temp2, offset1, offset2):
|
|
|
|
|
self.temp1 = temp1
|
|
|
|
|
self.temp2 = temp2
|
|
|
|
|
self.offset1 = offset1
|
|
|
|
|
self.offset2 = offset2
|
|
|
|
|
|
2025-06-21 10:36:45 +08:00
|
|
|
|
|
2025-02-22 13:55:58 +08:00
|
|
|
|
class MatplotlibCanvas(FigureCanvas):
|
|
|
|
|
""" 用于在 Qt 界面中嵌入 Matplotlib 绘图 """
|
2025-06-21 10:36:45 +08:00
|
|
|
|
|
2025-02-22 13:55:58 +08:00
|
|
|
|
def __init__(self, parent=None):
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.fig, self.axs = plt.subplots(2, 2, figsize=(10, 5)) # 2 个子图(时域 + 频域)
|
2025-02-22 13:55:58 +08:00
|
|
|
|
self.fig.subplots_adjust(hspace=0.6) # 增大时域图和频域图的间距
|
|
|
|
|
super().__init__(self.fig)
|
|
|
|
|
self.setParent(parent)
|
|
|
|
|
self.init_plot()
|
|
|
|
|
|
|
|
|
|
def init_plot(self):
|
|
|
|
|
""" 初始化默认图像(占位提示) """
|
2025-06-21 10:36:45 +08:00
|
|
|
|
self.axs[0, 0].set_title("加速度时域信号", fontsize=12, fontweight='bold')
|
|
|
|
|
self.axs[0, 0].set_xlabel("采样点")
|
|
|
|
|
self.axs[0, 0].set_ylabel("幅度(m/s2)")
|
|
|
|
|
self.axs[0, 0].text(0.5, 0.5, "暂无数据", fontsize=12, ha='center', va='center',
|
|
|
|
|
transform=self.axs[0, 0].transAxes)
|
|
|
|
|
|
|
|
|
|
self.axs[0, 1].set_title("加速度频域信号", fontsize=12, fontweight='bold')
|
|
|
|
|
self.axs[0, 1].set_xlabel("频率 (Hz)")
|
|
|
|
|
self.axs[0, 1].set_ylabel("幅度(m/s2)")
|
|
|
|
|
self.axs[0, 1].text(0.5, 0.5, "暂无数据", fontsize=12, ha='center', va='center',
|
|
|
|
|
transform=self.axs[0, 1].transAxes)
|
2025-05-26 20:31:47 +08:00
|
|
|
|
|
|
|
|
|
self.axs[1, 0].set_title("速度时域信号", fontsize=12, fontweight='bold')
|
|
|
|
|
self.axs[1, 0].set_xlabel("采样点")
|
|
|
|
|
self.axs[1, 0].set_ylabel("幅度(mm/s)")
|
|
|
|
|
self.axs[1, 0].text(0.5, 0.5, "暂无数据", fontsize=12, ha='center', va='center',
|
|
|
|
|
transform=self.axs[1, 0].transAxes)
|
|
|
|
|
|
|
|
|
|
self.axs[1, 1].set_title("速度频域信号", fontsize=12, fontweight='bold')
|
|
|
|
|
self.axs[1, 1].set_xlabel("频率 (Hz)")
|
|
|
|
|
self.axs[1, 1].set_ylabel("幅度(mm/s)")
|
|
|
|
|
self.axs[1, 1].text(0.5, 0.5, "暂无数据", fontsize=12, ha='center', va='center',
|
|
|
|
|
transform=self.axs[1, 1].transAxes)
|
2025-02-22 13:55:58 +08:00
|
|
|
|
|
|
|
|
|
self.draw() # 更新绘图
|
|
|
|
|
|
2025-06-21 10:36:45 +08:00
|
|
|
|
def plot_data(self, data, sample):
|
2025-02-22 13:55:58 +08:00
|
|
|
|
""" 绘制时域和频域图 """
|
2025-06-21 10:36:45 +08:00
|
|
|
|
self.axs[0, 0].clear()
|
|
|
|
|
self.axs[0, 1].clear()
|
2025-02-22 13:55:58 +08:00
|
|
|
|
|
|
|
|
|
# 时域信号
|
2025-06-21 10:36:45 +08:00
|
|
|
|
self.axs[0, 0].plot(data, color='blue')
|
|
|
|
|
self.axs[0, 0].set_title("加速度时域信号", fontsize=12, fontweight='bold')
|
|
|
|
|
self.axs[0, 0].set_xlabel("采样点")
|
|
|
|
|
self.axs[0, 0].set_ylabel("幅度(m/s2)")
|
2025-02-22 13:55:58 +08:00
|
|
|
|
|
|
|
|
|
# 频域信号
|
|
|
|
|
N = len(data)
|
2025-05-26 20:31:47 +08:00
|
|
|
|
T = 1.0 / sample
|
|
|
|
|
yf = fft(data)[:N // 2]
|
2025-02-22 13:55:58 +08:00
|
|
|
|
xf = fftfreq(N, T)[:N // 2]
|
|
|
|
|
|
2025-05-26 20:31:47 +08:00
|
|
|
|
# self.axs[0,1].plot(xf, 2.0 / N * np.abs(yf[:N // 2]), color='red')
|
|
|
|
|
|
|
|
|
|
# yf = yf[:4000]
|
|
|
|
|
# xf = xf[:4000]
|
2025-06-21 10:36:45 +08:00
|
|
|
|
self.axs[0, 1].plot(xf, 2.0 / N * np.abs(yf), lw=0.2, color='black')
|
|
|
|
|
self.axs[0, 1].plot(xf, 2.0 / N * np.abs(yf), '.', lw=0.3, color='red')
|
2025-05-26 20:31:47 +08:00
|
|
|
|
|
2025-06-21 10:36:45 +08:00
|
|
|
|
self.axs[0, 1].set_title("加速度频域信号", fontsize=12, fontweight='bold')
|
|
|
|
|
self.axs[0, 1].set_xlabel("频率 (Hz)")
|
|
|
|
|
self.axs[0, 1].set_ylabel("幅度(m/s2)")
|
2025-02-22 13:55:58 +08:00
|
|
|
|
|
|
|
|
|
self.draw() # 更新绘图
|
|
|
|
|
|
2025-06-21 10:36:45 +08:00
|
|
|
|
def plot_data_vel(self, data, sample):
|
2025-05-26 20:31:47 +08:00
|
|
|
|
""" 绘制时域和频域图 """
|
2025-06-21 10:36:45 +08:00
|
|
|
|
self.axs[1, 0].clear()
|
|
|
|
|
self.axs[1, 1].clear()
|
2025-05-26 20:31:47 +08:00
|
|
|
|
|
|
|
|
|
# 时域信号
|
2025-06-21 10:36:45 +08:00
|
|
|
|
self.axs[1, 0].plot(data, color='blue')
|
|
|
|
|
self.axs[1, 0].set_title("速度时域信号", fontsize=12, fontweight='bold')
|
|
|
|
|
self.axs[1, 0].set_xlabel("采样点")
|
|
|
|
|
self.axs[1, 0].set_ylabel("幅度(mm/s)")
|
2025-05-26 20:31:47 +08:00
|
|
|
|
|
|
|
|
|
# 频域信号
|
|
|
|
|
N = len(data)
|
|
|
|
|
T = 1.0 / sample
|
|
|
|
|
yf = fft(data)[:N // 2]
|
|
|
|
|
xf = fftfreq(N, T)[:N // 2]
|
|
|
|
|
|
|
|
|
|
# self.axs[1,1].plot(xf, 2.0 / N * np.abs(yf[:N // 2]), color='red')
|
|
|
|
|
|
|
|
|
|
yf = yf[:1000]
|
|
|
|
|
xf = xf[:1000]
|
2025-06-21 10:36:45 +08:00
|
|
|
|
self.axs[1, 1].plot(xf, 2.0 / N * np.abs(yf), lw=0.2, color='black')
|
|
|
|
|
self.axs[1, 1].plot(xf, 2.0 / N * np.abs(yf), '.', lw=0.3, color='red')
|
2025-05-26 20:31:47 +08:00
|
|
|
|
|
2025-06-21 10:36:45 +08:00
|
|
|
|
self.axs[1, 1].set_title("速度频域信号", fontsize=12, fontweight='bold')
|
|
|
|
|
self.axs[1, 1].set_xlabel("频率 (Hz)")
|
|
|
|
|
self.axs[1, 1].set_ylabel("幅度(mm/s)")
|
2025-05-26 20:31:47 +08:00
|
|
|
|
|
|
|
|
|
self.draw() # 更新绘图
|
2025-02-22 13:55:58 +08:00
|
|
|
|
|
2025-06-21 10:36:45 +08:00
|
|
|
|
|
2025-02-22 13:55:58 +08:00
|
|
|
|
class SocketClientApp(QMainWindow):
|
|
|
|
|
def __init__(self):
|
|
|
|
|
super().__init__()
|
|
|
|
|
self.setWindowTitle("Socket Client & Data Plotter")
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.setGeometry(100, 100, 900, 700) # 设置初始尺寸
|
|
|
|
|
self.rate_code = 4
|
|
|
|
|
self.time_str = '1'
|
|
|
|
|
self.recv_state = ''
|
|
|
|
|
self.current_cmd = None
|
|
|
|
|
self.expected_length = 0
|
|
|
|
|
self.partial_data = QByteArray()
|
|
|
|
|
self.scaled_data = ''
|
|
|
|
|
|
|
|
|
|
self.sampling_rate = 0
|
2025-04-16 14:52:26 +08:00
|
|
|
|
self.buffer = QByteArray()
|
|
|
|
|
self.reconnect_timer = QTimer(self)
|
|
|
|
|
self.reconnect_timer.timeout.connect(self.attempt_reconnect)
|
|
|
|
|
self.reconnect_interval = 5000
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.max_reconnect_attempts = 10
|
2025-04-16 14:52:26 +08:00
|
|
|
|
self.current_reconnect_attempts = 0
|
|
|
|
|
|
|
|
|
|
self.socket = QTcpSocket(self)
|
|
|
|
|
self.socket.readyRead.connect(self.on_ready_read)
|
|
|
|
|
self.socket.disconnected.connect(self.on_socket_disconnected)
|
|
|
|
|
self.socket.errorOccurred.connect(self.on_socket_error)
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.socket.connected.connect(self.on_socket_connected)
|
2025-04-16 14:52:26 +08:00
|
|
|
|
|
2025-02-22 13:55:58 +08:00
|
|
|
|
# 组件初始化
|
|
|
|
|
self.ip_label = QLabel("IP 地址:")
|
|
|
|
|
self.port_label = QLabel("端口号:")
|
|
|
|
|
self.ip_input = QLineEdit(self)
|
|
|
|
|
self.port_input = QLineEdit(self)
|
|
|
|
|
self.connect_button = QPushButton("连接")
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.get_data_button = QPushButton("获取数据1")
|
|
|
|
|
self.get_data_button2 = QPushButton("获取数据2")
|
|
|
|
|
self.get_temp_button = QPushButton("温度、偏置")
|
2025-04-08 16:47:59 +08:00
|
|
|
|
self.upgrade_button = QPushButton("更新固件")
|
2025-06-23 14:00:03 +08:00
|
|
|
|
self.get_mac_button = QPushButton("获取MAC地址")
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.mac_config_button = QPushButton("mac配置")
|
|
|
|
|
self.ipv4_config_button = QPushButton("网络配置")
|
|
|
|
|
self.calibration_config_button = QPushButton("校准")
|
|
|
|
|
self.get_version_button = QPushButton("版本")
|
|
|
|
|
self.upgrade_button_sampling = QPushButton("采样率/时间")
|
|
|
|
|
self.save_button_csv = QPushButton("存储到csv")
|
2025-02-22 13:55:58 +08:00
|
|
|
|
self.get_data_button.setEnabled(False) # 初始状态不可点击
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.get_data_button2.setEnabled(False) # 初始状态不可点击
|
2025-04-08 16:47:59 +08:00
|
|
|
|
self.upgrade_button.setEnabled(False) # 初始状态不可点击
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.get_temp_button.setEnabled(False)
|
|
|
|
|
self.upgrade_button_sampling.setEnabled(False)
|
|
|
|
|
self.save_button_csv.setEnabled(False)
|
2025-05-28 17:42:25 +08:00
|
|
|
|
self.mac_config_button.setEnabled(False)
|
2025-06-23 14:00:03 +08:00
|
|
|
|
self.get_mac_button.setEnabled(False)
|
2025-05-28 17:42:25 +08:00
|
|
|
|
self.ipv4_config_button.setEnabled(False)
|
|
|
|
|
self.calibration_config_button.setEnabled(False)
|
|
|
|
|
self.get_version_button.setEnabled(False)
|
2025-06-21 17:24:51 +08:00
|
|
|
|
self.ip_input.setText("192.168.0.191")
|
2025-02-22 13:55:58 +08:00
|
|
|
|
self.port_input.setText("12345")
|
|
|
|
|
|
|
|
|
|
# 预留绘图区域
|
|
|
|
|
self.canvas = MatplotlibCanvas(self)
|
|
|
|
|
self.toolbar = NavigationToolbar2QT(self.canvas, self) # 添加工具栏(放大、缩小、拖拽)
|
|
|
|
|
|
|
|
|
|
# 预留特征值显示区域
|
|
|
|
|
self.feature_label = QLabel("特征值:")
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.acceleration_label_rms = QLabel("加速度有效值: -")
|
|
|
|
|
self.acceleration_label_pp = QLabel("加速度峰值: -")
|
|
|
|
|
self.velocity_label_rms = QLabel("速度有效值: -")
|
|
|
|
|
self.velocity_label_pp = QLabel("速度峰值: -")
|
|
|
|
|
self.temp1_label = QLabel("温度1: -")
|
|
|
|
|
self.temp2_label = QLabel("温度2:-")
|
|
|
|
|
self.offset1_label = QLabel("偏置电压1:-")
|
|
|
|
|
self.offset2_label = QLabel("偏置电压2:-")
|
2025-02-22 13:55:58 +08:00
|
|
|
|
# 设置分割线
|
|
|
|
|
self.line = QFrame()
|
|
|
|
|
self.line.setFrameShape(QFrame.HLine)
|
|
|
|
|
self.line.setFrameShadow(QFrame.Sunken)
|
|
|
|
|
|
|
|
|
|
# 布局管理
|
|
|
|
|
main_layout = QVBoxLayout()
|
|
|
|
|
|
|
|
|
|
# 输入区域(IP & 端口)
|
|
|
|
|
input_layout = QHBoxLayout()
|
|
|
|
|
input_layout.addWidget(self.ip_label)
|
|
|
|
|
input_layout.addWidget(self.ip_input)
|
|
|
|
|
input_layout.addWidget(self.port_label)
|
|
|
|
|
input_layout.addWidget(self.port_input)
|
|
|
|
|
main_layout.addLayout(input_layout)
|
|
|
|
|
|
|
|
|
|
# 按钮区域
|
|
|
|
|
button_layout = QHBoxLayout()
|
|
|
|
|
button_layout.addWidget(self.connect_button)
|
|
|
|
|
button_layout.addWidget(self.get_data_button)
|
2025-05-26 20:31:47 +08:00
|
|
|
|
button_layout.addWidget(self.get_data_button2)
|
|
|
|
|
button_layout.addWidget(self.get_temp_button)
|
2025-04-08 16:47:59 +08:00
|
|
|
|
button_layout.addWidget(self.upgrade_button)
|
2025-05-26 20:31:47 +08:00
|
|
|
|
button_layout.addWidget(self.upgrade_button_sampling)
|
2025-06-23 14:00:03 +08:00
|
|
|
|
button_layout.addWidget(self.get_mac_button)
|
2025-05-26 20:31:47 +08:00
|
|
|
|
button_layout.addWidget(self.mac_config_button)
|
|
|
|
|
button_layout.addWidget(self.ipv4_config_button)
|
|
|
|
|
button_layout.addWidget(self.calibration_config_button)
|
|
|
|
|
button_layout.addWidget(self.get_version_button)
|
|
|
|
|
button_layout.addWidget(self.save_button_csv)
|
2025-02-22 13:55:58 +08:00
|
|
|
|
main_layout.addLayout(button_layout)
|
|
|
|
|
|
|
|
|
|
# 添加分割线
|
|
|
|
|
main_layout.addWidget(self.line)
|
|
|
|
|
|
|
|
|
|
# 工具栏(放大、缩小、拖拽)
|
|
|
|
|
main_layout.addWidget(self.toolbar)
|
|
|
|
|
|
|
|
|
|
# 绘图 + 特征值区域
|
|
|
|
|
graph_layout = QVBoxLayout()
|
|
|
|
|
graph_layout.addWidget(self.canvas)
|
|
|
|
|
|
|
|
|
|
# 特征值显示区域
|
|
|
|
|
feature_layout = QGridLayout()
|
2025-05-26 20:31:47 +08:00
|
|
|
|
feature_layout.setVerticalSpacing(10)
|
2025-02-22 13:55:58 +08:00
|
|
|
|
feature_layout.addWidget(self.feature_label, 0, 0)
|
2025-05-26 20:31:47 +08:00
|
|
|
|
feature_layout.addWidget(self.acceleration_label_rms, 0, 1)
|
|
|
|
|
feature_layout.addWidget(self.acceleration_label_pp, 0, 2)
|
|
|
|
|
feature_layout.addWidget(self.velocity_label_rms, 1, 1)
|
|
|
|
|
feature_layout.addWidget(self.velocity_label_pp, 1, 2)
|
|
|
|
|
feature_layout.addWidget(self.temp1_label, 2, 1)
|
|
|
|
|
feature_layout.addWidget(self.temp2_label, 2, 2)
|
|
|
|
|
feature_layout.addWidget(self.offset1_label, 3, 1)
|
|
|
|
|
feature_layout.addWidget(self.offset2_label, 3, 2)
|
|
|
|
|
|
2025-02-22 13:55:58 +08:00
|
|
|
|
graph_layout.addLayout(feature_layout)
|
|
|
|
|
|
|
|
|
|
main_layout.addLayout(graph_layout)
|
|
|
|
|
|
|
|
|
|
# 增大特征值区域与状态栏的间距
|
|
|
|
|
main_layout.addSpacing(20)
|
|
|
|
|
|
|
|
|
|
# 创建状态栏
|
|
|
|
|
self.status_bar = QStatusBar()
|
|
|
|
|
self.setStatusBar(self.status_bar)
|
|
|
|
|
|
|
|
|
|
# 状态栏显示初始消息
|
|
|
|
|
self.status_bar.showMessage("状态: 请填写 IP 和端口号")
|
|
|
|
|
|
|
|
|
|
# 主窗口的中央部件
|
|
|
|
|
central_widget = QWidget()
|
|
|
|
|
central_widget.setLayout(main_layout)
|
|
|
|
|
self.setCentralWidget(central_widget)
|
|
|
|
|
|
|
|
|
|
# 事件绑定
|
|
|
|
|
self.connect_button.clicked.connect(self.connect_to_server)
|
|
|
|
|
self.get_data_button.clicked.connect(self.on_button_clicked)
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.get_data_button2.clicked.connect(self.on_button_clicked2)
|
2025-04-08 16:47:59 +08:00
|
|
|
|
self.upgrade_button.clicked.connect(self.on_button_upgrade)
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.get_temp_button.clicked.connect(self.on_button_temp)
|
|
|
|
|
self.upgrade_button_sampling.clicked.connect(self.on_button_samping_set)
|
|
|
|
|
self.save_button_csv.clicked.connect(self.on_button_save_csv)
|
|
|
|
|
self.mac_config_button.clicked.connect(self.mac_config_dialog)
|
2025-06-23 14:00:03 +08:00
|
|
|
|
self.get_mac_button.clicked.connect(self.on_button_get_mac)
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.ipv4_config_button.clicked.connect(self.ipv4_config_dialog)
|
|
|
|
|
self.calibration_config_button.clicked.connect(self.calibration_dialog)
|
|
|
|
|
self.get_version_button.clicked.connect(self.on_button_get_version)
|
2025-02-22 13:55:58 +08:00
|
|
|
|
# 设置布局策略,确保控件大小随窗口调整
|
|
|
|
|
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
|
|
|
|
|
2025-06-21 10:36:45 +08:00
|
|
|
|
def get_extremes(self, data):
|
2025-04-15 14:18:19 +08:00
|
|
|
|
"""获取最大和最小的10个值(排序法)"""
|
|
|
|
|
sorted_data = np.sort(data)
|
|
|
|
|
return {
|
|
|
|
|
'top10_max': sorted_data[-10:][::-1].tolist(), # 降序排列
|
|
|
|
|
'top10_min': sorted_data[:10].tolist()
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-21 10:36:45 +08:00
|
|
|
|
def mean_without_max_optimized(self, data):
|
2025-04-15 14:18:19 +08:00
|
|
|
|
"""优化内存使用的版本"""
|
|
|
|
|
arr = np.array(data)
|
|
|
|
|
if len(arr) < 2:
|
|
|
|
|
return np.nan
|
|
|
|
|
|
|
|
|
|
max_val = np.max(arr)
|
|
|
|
|
# 计算总和和计数时直接排除最大值
|
|
|
|
|
total = np.sum(arr) - max_val
|
|
|
|
|
count = len(arr) - 1
|
|
|
|
|
return total / count
|
|
|
|
|
|
|
|
|
|
def mean_without_min_optimized(self, data):
|
|
|
|
|
"""优化内存使用的版本"""
|
|
|
|
|
arr = np.array(data)
|
|
|
|
|
if len(arr) < 2:
|
|
|
|
|
return np.nan
|
|
|
|
|
|
|
|
|
|
min_val = np.min(arr)
|
|
|
|
|
# 计算总和和计数时直接排除最大值
|
|
|
|
|
total = np.sum(arr) - min_val
|
|
|
|
|
count = len(arr) - 1
|
|
|
|
|
return total / count
|
2025-06-21 10:36:45 +08:00
|
|
|
|
|
|
|
|
|
def calculate_crc(self, data: bytes) -> int:
|
2025-04-08 16:47:59 +08:00
|
|
|
|
"""计算数据的累加和CRC"""
|
|
|
|
|
crc = 0
|
|
|
|
|
for byte in data:
|
|
|
|
|
crc += byte
|
|
|
|
|
return crc & 0xFF # 只保留最低字节
|
2025-05-26 20:31:47 +08:00
|
|
|
|
|
2025-02-22 13:55:58 +08:00
|
|
|
|
def connect_to_server(self):
|
2025-06-21 10:36:45 +08:00
|
|
|
|
# self.process_wave_packet('')
|
2025-05-28 17:42:25 +08:00
|
|
|
|
if self.connect_button.text() == "断开":
|
|
|
|
|
self.connect_button.setText("连接")
|
|
|
|
|
self.socket.disconnectFromHost()
|
|
|
|
|
elif self.connect_button.text() == "连接":
|
|
|
|
|
ip = self.ip_input.text()
|
|
|
|
|
port = int(self.port_input.text())
|
|
|
|
|
self.socket.abort()
|
|
|
|
|
self.socket.connectToHost(ip, port)
|
2025-04-16 14:52:26 +08:00
|
|
|
|
|
2025-05-26 20:31:47 +08:00
|
|
|
|
def on_socket_connected(self):
|
|
|
|
|
self.status_bar.showMessage("状态: 连接成功")
|
|
|
|
|
self.get_data_button.setEnabled(True)
|
|
|
|
|
self.get_data_button2.setEnabled(True)
|
|
|
|
|
self.upgrade_button.setEnabled(True)
|
|
|
|
|
self.get_temp_button.setEnabled(True)
|
|
|
|
|
self.upgrade_button_sampling.setEnabled(True)
|
|
|
|
|
self.save_button_csv.setEnabled(True)
|
2025-06-23 14:00:03 +08:00
|
|
|
|
self.get_mac_button.setEnabled(True)
|
2025-05-28 17:42:25 +08:00
|
|
|
|
self.mac_config_button.setEnabled(True)
|
|
|
|
|
self.ipv4_config_button.setEnabled(True)
|
|
|
|
|
self.calibration_config_button.setEnabled(True)
|
|
|
|
|
self.get_version_button.setEnabled(True)
|
|
|
|
|
self.connect_button.setText("断开")
|
2025-05-26 20:31:47 +08:00
|
|
|
|
|
2025-04-16 14:52:26 +08:00
|
|
|
|
def on_socket_disconnected(self):
|
2025-05-26 20:31:47 +08:00
|
|
|
|
print("on_socket_disconnected")
|
2025-05-28 17:42:25 +08:00
|
|
|
|
self.connect_button.setText("连接")
|
|
|
|
|
self.status_bar.showMessage("状态: 连接断开")
|
2025-04-16 14:52:26 +08:00
|
|
|
|
self.get_data_button.setEnabled(False)
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.get_data_button2.setEnabled(False)
|
|
|
|
|
self.upgrade_button.setEnabled(False)
|
|
|
|
|
self.get_temp_button.setEnabled(False)
|
|
|
|
|
self.upgrade_button_sampling.setEnabled(False)
|
|
|
|
|
self.save_button_csv.setEnabled(False)
|
2025-06-23 14:00:03 +08:00
|
|
|
|
self.get_mac_button.setEnabled(False)
|
2025-05-28 17:42:25 +08:00
|
|
|
|
self.mac_config_button.setEnabled(False)
|
|
|
|
|
self.ipv4_config_button.setEnabled(False)
|
|
|
|
|
self.calibration_config_button.setEnabled(False)
|
|
|
|
|
self.get_version_button.setEnabled(False)
|
|
|
|
|
# self.current_reconnect_attempts = 0
|
|
|
|
|
# self.reconnect_timer.start(self.reconnect_interval)
|
2025-04-16 14:52:26 +08:00
|
|
|
|
|
|
|
|
|
def on_socket_error(self, error):
|
|
|
|
|
self.status_bar.showMessage(f"状态: 错误 - {self.socket.errorString()}")
|
|
|
|
|
|
|
|
|
|
def attempt_reconnect(self):
|
|
|
|
|
if self.current_reconnect_attempts >= self.max_reconnect_attempts:
|
|
|
|
|
self.reconnect_timer.stop()
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.status_bar.showMessage("状态: 多次重连失败")
|
2025-02-22 13:55:58 +08:00
|
|
|
|
return
|
2025-05-26 20:31:47 +08:00
|
|
|
|
|
2025-04-16 14:52:26 +08:00
|
|
|
|
self.current_reconnect_attempts += 1
|
2025-05-26 20:31:47 +08:00
|
|
|
|
print(f"第 {self.current_reconnect_attempts} 次尝试重连...")
|
|
|
|
|
|
|
|
|
|
self.socket.abort()
|
2025-04-16 14:52:26 +08:00
|
|
|
|
self.connect_to_server()
|
|
|
|
|
|
2025-05-26 20:31:47 +08:00
|
|
|
|
if self.socket.waitForConnected(1000):
|
|
|
|
|
self.status_bar.showMessage("状态: 重新连接成功")
|
|
|
|
|
self.get_data_button.setEnabled(True)
|
|
|
|
|
self.reconnect_timer.stop()
|
2025-06-21 10:36:45 +08:00
|
|
|
|
|
2025-05-26 20:31:47 +08:00
|
|
|
|
def on_button_save_csv(self):
|
|
|
|
|
file_path = QFileDialog.getExistingDirectory(
|
|
|
|
|
None,
|
|
|
|
|
"选择保存目录",
|
|
|
|
|
"",
|
|
|
|
|
QFileDialog.ShowDirsOnly
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if not file_path:
|
|
|
|
|
return
|
|
|
|
|
file_path = os.path.join(file_path, "wave.csv")
|
|
|
|
|
try:
|
|
|
|
|
# 将 QByteArray 转换为字符串并写入文件
|
|
|
|
|
# 写入 CSV 文件
|
|
|
|
|
with open(file_path, 'w', newline='') as csvfile:
|
|
|
|
|
writer = csv.writer(csvfile)
|
|
|
|
|
for val in self.scaled_data:
|
|
|
|
|
writer.writerow([val])
|
|
|
|
|
|
|
|
|
|
print(f"已保存 {len(self.scaled_data)} 个 float 到 {file_path}")
|
|
|
|
|
|
|
|
|
|
QMessageBox.information(
|
|
|
|
|
self,
|
|
|
|
|
"保存成功",
|
|
|
|
|
f"文件已成功保存到:\n{file_path}"
|
|
|
|
|
)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
QMessageBox.critical(
|
|
|
|
|
self,
|
|
|
|
|
"保存失败",
|
|
|
|
|
f"保存文件时出错:\n{str(e)}"
|
|
|
|
|
)
|
2025-06-21 10:36:45 +08:00
|
|
|
|
|
2025-05-26 20:31:47 +08:00
|
|
|
|
def on_button_samping_set(self):
|
|
|
|
|
dialog = SamplingDialog(self)
|
|
|
|
|
if dialog.exec_() == QDialog.Accepted:
|
|
|
|
|
self.rate_code, self.time_str = dialog.get_values()
|
2025-06-21 10:36:45 +08:00
|
|
|
|
|
2025-04-16 14:52:26 +08:00
|
|
|
|
def on_ready_read(self):
|
2025-05-26 20:31:47 +08:00
|
|
|
|
while self.socket.bytesAvailable():
|
|
|
|
|
if self.recv_state == 'WAIT_HEADER':
|
|
|
|
|
self.start_time = time.time()
|
|
|
|
|
print(f"开始时间戳: {self.start_time}")
|
|
|
|
|
if self.socket.bytesAvailable() >= HEADER_SIZE:
|
|
|
|
|
self.header = self.socket.read(HEADER_SIZE)
|
|
|
|
|
if self.header[:3] != HEADER_MAGIC:
|
|
|
|
|
print("无效 header magic,跳过")
|
|
|
|
|
continue
|
|
|
|
|
self.cmd = self.header[3]
|
|
|
|
|
if self.cmd == 0x01:
|
|
|
|
|
self.recv_state = 'WAIT_WAVE_HEADER'
|
|
|
|
|
else:
|
|
|
|
|
print(f"未知或暂不处理的 cmd: {self.cmd}")
|
|
|
|
|
self.recv_state = 'WAIT_HEADER'
|
|
|
|
|
return
|
|
|
|
|
else:
|
|
|
|
|
return
|
|
|
|
|
elif self.recv_state == 'WAIT_WAVE_HEADER':
|
|
|
|
|
if self.socket.bytesAvailable() >= 5:
|
|
|
|
|
wave_header = self.socket.read(5)
|
|
|
|
|
self.sampling_rate = struct.unpack('<i', wave_header[1:5])[0]
|
|
|
|
|
print(f"采样率: {self.sampling_rate}")
|
|
|
|
|
self.expected_length = self.sampling_rate * 4
|
|
|
|
|
self.partial_data.clear()
|
|
|
|
|
self.recv_state = 'WAIT_WAVE_DATA'
|
|
|
|
|
else:
|
|
|
|
|
return
|
|
|
|
|
elif self.recv_state == 'WAIT_WAVE_DATA':
|
|
|
|
|
bytes_needed = self.expected_length - len(self.partial_data)
|
|
|
|
|
chunk = self.socket.read(min(self.socket.bytesAvailable(), bytes_needed))
|
|
|
|
|
self.partial_data += chunk
|
|
|
|
|
if len(self.partial_data) >= self.expected_length:
|
|
|
|
|
end_time = time.time()
|
|
|
|
|
execution_time = end_time - self.start_time
|
|
|
|
|
print(f"结束时间戳: {end_time}")
|
2025-06-21 17:24:51 +08:00
|
|
|
|
print(f"代码执行时间: {round(execution_time, 3)} 秒")
|
2025-06-21 10:36:45 +08:00
|
|
|
|
print(f"speed :{round((self.sampling_rate * 4 * 8) / execution_time, 3)} Kbps")
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.process_wave_packet(bytes(self.partial_data))
|
|
|
|
|
self.recv_state = 'WAIT_HEADER'
|
|
|
|
|
self.partial_data.clear()
|
|
|
|
|
else:
|
|
|
|
|
if self.socket.bytesAvailable() >= HEADER_SIZE:
|
|
|
|
|
recv_data = self.socket.read(1340)
|
|
|
|
|
if recv_data[:3] != HEADER_MAGIC:
|
|
|
|
|
print("无效 header magic,跳过")
|
|
|
|
|
continue
|
|
|
|
|
cmd = recv_data[3]
|
|
|
|
|
if cmd == 0x0C:
|
|
|
|
|
body_format = '< H H H H'
|
|
|
|
|
body_size = struct.calcsize(body_format)
|
|
|
|
|
body_data = recv_data[HEADER_SIZE:HEADER_SIZE + body_size]
|
|
|
|
|
unpacked_data = struct.unpack(body_format, body_data)
|
|
|
|
|
value = Eigenvalue(*unpacked_data)
|
2025-06-21 10:36:45 +08:00
|
|
|
|
print(
|
|
|
|
|
f"温度1:{value.temp1 / 1000},温度2:{value.temp2 / 1000},偏置电压1:{value.offset1 / 100},偏置电压2:{value.offset2 / 100}")
|
|
|
|
|
self.temp1_label.setText(f"温度1:{value.temp1 / 1000} v")
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.temp2_label.setText(f"温度2:{value.temp2 / 1000} v")
|
|
|
|
|
self.offset1_label.setText(f"偏置电压1:{value.offset1 / 100} v")
|
|
|
|
|
self.offset2_label.setText(f"偏置电压2:{value.offset2 / 100} v")
|
2025-06-24 17:59:40 +08:00
|
|
|
|
self.status_bar.showMessage("状态: 温度数据获取完成", 5000)
|
2025-05-26 20:31:47 +08:00
|
|
|
|
elif cmd == 0x0F:
|
|
|
|
|
body_format = '< B B'
|
|
|
|
|
body_size = struct.calcsize(body_format)
|
|
|
|
|
body_data = recv_data[HEADER_SIZE:HEADER_SIZE + body_size]
|
|
|
|
|
unpacked_data = struct.unpack(body_format, body_data)
|
|
|
|
|
print(f"version{unpacked_data}")
|
|
|
|
|
QMessageBox.information(self, "版本", f"{unpacked_data[0]}.{unpacked_data[1]}")
|
2025-06-23 14:00:03 +08:00
|
|
|
|
elif cmd == 0x12:
|
|
|
|
|
body_format = '< B B'
|
|
|
|
|
body_size = struct.calcsize(body_format)
|
|
|
|
|
body_data = recv_data[HEADER_SIZE:HEADER_SIZE + body_size]
|
|
|
|
|
unpacked_data = struct.unpack(body_format, body_data)
|
|
|
|
|
print(f"version{unpacked_data}")
|
|
|
|
|
QMessageBox.information(self, "MAC地址",
|
|
|
|
|
f"50-29-4D-20-{format(unpacked_data[0], '02x')}-{format(unpacked_data[1], '02x')}")
|
2025-05-26 20:31:47 +08:00
|
|
|
|
|
2025-04-16 14:52:26 +08:00
|
|
|
|
def receive_data(self, length: int):
|
|
|
|
|
while len(self.buffer) < length:
|
|
|
|
|
if not self.socket.waitForReadyRead(1000):
|
|
|
|
|
raise ConnectionError("等待数据超时")
|
|
|
|
|
data = self.buffer[:length]
|
|
|
|
|
self.buffer = self.buffer[length:]
|
|
|
|
|
return bytes(data)
|
2025-02-22 13:55:58 +08:00
|
|
|
|
|
2025-06-21 10:36:45 +08:00
|
|
|
|
def parse_package_head(self, data: bytes) -> Tuple[Optional[dict], Optional[bytes]]:
|
2025-04-08 16:47:59 +08:00
|
|
|
|
"""
|
|
|
|
|
解析包头部
|
|
|
|
|
返回: (header_dict, remaining_data)
|
|
|
|
|
"""
|
|
|
|
|
if len(data) < HEADER_SIZE:
|
|
|
|
|
return None, None
|
|
|
|
|
|
|
|
|
|
# 检查魔数
|
|
|
|
|
if data[:3] != HEADER_MAGIC:
|
|
|
|
|
print(f"Invalid header magic: {data[:3].hex()}")
|
|
|
|
|
return None, None
|
|
|
|
|
|
|
|
|
|
# 解析头部
|
|
|
|
|
cmd, version, result_code = struct.unpack_from('<BBB', data, 3)
|
|
|
|
|
return {
|
|
|
|
|
'cmd': cmd,
|
|
|
|
|
'version': version,
|
|
|
|
|
'result_code': result_code
|
|
|
|
|
}, data[HEADER_SIZE:]
|
2025-06-21 10:36:45 +08:00
|
|
|
|
|
|
|
|
|
def process_wave_packet(self, wave_data):
|
2025-05-26 20:31:47 +08:00
|
|
|
|
data = wave_data # 接收所有数据
|
|
|
|
|
data = np.frombuffer(data, dtype=np.int32) # 根据实际数据格式转换
|
2025-06-21 17:24:51 +08:00
|
|
|
|
for i in range(min(5, len(data))): # 确保不超过数据长度
|
|
|
|
|
print(f"{data[i]:.3f}", end=" ")
|
2025-05-26 20:31:47 +08:00
|
|
|
|
print() # 换行
|
2025-06-21 10:36:45 +08:00
|
|
|
|
LSB_32BIT = (2.8 / (2 ** 31)) * ((750 + 287) / 287) * 1000 / 10.2
|
2025-05-26 20:31:47 +08:00
|
|
|
|
# LSB_32BIT = (2.8 / (2 ** 31)) * ((750 + 287) / 287) * 1000
|
|
|
|
|
self.scaled_data = data * LSB_32BIT
|
|
|
|
|
# for i in range(min(100, len(self.scaled_data))): # 确保不超过数据长度
|
|
|
|
|
# print(f"{self.scaled_data[i]:2f}", end=" ")
|
|
|
|
|
# print() # 换行
|
|
|
|
|
# result = self.get_extremes(self.scaled_data)
|
|
|
|
|
# print("最大的10个值:", result['top10_max'])
|
|
|
|
|
# print("最小的10个值:", result['top10_min'])
|
|
|
|
|
# mean_max = self.mean_without_max_optimized(result['top10_max'])
|
|
|
|
|
# print(f"top10_max 去除最大的数据后的平均值1:{mean_max}")
|
|
|
|
|
# mean_min = self.mean_without_min_optimized(result['top10_min'])
|
|
|
|
|
# print(f"top10_min 去除最大的数据后的平均值2:{mean_min}")
|
|
|
|
|
# print(f"pp :{mean_max - mean_min}")
|
|
|
|
|
print(f"采样率: {self.sampling_rate}")
|
|
|
|
|
# self.sampling_rate = 48000 # 假设采样率为 48000 Hz
|
2025-06-21 10:36:45 +08:00
|
|
|
|
self.canvas.plot_data(self.scaled_data, self.sampling_rate) # 在 Qt 界面中绘图
|
|
|
|
|
data_filter = fft_filter(self.scaled_data, 10, 1000, self.sampling_rate)
|
|
|
|
|
data_vel1, data_vel2 = acc2dis(data_filter, self.sampling_rate)
|
|
|
|
|
self.canvas.plot_data_vel(data_vel1, self.sampling_rate) # 在 Qt 界面中绘图
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.status_bar.showMessage("状态: 数据绘制完成")
|
|
|
|
|
# 速度有效值
|
|
|
|
|
|
|
|
|
|
speed_rms_value = calc_vel_pass_rms(self.scaled_data, self.sampling_rate)
|
2025-06-21 17:24:51 +08:00
|
|
|
|
print("速度有效值:", round(speed_rms_value, 1))
|
2025-05-26 20:31:47 +08:00
|
|
|
|
# 速度峰值
|
|
|
|
|
speed_vel_p = calc_vel_p(self.scaled_data, self.sampling_rate)
|
2025-06-21 17:24:51 +08:00
|
|
|
|
print("速度峰值:", round(speed_vel_p, 1))
|
2025-05-26 20:31:47 +08:00
|
|
|
|
# 加速度有效值
|
|
|
|
|
acc_rms = calc_acc_rms(self.scaled_data, self.sampling_rate)
|
2025-06-21 17:24:51 +08:00
|
|
|
|
print("加速度有效值:", round(acc_rms, 1))
|
2025-05-26 20:31:47 +08:00
|
|
|
|
# 加速度峰值
|
|
|
|
|
acc_p = calc_acc_p(self.scaled_data, self.sampling_rate)
|
2025-06-21 17:24:51 +08:00
|
|
|
|
print("加速度峰值:", round(acc_p, 1))
|
2025-06-21 10:36:45 +08:00
|
|
|
|
self.acceleration_label_rms.setText(f"加速度有效值:{round(acc_rms, 3)} m/s^2")
|
|
|
|
|
self.acceleration_label_pp.setText(f"加速度峰值:{round(acc_p, 3)} m/s^2")
|
|
|
|
|
self.velocity_label_rms.setText(f"速度有效值:{round(speed_rms_value, 3)} mm/s")
|
|
|
|
|
self.velocity_label_pp.setText(f"速度峰值:{round(speed_vel_p, 3)} mm/s")
|
2025-04-08 16:47:59 +08:00
|
|
|
|
|
2025-05-26 20:31:47 +08:00
|
|
|
|
def on_button_clicked(self):
|
2025-02-22 13:55:58 +08:00
|
|
|
|
try:
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.recv_state = 'WAIT_HEADER'
|
|
|
|
|
time_value = int(self.time_str)
|
|
|
|
|
rate_bytes = struct.pack('<I', self.rate_code)
|
|
|
|
|
time_bytes = struct.pack('<I', time_value)
|
|
|
|
|
|
|
|
|
|
packet = bytes([
|
|
|
|
|
0xAA, 0x55, 0xAA,
|
|
|
|
|
0x01, 0x00, 0x00,
|
|
|
|
|
0x01
|
|
|
|
|
]) + rate_bytes + time_bytes
|
|
|
|
|
|
|
|
|
|
self.socket.write(packet)
|
|
|
|
|
print(packet)
|
|
|
|
|
self.status_bar.showMessage(f"状态: 正在获取通道1数据,采样率: {self.rate_code}, 时间: {time_value}s")
|
|
|
|
|
self.socket.waitForReadyRead()
|
2025-02-22 13:55:58 +08:00
|
|
|
|
except Exception as e:
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.status_bar.showMessage(f"状态: 错误 - {str(e)}")
|
2025-06-21 10:36:45 +08:00
|
|
|
|
|
2025-05-26 20:31:47 +08:00
|
|
|
|
def on_button_clicked2(self):
|
2025-02-22 13:55:58 +08:00
|
|
|
|
""" 获取数据并绘制 """
|
|
|
|
|
try:
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.recv_state = 'WAIT_HEADER'
|
|
|
|
|
time_value = int(self.time_str)
|
|
|
|
|
rate_bytes = struct.pack('<I', self.rate_code)
|
|
|
|
|
time_bytes = struct.pack('<I', time_value)
|
|
|
|
|
|
|
|
|
|
packet = bytes([
|
|
|
|
|
0xAA, 0x55, 0xAA,
|
|
|
|
|
0x01, 0x00, 0x00,
|
|
|
|
|
0x02
|
|
|
|
|
]) + rate_bytes + time_bytes
|
|
|
|
|
|
|
|
|
|
self.socket.write(packet)
|
|
|
|
|
self.status_bar.showMessage(f"状态: 正在获取通道2数据,采样率: {self.rate_code}, 时间: {time_value}s")
|
|
|
|
|
self.socket.waitForReadyRead()
|
2025-02-22 13:55:58 +08:00
|
|
|
|
except Exception as e:
|
|
|
|
|
self.status_bar.showMessage(f"状态: 错误 - {str(e)}")
|
2025-06-21 10:36:45 +08:00
|
|
|
|
|
2025-04-08 16:47:59 +08:00
|
|
|
|
def on_button_upgrade(self):
|
|
|
|
|
"""打开文件选择对话框"""
|
|
|
|
|
file_path, _ = QFileDialog.getOpenFileName(
|
|
|
|
|
self, "选择升级文件", "", "二进制文件 (*.bin);;所有文件 (*)"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if file_path:
|
|
|
|
|
file_name = os.path.basename(file_path)
|
|
|
|
|
self.status_bar.showMessage(f"已选择: {file_name}")
|
|
|
|
|
try:
|
|
|
|
|
print("Starting upgrade process...")
|
|
|
|
|
|
|
|
|
|
if not os.path.exists(file_path):
|
|
|
|
|
raise FileNotFoundError(f"Upgrade file {file_path} not found")
|
|
|
|
|
|
|
|
|
|
with open(file_path, "rb") as f:
|
|
|
|
|
package_data = f.read()
|
|
|
|
|
|
|
|
|
|
if not package_data:
|
|
|
|
|
raise ValueError("Upgrade file is empty")
|
|
|
|
|
|
|
|
|
|
print(f"Read upgrade package, size: {len(package_data)} bytes")
|
|
|
|
|
|
|
|
|
|
upgrade_len = len(package_data)
|
|
|
|
|
crc = self.calculate_crc(package_data)
|
|
|
|
|
upgrade_req = struct.pack("<IB", upgrade_len, crc) + package_data
|
|
|
|
|
|
|
|
|
|
header_magic = bytes([0xAA, 0x55, 0xAA])
|
|
|
|
|
cmd = 0x05
|
|
|
|
|
version = 1
|
|
|
|
|
result_code = 0
|
|
|
|
|
|
|
|
|
|
package_head = struct.pack("<3sBBB", header_magic, cmd, version, result_code)
|
|
|
|
|
full_packet = package_head + upgrade_req
|
|
|
|
|
|
|
|
|
|
print("Full packet prepared:")
|
|
|
|
|
print(f"Header magic: {package_head[:3].hex()}")
|
|
|
|
|
print(f"Command: {cmd}, Version: {version}")
|
|
|
|
|
print(f"Upgrade length: {upgrade_len}, CRC: {crc}")
|
|
|
|
|
print(f"Total packet size: {len(full_packet)} bytes")
|
|
|
|
|
|
2025-06-21 17:24:51 +08:00
|
|
|
|
# 分包处理:每包最大1500字节
|
|
|
|
|
max_packet_size = 1500
|
|
|
|
|
total_size = len(full_packet)
|
|
|
|
|
num_packets = (total_size // max_packet_size) + (1 if total_size % max_packet_size != 0 else 0)
|
|
|
|
|
|
|
|
|
|
print(f"Total packets: {num_packets}, each up to {max_packet_size} bytes")
|
|
|
|
|
|
|
|
|
|
# 分包并发送
|
|
|
|
|
for i in range(num_packets):
|
|
|
|
|
start_index = i * max_packet_size
|
|
|
|
|
end_index = min((i + 1) * max_packet_size, total_size)
|
|
|
|
|
packet_chunk = full_packet[start_index:end_index]
|
|
|
|
|
|
|
|
|
|
print(f"Sending packet {i + 1}/{num_packets}, size: {len(packet_chunk)} bytes")
|
|
|
|
|
self.socket.write(packet_chunk)
|
|
|
|
|
print(f"Packet {i + 1} sent successfully")
|
|
|
|
|
time.sleep(0.05)
|
2025-04-08 16:47:59 +08:00
|
|
|
|
print("Upgrade packet ready to send (commented out actual send code)")
|
2025-06-24 17:59:40 +08:00
|
|
|
|
QMessageBox.information(
|
|
|
|
|
self,
|
|
|
|
|
"升级",
|
|
|
|
|
"升级包已成功上传"
|
|
|
|
|
)
|
2025-04-08 16:47:59 +08:00
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"Upgrade failed: {str(e)}")
|
2025-06-24 17:59:40 +08:00
|
|
|
|
QMessageBox.critical(
|
|
|
|
|
self,
|
|
|
|
|
"升级",
|
|
|
|
|
"升级包上传失败"
|
|
|
|
|
)
|
2025-02-22 13:55:58 +08:00
|
|
|
|
|
2025-04-15 14:18:19 +08:00
|
|
|
|
def on_button_upgrade_test(self):
|
|
|
|
|
"""打开文件选择对话框"""
|
|
|
|
|
file_path, _ = QFileDialog.getOpenFileName(
|
|
|
|
|
self, "选择升级文件", "", "二进制文件 (*.bin);;所有文件 (*)"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if file_path:
|
|
|
|
|
file_name = os.path.basename(file_path)
|
|
|
|
|
self.status_bar.showMessage(f"已选择: {file_name}")
|
|
|
|
|
try:
|
|
|
|
|
print("Starting upgrade process...")
|
|
|
|
|
|
|
|
|
|
if not os.path.exists(file_path):
|
|
|
|
|
raise FileNotFoundError(f"Upgrade file {file_path} not found")
|
|
|
|
|
|
|
|
|
|
with open(file_path, "rb") as f:
|
|
|
|
|
package_data = f.read()
|
|
|
|
|
|
|
|
|
|
if not package_data:
|
|
|
|
|
raise ValueError("Upgrade file is empty")
|
|
|
|
|
|
|
|
|
|
print(f"Read upgrade package, size: {len(package_data)} bytes")
|
|
|
|
|
|
|
|
|
|
upgrade_len = len(package_data)
|
|
|
|
|
crc = self.calculate_crc(package_data)
|
|
|
|
|
upgrade_req = struct.pack("<IB", upgrade_len, crc) + package_data
|
|
|
|
|
|
|
|
|
|
header_magic = bytes([0xAA, 0x55, 0xAA])
|
|
|
|
|
cmd = 0x05
|
|
|
|
|
version = 1
|
|
|
|
|
result_code = 0
|
|
|
|
|
|
|
|
|
|
package_head = struct.pack("<3sBBB", header_magic, cmd, version, result_code)
|
|
|
|
|
full_packet = package_head + upgrade_req
|
|
|
|
|
|
|
|
|
|
print("Full packet prepared:")
|
|
|
|
|
print(f"Header magic: {package_head[:3].hex()}")
|
|
|
|
|
print(f"Command: {cmd}, Version: {version}")
|
|
|
|
|
print(f"Upgrade length: {upgrade_len}, CRC: {crc}")
|
|
|
|
|
print(f"Total packet size: {len(full_packet)} bytes")
|
|
|
|
|
|
2025-04-16 14:52:26 +08:00
|
|
|
|
self.socket.write(full_packet)
|
2025-04-15 14:18:19 +08:00
|
|
|
|
sleep(15)
|
|
|
|
|
self.socket.close()
|
|
|
|
|
self.connect_to_server()
|
2025-04-16 14:52:26 +08:00
|
|
|
|
self.socket.write(full_packet)
|
2025-04-15 14:18:19 +08:00
|
|
|
|
print("Upgrade packet ready to send (commented out actual send code)")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"Upgrade failed: {str(e)}")
|
2025-06-21 10:36:45 +08:00
|
|
|
|
|
2025-05-26 20:31:47 +08:00
|
|
|
|
def on_button_temp(self):
|
|
|
|
|
try:
|
|
|
|
|
self.recv_state = ''
|
2025-06-21 10:36:45 +08:00
|
|
|
|
self.status_bar.showMessage("状态: 正在获取数据...", 3000)
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.socket.write(bytes(
|
|
|
|
|
[0xAA, 0x55, 0xAA, 0x0B, 0x01, 0x00])) # 发送数据
|
|
|
|
|
self.socket.waitForReadyRead()
|
|
|
|
|
except Exception as e:
|
|
|
|
|
self.status_bar.showMessage(f"状态: 错误 - {str(e)}")
|
|
|
|
|
|
|
|
|
|
def mac_config_dialog(self):
|
|
|
|
|
self.recv_state = ''
|
|
|
|
|
self.socket.readyRead.disconnect(self.on_ready_read)
|
|
|
|
|
dialog = MacConfigDialog(self.socket, self)
|
|
|
|
|
dialog.exec_()
|
|
|
|
|
self.socket.readyRead.connect(self.on_ready_read)
|
|
|
|
|
|
|
|
|
|
def ipv4_config_dialog(self):
|
|
|
|
|
self.recv_state = ''
|
|
|
|
|
self.socket.readyRead.disconnect(self.on_ready_read)
|
|
|
|
|
dialog = IPConfigDialog(self.socket, self)
|
|
|
|
|
dialog.exec_()
|
|
|
|
|
self.socket.readyRead.connect(self.on_ready_read)
|
|
|
|
|
|
|
|
|
|
def calibration_dialog(self):
|
|
|
|
|
self.recv_state = ''
|
|
|
|
|
self.socket.readyRead.disconnect(self.on_ready_read)
|
|
|
|
|
dialog = CalibrationDialog(self.socket, self)
|
|
|
|
|
dialog.exec_()
|
|
|
|
|
self.socket.readyRead.connect(self.on_ready_read)
|
2025-06-21 10:36:45 +08:00
|
|
|
|
|
2025-05-26 20:31:47 +08:00
|
|
|
|
def on_button_get_version(self):
|
|
|
|
|
try:
|
|
|
|
|
self.recv_state = ''
|
2025-06-21 10:36:45 +08:00
|
|
|
|
self.status_bar.showMessage("状态: 正在获取数据...", 3000)
|
2025-05-26 20:31:47 +08:00
|
|
|
|
self.socket.write(bytes(
|
|
|
|
|
[0xAA, 0x55, 0xAA, 0x0F, 0x01, 0x00])) # 发送数据
|
|
|
|
|
self.socket.waitForReadyRead()
|
|
|
|
|
except Exception as e:
|
|
|
|
|
self.status_bar.showMessage(f"状态: 错误 - {str(e)}")
|
2025-04-15 14:18:19 +08:00
|
|
|
|
|
2025-06-23 14:00:03 +08:00
|
|
|
|
def on_button_get_mac(self):
|
|
|
|
|
try:
|
|
|
|
|
self.recv_state = ''
|
|
|
|
|
self.status_bar.showMessage("状态: 正在获取数据...", 3000)
|
|
|
|
|
self.socket.write(bytes(
|
|
|
|
|
[0xAA, 0x55, 0xAA, 0x12, 0x01, 0x00])) # 发送数据
|
|
|
|
|
self.socket.waitForReadyRead()
|
|
|
|
|
except Exception as e:
|
|
|
|
|
self.status_bar.showMessage(f"状态: 错误 - {str(e)}")
|
|
|
|
|
|
2025-06-21 10:36:45 +08:00
|
|
|
|
|
2025-02-22 13:55:58 +08:00
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
app = QApplication(sys.argv)
|
|
|
|
|
window = SocketClientApp()
|
|
|
|
|
window.show()
|
|
|
|
|
sys.exit(app.exec_())
|