rnc_tuning/br_widget_arr_details.py
2025-11-03 13:53:12 +08:00

367 lines
14 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 ui_arr_details import Ui_Widget
from PySide6.QtWidgets import QWidget, QTableWidgetItem
from PySide6.QtCore import Slot, Signal, SignalInstance
from param_data import ParamDataArr
from br_com_message import BrComMessage
from br_widget_basic_plot import BrWidgetBasicPlot
class BrWidgetArrDetails(QWidget, Ui_Widget):
signal_read: SignalInstance = Signal(list)
signal_write: SignalInstance = Signal(list)
signal_stop: SignalInstance = Signal()
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.param_data: ParamDataArr = None
self.is_reading = False
self.is_writing = False
self.read_count = 0 # 读取计数器
self.total_read_count = 0 # 总读取数量
self.write_count = 0 # 写入计数器
self.total_write_count = 0 # 总写入数量
self.processed_read_addresses = set() # 已处理的读取地址
self.processed_write_addresses = set() # 已处理的写入地址
# 初始化按钮状态
self.pushButton_read.setEnabled(True)
self.pushButton_write.setEnabled(True)
self.pushButton_read_stop.setEnabled(False)
self.pushButton_write_stop.setEnabled(False)
self.updating = False
self.tableWidget_val.setColumnCount(2)
self.tableWidget_val.setHorizontalHeaderLabels(['Addr', 'Value'])
self.tableWidget_setval.setColumnCount(2)
self.tableWidget_setval.setHorizontalHeaderLabels(['Addr', 'Value'])
self.tableWidget_setval.itemChanged.connect(self.on_table_setval_itemChanged)
self.pushButton_read_stop.clicked.connect(self.on_pushButton_read_stop_clicked)
self.pushButton_write_stop.clicked.connect(self.on_pushButton_write_stop_clicked)
def on_table_setval_itemChanged(self, item: QTableWidgetItem):
if self.updating:
return
# 获取编辑的行index,获取输入的值
row_index = item.row()
input_val = item.text()
self.param_data.setval_list[row_index] = float(input_val)
print('item changed', row_index, input_val)
def update_param_info(self, p_data: ParamDataArr):
self.param_data = p_data
self.label_addr.setText(str(p_data.addr))
self.label_name.setText(str(p_data.name))
self.label_length.setText(str(p_data.size))
self.label_details.setText(str(p_data.details))
self.update_table()
def update_table(self):
self.updating = True
self.tableWidget_val.setRowCount(self.param_data.size)
for row in range(0, self.param_data.size):
self.tableWidget_val.setItem(
row, 0, QTableWidgetItem(
str(self.param_data.addr + row)
)
)
self.tableWidget_val.setItem(
row, 1, QTableWidgetItem(
str(self.param_data.getval_list[row]))
)
self.tableWidget_setval.setRowCount(self.param_data.size)
# 增加table写功能
for row in range(0, self.param_data.size):
self.tableWidget_setval.setItem(
row, 0, QTableWidgetItem(
str(self.param_data.addr + row)
)
)
self.tableWidget_setval.setItem(
row, 1, QTableWidgetItem(
str(self.param_data.getval_list[row]))
)
# 把设定值设置为获取到的值
self.param_data.setval_list = self.param_data.getval_list
self.updating = False
def update_val_list(self):
for i in range(0, self.param_data.size):
self.tableWidget_val.setItem(0, i, QTableWidgetItem(str(self.param_data.getval_list[i])))
def update_setval_list(self):
for i in range(0, len(self.param_data.setval_list)):
self.tableWidget_setval.setItem(0, i, QTableWidgetItem(str(self.param_data.setval_list[i])))
def reset_read_state(self):
"""重置读取状态"""
print('Resetting read state')
self.is_reading = False
self.read_count = 0
self.total_read_count = 0
self.processed_read_addresses.clear()
self.pushButton_read.setEnabled(True)
self.pushButton_write.setEnabled(True)
self.pushButton_read_stop.setEnabled(False)
self.pushButton_write_stop.setEnabled(False)
def reset_write_state(self):
"""重置写入状态"""
print('Resetting write state')
self.is_writing = False
self.write_count = 0
self.total_write_count = 0
self.processed_write_addresses.clear()
self.pushButton_write.setEnabled(True)
self.pushButton_read.setEnabled(True)
self.pushButton_write_stop.setEnabled(False)
self.pushButton_read_stop.setEnabled(False)
@Slot()
def on_pushButton_read_clicked(self):
print('[read] button clicked!')
print(f'Starting read operation for array size: {self.param_data.size}')
# 确保之前的状态被清理
self.reset_read_state()
self.reset_write_state()
# 设置新的读取状态
self.is_reading = True
self.read_count = 0
self.total_read_count = self.param_data.size
# 设置按钮状态
self.pushButton_read.setEnabled(False)
self.pushButton_write.setEnabled(False)
self.pushButton_read_stop.setEnabled(True)
self.pushButton_write_stop.setEnabled(False)
# 生成一组读取命令
_cmd_list = []
print(f'Expected addresses to read: ', end='')
for i in range(0, self.param_data.size):
addr = self.param_data.addr + i
_cmd_list.append(
BrComMessage(
BrComMessage.OP_READ,
addr
)
)
print(f'{addr} ', end='')
print() # 换行
print(f'Initialized read operation: count={self.read_count}, total={self.total_read_count}')
self.signal_read.emit(_cmd_list)
@Slot()
def on_pushButton_write_clicked(self):
print('[write] button clicked!')
# 确保之前的状态被清理
self.reset_read_state()
self.reset_write_state()
# 设置新的写入状态
self.is_writing = True
self.write_count = 0
self.total_write_count = self.param_data.size
# 设置按钮状态
self.pushButton_write.setEnabled(False)
self.pushButton_read.setEnabled(False)
self.pushButton_write_stop.setEnabled(True)
self.pushButton_read_stop.setEnabled(False)
print(f'Initialized write operation: count={self.write_count}, total={self.total_write_count}')
_cmd_list = []
for i in range(0, self.param_data.size):
_cmd_list.append(
BrComMessage(
BrComMessage.OP_WRITE,
self.param_data.addr + i,
self.param_data.getval_list[i]
)
)
self.signal_write.emit(_cmd_list)
@Slot()
def on_pushButton_read_stop_clicked(self):
print('[read stop] button clicked!')
self.reset_read_state()
self.signal_stop.emit()
@Slot()
def on_pushButton_write_stop_clicked(self):
print('[write stop] button clicked!')
self.reset_write_state()
self.signal_stop.emit()
def operation_completed(self):
"""操作完成时调用此方法"""
if self.is_reading:
self.reset_read_state()
if self.is_writing:
self.reset_write_state()
@Slot()
def on_pushButton_valplot_clicked(self):
print('[valpolt] button clicked!')
self.dialog = BrWidgetBasicPlot()
self.dialog.set_chart_data(self.param_data.getval_list, self.param_data.name)
self.dialog.show()
@Slot()
def on_pushButton_setvalplot_clicked(self):
print('[setvalplot] button clicked!')
def resend_missing_read_commands(self):
"""重新发送未处理地址的读取命令"""
if not self.is_reading:
return
array_start = self.param_data.addr
array_end = self.param_data.addr + self.param_data.size
expected_addresses = set(range(array_start, array_end))
missing_addresses = expected_addresses - self.processed_read_addresses
if missing_addresses:
print(f'Resending read commands for missing addresses: {sorted(missing_addresses)}')
_cmd_list = []
for addr in sorted(missing_addresses):
_cmd_list.append(
BrComMessage(
BrComMessage.OP_READ,
addr
)
)
self.signal_read.emit(_cmd_list)
return True
return False
def check_read_complete(self, addr):
"""检查读取是否完成"""
print(f'Checking completion for addr: {addr}')
if not self.is_reading:
print(f'Not in reading state, ignoring addr: {addr}')
return
# 检查地址是否在当前数组范围内
array_start = self.param_data.addr
array_end = self.param_data.addr + self.param_data.size
print(f'Array range: {array_start} to {array_end-1}, checking addr: {addr}')
if array_start <= addr < array_end and addr not in self.processed_read_addresses:
self.processed_read_addresses.add(addr)
self.read_count += 1
print(f'Valid address {addr}, incrementing counter. Progress: {self.read_count}/{self.total_read_count}')
# 找出未处理的地址
expected_addresses = set(range(array_start, array_end))
missing_addresses = expected_addresses - self.processed_read_addresses
print(f'Missing addresses: {sorted(missing_addresses)}')
# 如果有未处理的地址且已经读取了一定数量比如80%)的地址,尝试重发
if missing_addresses and self.read_count >= self.total_read_count * 0.8:
print(f'Detected missing addresses at {self.read_count}/{self.total_read_count}, attempting retry')
if self.resend_missing_read_commands():
print('Resent read commands for missing addresses')
return
# 如果已经读取了预期数量的地址
if self.read_count >= self.total_read_count:
if not missing_addresses:
print(f'All data read (count={self.read_count}), completing operation')
self.reset_read_state()
self.signal_stop.emit()
print('Read operation fully completed')
else:
if addr in self.processed_read_addresses:
print(f'Address {addr} already processed')
else:
print(f'Address {addr} outside current array range ({array_start}-{array_end-1})')
def resend_missing_write_commands(self):
"""重新发送未处理地址的写入命令"""
if not self.is_writing:
return
array_start = self.param_data.addr
array_end = self.param_data.addr + self.param_data.size
expected_addresses = set(range(array_start, array_end))
missing_addresses = expected_addresses - self.processed_write_addresses
if missing_addresses:
print(f'Resending write commands for missing addresses: {sorted(missing_addresses)}')
_cmd_list = []
for addr in sorted(missing_addresses):
_cmd_list.append(
BrComMessage(
BrComMessage.OP_WRITE,
addr,
self.param_data.getval_list[addr - array_start]
)
)
self.signal_write.emit(_cmd_list)
return True
return False
def check_write_complete(self, addr):
"""检查写入是否完成"""
print(f'Checking completion for addr: {addr}')
if not self.is_writing:
print(f'Not in writing state, ignoring addr: {addr}')
return
# 检查地址是否在当前数组范围内
array_start = self.param_data.addr
array_end = self.param_data.addr + self.param_data.size
print(f'Array range: {array_start} to {array_end-1}, checking addr: {addr}')
if array_start <= addr < array_end and addr not in self.processed_write_addresses:
self.processed_write_addresses.add(addr)
self.write_count += 1
print(f'Valid address {addr}, incrementing counter. Progress: {self.write_count}/{self.total_write_count}')
# 找出未处理的地址
expected_addresses = set(range(array_start, array_end))
missing_addresses = expected_addresses - self.processed_write_addresses
print(f'Missing addresses: {sorted(missing_addresses)}')
# 如果有未处理的地址且已经写入了一定数量比如80%)的地址,尝试重发
if missing_addresses and self.write_count >= self.total_write_count * 0.8:
print(f'Detected missing addresses at {self.write_count}/{self.total_write_count}, attempting retry')
if self.resend_missing_write_commands():
print('Resent write commands for missing addresses')
return
# 如果已经写入了预期数量的地址
if self.write_count >= self.total_write_count:
if not missing_addresses:
print(f'All data written (count={self.write_count}), completing operation')
self.reset_write_state()
self.signal_stop.emit()
print('Write operation fully completed')
else:
if addr in self.processed_write_addresses:
print(f'Address {addr} already processed')
else:
print(f'Address {addr} outside current array range ({array_start}-{array_end-1})')
if __name__ == "__main__":
from PySide6.QtWidgets import QApplication
import sys
app = QApplication()
widget = BrWidgetArrDetails()
param_data = ParamDataArr(10, 'name', 'NULL', 0, 10)
widget.update_param_info(param_data)
widget.update_val_list()
widget.update_setval_list()
widget.show()
sys.exit(app.exec())