完成寄存器监听以及对应业务操作

This commit is contained in:
zhu-mengmeng 2025-06-12 10:25:33 +08:00
parent fddb83dcce
commit 79eca2b44f
7 changed files with 290 additions and 115 deletions

View File

@ -439,4 +439,22 @@ class InspectionDAO:
logging.error(f"保存包装记录失败: {str(e)}")
self.db.conn.rollback()
def delete_inspection_data(self, order_id, tray_id):
"""删除检验数据
Args:
order_id: 工程号
tray_id: 托盘号
"""
try:
sql = """
UPDATE inspection_data
SET is_deleted = TRUE
WHERE order_id = ? AND tray_id = ?
"""
params = (order_id, tray_id)
self.db.cursor.execute(sql, params)
self.db.conn.commit()
except Exception as e:
logging.error(f"删除检验数据失败: {str(e)}")
self.db.conn.rollback()

Binary file not shown.

View File

@ -2,8 +2,9 @@ from pymodbus.client import ModbusTcpClient
client = ModbusTcpClient('localhost', port=5020)
client.connect()
# client.write_registers(address=11, values=[117])
client.write_registers(address=13, values=[1])
# client.write_registers(address=11, values=[114])
client.write_registers(address=6, values=[1])
# client.write_registers(address=5, values=[16])
# client.write_registers(address=13, values=[1])

View File

@ -152,4 +152,13 @@ class InspectionConfigManager:
Returns:
list: 检验数据列表
"""
return self.dao.get_inspection_data_by_order(order_id)
return self.dao.get_inspection_data_by_order(order_id)
def delete_inspection_data(self, order_id, tray_id):
"""删除检验数据
Args:
order_id: 工程号
tray_id: 托盘号
"""
return self.dao.delete_inspection_data(order_id, tray_id)

View File

@ -77,7 +77,7 @@ class ModbusMonitor(QObject):
def _initialize_registers(self):
"""初始化要监控的寄存器列表"""
# 默认监控的寄存器地址
register_addresses = [11, 13, 20, 21, 22, 23, 24]
register_addresses = [4, 5, 6, 11, 13, 20, 21, 22, 23, 24]
for address in register_addresses:
self.registers[address] = RegisterValue(address)

View File

@ -47,6 +47,9 @@ class MachineStatusHandlers(QObject):
error_1_changed = Signal(int, str) # 故障信息1
error_2_changed = Signal(int, str) # 故障信息2
error_3_changed = Signal(int, str) # 故障信息3
weight_changed = Signal(int) # 称重数据变化
label_signal_changed = Signal(int, str) # 贴标信号变化
ng_changed = Signal(int) # NG信号变化
def __init__(self):
super().__init__()
@ -54,17 +57,13 @@ class MachineStatusHandlers(QObject):
# 上料信息反馈状态映射
self.loading_feedback_map = {
0: "无操作",
1: "上料中",
2: "上料完成",
3: "上料错误"
1: "上料",
}
# 下料信息反馈状态映射
self.unloading_feedback_map = {
0: "无操作",
1: "下料中",
2: "下料完成",
3: "下料错误"
1: "下料",
}
# 故障信息映射 - 可以根据实际设备故障码进行扩展
@ -76,58 +75,161 @@ class MachineStatusHandlers(QObject):
4: "气压不足",
5: "材料不足"
}
def handle_weight_data(self, weight):
"""处理称重数据"""
logging.info(f"[处理器] 称重数据: {weight}g")
# 发射信号由MainWindow更新UI
self.weight_changed.emit(weight)
def handle_label_signal(self, signal, status):
"""处理贴标信号"""
logging.info(f"[处理器] 贴标信号: {status} (值={signal})")
# 发射信号由MainWindow更新UI
self.label_signal_changed.emit(signal, status)
def handle_loading_feedback(self, status, description):
"""处理上料信息反馈"""
logging.info(f"[处理器] 上料信息反馈: {description} (值={status})")
self.loading_feedback_changed.emit(status, description)
def handle_unloading_feedback(self, status, description):
"""处理下料信息反馈"""
logging.info(f"[处理器] 下料信息反馈: {description} (值={status})")
self.unloading_feedback_changed.emit(status, description)
def handle_error_1(self, status, description):
"""处理故障信息1"""
logging.info(f"[处理器] 故障信息1: {description} (值={status})")
self.error_1_changed.emit(status, description)
def handle_error_2(self, status, description):
"""处理故障信息2"""
logging.info(f"[处理器] 故障信息2: {description} (值={status})")
self.error_2_changed.emit(status, description)
def handle_error_3(self, status, description):
"""处理故障信息3"""
logging.info(f"[处理器] 故障信息3: {description} (值={status})")
self.error_3_changed.emit(status, description)
def handle_ng(self, ng):
"""处理NG信号"""
logging.info(f"[处理器] NG信号: {ng}")
self.ng_changed.emit(ng)
class LoadingFeedbackHandler(RegisterHandler):
"""寄存器D20处理器处理上料信息反馈"""
def __init__(self, handlers):
self.handlers = handlers
def __init__(self, callback=None):
super().__init__()
self.callback = callback
def handle_change(self, value):
feedback = self.handlers.loading_feedback_map.get(value, f"未知状态({value})")
feedback = "上料" if value == 1 else "无操作"
logging.info(f"上料信息反馈: {feedback}")
self.handlers.loading_feedback_changed.emit(value, feedback)
# 如果有回调函数,则调用
if self.callback:
self.callback(value, feedback)
class UnloadingFeedbackHandler(RegisterHandler):
"""寄存器D21处理器处理下料信息反馈"""
def __init__(self, handlers):
self.handlers = handlers
def __init__(self, callback=None):
super().__init__()
self.callback = callback
def handle_change(self, value):
feedback = self.handlers.unloading_feedback_map.get(value, f"未知状态({value})")
feedback = "下料" if value == 1 else "无操作"
logging.info(f"下料信息反馈: {feedback}")
self.handlers.unloading_feedback_changed.emit(value, feedback)
# 如果有回调函数,则调用
if self.callback:
self.callback(value, feedback)
class Error1Handler(RegisterHandler):
"""寄存器D22处理器处理故障信息1"""
def __init__(self, handlers):
self.handlers = handlers
def __init__(self, callback=None):
super().__init__()
self.callback = callback
def handle_change(self, value):
error_desc = self.handlers.error_map.get(value, f"未知错误({value})")
error_desc = "正常" if value == 0 else f"故障类型1-{value}"
logging.info(f"故障信息1: {error_desc}")
self.handlers.error_1_changed.emit(value, error_desc)
# 如果有回调函数,则调用
if self.callback:
self.callback(value, error_desc)
class Error2Handler(RegisterHandler):
"""寄存器D23处理器处理故障信息2"""
def __init__(self, handlers):
self.handlers = handlers
def __init__(self, callback=None):
super().__init__()
self.callback = callback
def handle_change(self, value):
error_desc = self.handlers.error_map.get(value, f"未知错误({value})")
error_desc = "正常" if value == 0 else f"故障类型2-{value}"
logging.info(f"故障信息2: {error_desc}")
self.handlers.error_2_changed.emit(value, error_desc)
# 如果有回调函数,则调用
if self.callback:
self.callback(value, error_desc)
class Error3Handler(RegisterHandler):
"""寄存器D24处理器处理故障信息3"""
def __init__(self, handlers):
self.handlers = handlers
def __init__(self, callback=None):
super().__init__()
self.callback = callback
def handle_change(self, value):
error_desc = self.handlers.error_map.get(value, f"未知错误({value})")
error_desc = "正常" if value == 0 else f"故障类型3-{value}"
logging.info(f"故障信息3: {error_desc}")
self.handlers.error_3_changed.emit(value, error_desc)
# 如果有回调函数,则调用
if self.callback:
self.callback(value, error_desc)
class UnloadingLevelHandler(RegisterHandler):
"""寄存器D4处理器处理下料层数"""
def __init__(self, callback=None):
super().__init__()
self.callback = callback
def handle_change(self, value):
logging.info(f"下料层数变化: {value}")
# 如果有回调函数,则调用
if self.callback:
self.callback(value)
class UnloadingPositionHandler(RegisterHandler):
"""寄存器D5处理器处理下料位置"""
def __init__(self, callback=None):
super().__init__()
self.callback = callback
def handle_change(self, value):
logging.info(f"下料位置变化: {value}")
# 如果有回调函数,则调用
if self.callback:
self.callback(value)
class NGHandler(RegisterHandler):
"""寄存器D6处理器处理NG信号"""
def __init__(self, callback=None):
super().__init__()
self.callback = callback
def handle_change(self, value):
logging.info(f"NG信号变化: {value}")
#如果有回调函数,则调用
if self.callback:
self.callback(value)

View File

@ -7,6 +7,7 @@ from pathlib import Path
from utils.modbus_utils import ModbusUtils
from utils.modbus_monitor import get_instance as get_modbus_monitor
from utils.register_handlers import (
NGHandler,
WeightDataHandler,
LabelSignalHandler,
MachineStatusHandlers,
@ -14,12 +15,15 @@ from utils.register_handlers import (
UnloadingFeedbackHandler,
Error1Handler,
Error2Handler,
Error3Handler
Error3Handler,
UnloadingLevelHandler,
UnloadingPositionHandler
)
# 导入PySide6
from PySide6.QtWidgets import (
QWidget, QMessageBox, QTableWidgetItem, QStackedWidget, QLabel, QMainWindow,
QTableWidget, QMenu, QComboBox, QFormLayout, QDialog, QVBoxLayout, QHBoxLayout, QPushButton
QTableWidget, QMenu, QComboBox, QFormLayout, QDialog, QVBoxLayout, QHBoxLayout, QPushButton,
QStatusBar, QSplitter, QFrame
)
from PySide6.QtCore import Qt, QTimer, Slot
from PySide6.QtGui import QBrush, QColor
@ -81,11 +85,29 @@ class MainWindow(MainWindowUI):
self.material_content_layout.addWidget(self.material_placeholder)
# 为下料区添加占位标签,确保它保持为空
self.output_placeholder = QLabel("下料区 - 暂无内容")
self.output_placeholder.setAlignment(Qt.AlignCenter)
self.output_placeholder.setStyleSheet("color: #888888; background-color: #f0f0f0;")
self.output_placeholder = QWidget()
self.output_placeholder.setStyleSheet("background-color: #f0f0f0;")
placeholder_layout = QVBoxLayout(self.output_placeholder)
placeholder_layout.setAlignment(Qt.AlignCenter)
# 添加标题标签
title_label = QLabel("下料区")
title_label.setAlignment(Qt.AlignCenter)
title_label.setStyleSheet("color: #888888;")
title_label.setFont(self.second_title_font)
placeholder_layout.addWidget(title_label)
self.output_content_layout.addWidget(self.output_placeholder)
# 添加下料信息标签
self.unloading_level_label = QLabel("下料层数:--")
self.unloading_position_label = QLabel("下料位置:--")
placeholder_layout.addWidget(self.unloading_level_label)
placeholder_layout.addWidget(self.unloading_position_label)
self.unloading_level_label.setStyleSheet("color: #888888; font-weight: bold;")
self.unloading_position_label.setStyleSheet("color: #888888; font-weight: bold;")
self.unloading_level_label.setFont(self.normal_font)
self.unloading_position_label.setFont(self.normal_font)
# 创建堆叠部件
self.stacked_widget = QStackedWidget()
self.stacked_widget.addWidget(self.central_widget) # 主页面
@ -1354,25 +1376,33 @@ class MainWindow(MainWindowUI):
def _register_modbus_handlers(self):
"""注册寄存器处理器"""
# 注册D6处理器处理NG信号
self.modbus_monitor.register_handler(6, NGHandler(self.machine_handlers.handle_ng))
# 注册D11处理器处理称重数据
self.modbus_monitor.register_handler(11, WeightDataHandler(self.handle_weight_data))
self.modbus_monitor.register_handler(11, WeightDataHandler(self.machine_handlers.handle_weight_data))
# 注册D13处理器处理贴标信号
self.modbus_monitor.register_handler(13, LabelSignalHandler(self.handle_label_signal))
self.modbus_monitor.register_handler(13, LabelSignalHandler(self.machine_handlers.handle_label_signal))
# 注册D20-D24处理器处理各种状态信息
self.modbus_monitor.register_handler(20, LoadingFeedbackHandler(self.machine_handlers))
self.modbus_monitor.register_handler(21, UnloadingFeedbackHandler(self.machine_handlers))
self.modbus_monitor.register_handler(22, Error1Handler(self.machine_handlers))
self.modbus_monitor.register_handler(23, Error2Handler(self.machine_handlers))
self.modbus_monitor.register_handler(24, Error3Handler(self.machine_handlers))
self.modbus_monitor.register_handler(20, LoadingFeedbackHandler(self.handle_loading_feedback))
self.modbus_monitor.register_handler(21, UnloadingFeedbackHandler(self.handle_unloading_feedback))
self.modbus_monitor.register_handler(22, Error1Handler(self.machine_handlers.handle_error_1))
self.modbus_monitor.register_handler(23, Error2Handler(self.machine_handlers.handle_error_2))
self.modbus_monitor.register_handler(24, Error3Handler(self.machine_handlers.handle_error_3))
# 注册下料层数和位置处理器
self.modbus_monitor.register_handler(4, UnloadingLevelHandler(self.handle_unloading_level))
self.modbus_monitor.register_handler(5, UnloadingPositionHandler(self.handle_unloading_position))
def _connect_modbus_signals(self):
"""连接Modbus信号槽"""
# 连接监控器状态信号
self.modbus_monitor.monitor_status_changed.connect(self.handle_modbus_status)
self.modbus_monitor.monitor_status_changed.connect(self.handle_modbus_status_change)
self.modbus_monitor.register_error.connect(self.handle_register_error)
self.machine_handlers.ng_changed.connect(self.handle_ng)
# 直接连接寄存器变化信号
self.modbus_monitor.register_changed.connect(self.handle_register_change)
@ -1383,6 +1413,10 @@ class MainWindow(MainWindowUI):
self.machine_handlers.error_2_changed.connect(self.handle_error_2)
self.machine_handlers.error_3_changed.connect(self.handle_error_3)
# 连接称重数据和贴标信号
self.machine_handlers.weight_changed.connect(self.handle_weight_data)
self.machine_handlers.label_signal_changed.connect(self.handle_label_signal)
@Slot(int)
def handle_weight_data(self, weight):
"""处理称重数据变化"""
@ -1422,47 +1456,30 @@ class MainWindow(MainWindowUI):
logging.warning("工程号为空")
return
# 获取托盘号
tray_id = self.tray_edit.currentText()
# 断开单元格变更信号,避免程序自动写入时触发
# 暂时断开信号连接避免触发cellChanged信号
try:
self.process_table.cellChanged.disconnect(self.handle_inspection_cell_changed)
except:
logging.warning("断开单元格变更信号失败,可能信号未连接")
pass
# 创建并设置称重单元格
# 设置称重单元格
weight_item = QTableWidgetItem(str(weight))
weight_item.setTextAlignment(Qt.AlignCenter)
# 写入单元格
self.process_table.setItem(data_row, weight_col, weight_item)
logging.info(f"已将称重数据 {weight}g 写入表格单元格 [{data_row}, {weight_col}]")
# 保存称重数据到数据库
from dao.inspection_dao import InspectionDAO
inspection_dao = InspectionDAO()
# 构建数据
data = [{
'position': 12, # 称重位置是12
'config_id': 12,
'value': str(weight),
'status': 'pass',
'remark': '',
'tray_id': tray_id
}]
# 保存到数据库
inspection_dao.save_inspection_data(order_id, data)
logging.info(f"称重数据 {weight}g 已保存到数据库")
tray_id = self.tray_edit.currentText()
self.save_inspection_data(order_id, tray_id, 12, 12, str(weight), "pass")
# 重新连接单元格变更信号
# 重新连接信号
self.process_table.cellChanged.connect(self.handle_inspection_cell_changed)
logging.info(f"已将称重数据 {weight}g 写入行 {data_row}, 列 {weight_col}")
# TODO调用称重打印进行下一步打印
except Exception as e:
logging.error(f"写入称重数据到表格失败: {str(e)}")
# 确保信号重新连接
logging.error(f"处理称重数据时发生错误: {str(e)}")
# 确保重新连接信号
try:
self.process_table.cellChanged.connect(self.handle_inspection_cell_changed)
except:
@ -1470,17 +1487,18 @@ class MainWindow(MainWindowUI):
@Slot(int, str)
def handle_label_signal(self, signal, status):
"""处理贴标信号变化"""
logging.info(f"[处理] 贴标状态: {status}")
"""处理贴标信号"""
logging.info(f"[处理] 贴标信号: {status} (值={signal})")
# 更新UI显示
self.label_status_label.setText(f"贴标: {status}")
# 只有当信号为贴标完成(2)时才进行处理
# 只有当信号为贴标完成(1)时才进行处理
if signal == 1:
try:
# 获取数据行数
if self.process_table.rowCount() <= 2: # 没有数据行
logging.warning("没有可用的数据行来处理贴标完成信号")
logging.warning("没有可用的数据行来写入贴标数据")
return
# 获取当前选中的行或第一个数据行
@ -1519,7 +1537,7 @@ class MainWindow(MainWindowUI):
try:
self.process_table.cellChanged.disconnect(self.handle_inspection_cell_changed)
except:
logging.warning("断开单元格变更信号失败,可能信号未连接")
pass
# 创建并设置贴标单元格
label_item = QTableWidgetItem(label_value)
@ -1530,21 +1548,7 @@ class MainWindow(MainWindowUI):
logging.info(f"已将贴标数据 {label_value} 写入表格单元格 [{data_row}, {label_col}]")
# 保存贴标数据到数据库
from dao.inspection_dao import InspectionDAO
inspection_dao = InspectionDAO()
# 构建数据
data = [{
'position': 11, # 贴标位置是11
'config_id': 11,
'value': label_value,
'status': 'pass',
'remark': '',
'tray_id': tray_id
}]
# 保存到数据库
inspection_dao.save_inspection_data(order_id, data)
self.save_inspection_data(order_id, tray_id, 11, 11, label_value, "pass")
# 调用加载到包装记录的方法
self.load_finished_record_to_package_record(order_id, tray_id)
@ -1568,7 +1572,7 @@ class MainWindow(MainWindowUI):
pass
@Slot(bool, str)
def handle_modbus_status(self, is_connected, message):
def handle_modbus_status_change(self, is_connected, message):
"""处理Modbus连接状态变化"""
if is_connected:
self.modbus_status_label.setText("Modbus: 已连接")
@ -1599,28 +1603,27 @@ class MainWindow(MainWindowUI):
"""处理上料信息反馈"""
logging.info(f"[处理] 上料信息: {desc}")
# 如果上料完成(status=2),显示状态信息
if status == 2:
# 如果上料完成(status=1),显示状态信息,把上料寄存器置为 0
if status == 1:
modbus = ModbusUtils()
client = modbus.get_client()
modbus.write_register_until_success(client, 2, 0)
modbus.close_client(client)
self.show_operation_status("上料完成", "input", desc)
QMessageBox.information(self, "上料操作", f"上料操作已完成: {desc}")
# 如果上料错误(status=3),显示错误信息
elif status == 3:
self.show_operation_status("上料错误", "input", desc)
QMessageBox.warning(self, "上料操作", f"上料操作出错: {desc}")
@Slot(int, str)
def handle_unloading_feedback(self, status, desc):
"""处理下料信息反馈"""
logging.info(f"[处理] 下料信息: {desc}")
# 如果下料完成(status=2),显示状态信息
if status == 2:
self.show_operation_status("下料完成", "output", desc)
# 如果下料完成(status=1),显示状态信息,把下料寄存器置为 0
if status == 1:
modbus = ModbusUtils()
client = modbus.get_client()
modbus.write_register_until_success(client, 3, 0)
modbus.close_client(client)
self.show_operation_status("下料", "output", desc)
QMessageBox.information(self, "下料操作", f"下料操作已完成: {desc}")
# 如果下料错误(status=3),显示错误信息
elif status == 3:
self.show_operation_status("下料错误", "output", desc)
QMessageBox.warning(self, "下料操作", f"下料操作出错: {desc}")
def _update_error_status(self):
"""更新故障状态显示"""
@ -1665,8 +1668,13 @@ class MainWindow(MainWindowUI):
# 如果有故障,显示提示
if error_code > 0:
QMessageBox.warning(self, "设备故障", f"故障1: {error_desc}")
# 在这里添加其他故障处理逻辑
pass
# error_1 属于上料故障,需要把上料寄存器置为 0
modbus = ModbusUtils()
client = modbus.get_client()
modbus.write_register_until_success(client, 2, 0)
modbus.close_client(client)
self.show_operation_status("上料", "input", error_desc)
@Slot(int, str)
def handle_error_2(self, error_code, error_desc):
@ -1679,8 +1687,12 @@ class MainWindow(MainWindowUI):
# 如果有故障,显示提示
if error_code > 0:
QMessageBox.warning(self, "设备故障", f"故障2: {error_desc}")
# 在这里添加其他故障处理逻辑
pass
# error_2 属于下料故障,需要把下料寄存器置为 0
modbus = ModbusUtils()
client = modbus.get_client()
modbus.write_register_until_success(client, 3, 0)
modbus.close_client(client)
self.show_operation_status("下料", "output", error_desc)
@Slot(int, str)
def handle_error_3(self, error_code, error_desc):
@ -1693,5 +1705,38 @@ class MainWindow(MainWindowUI):
# 如果有故障,显示提示
if error_code > 0:
QMessageBox.warning(self, "设备故障", f"故障3: {error_desc}")
# 在这里添加其他故障处理逻辑
pass
# error_3 属于全局故障,需要把上料和下料寄存器置为 0
modbus = ModbusUtils()
client = modbus.get_client()
modbus.write_register_until_success(client, 2, 0)
modbus.write_register_until_success(client, 3, 0)
modbus.close_client(client)
self.show_operation_status("上料", "input", error_desc)
self.show_operation_status("下料", "output", error_desc)
@Slot(int)
def handle_unloading_level(self, level):
"""处理下料层数信息"""
self.unloading_level_label.setText(f"下料层数:{level}")
@Slot(int)
def handle_unloading_position(self, position):
"""处理下料位置信息"""
self.unloading_position_label.setText(f"下料位置:{position}")
@Slot(int)
def handle_ng(self, ng):
"""处理NG信号, 删除当前在处理的数据(也就是第一条数据)"""
if ng == 1:
# 获取当前选中的行或第一个数据行,并删除
order_id = self.process_table.item(2, 1).text().strip()
tray_id = self.tray_edit.currentText()
self.inspection_manager.delete_inspection_data(order_id, tray_id)
# 触发重新查询,更新数据
self.load_finished_inspection_data()
logging.info(f"已删除当前在处理的数据: order_id: {order_id}, tray_id: {tray_id}")
# 复原NG信号
modbus = ModbusUtils()
client = modbus.get_client()
modbus.write_register_until_success(client, 6, 0)
modbus.close_client(client)