修改新增工程信息的逻辑,新增的数据往后延续,方便实现 FIFO
This commit is contained in:
parent
4b214ee4a6
commit
266380f43f
@ -314,7 +314,7 @@ class InspectionDAO:
|
||||
LEFT JOIN inspection_config c ON d.config_id = c.id
|
||||
WHERE d.is_deleted = FALSE AND d.tray_id = ?
|
||||
AND d.order_id IN ({placeholders})
|
||||
ORDER BY d.order_id, d.position
|
||||
ORDER BY d.create_time, d.order_id, d.position
|
||||
"""
|
||||
|
||||
params = [tray_id] + order_ids
|
||||
@ -358,7 +358,7 @@ class InspectionDAO:
|
||||
FROM inspection_data d
|
||||
LEFT JOIN inspection_config c ON d.config_id = c.id
|
||||
WHERE d.order_id = ? AND d.is_deleted = FALSE AND d.tray_id = ?
|
||||
ORDER BY d.position
|
||||
ORDER BY d.create_time, d.order_id, d.position
|
||||
"""
|
||||
params = (order_id, tray_id)
|
||||
|
||||
@ -386,31 +386,6 @@ class InspectionDAO:
|
||||
logging.error(f"获取检验数据失败: {str(e)}")
|
||||
return []
|
||||
|
||||
def get_inspection_unfinished_count(self, order_id, tray_id):
|
||||
"""根据托盘号和工程号获取未完成检验的数量,如果存在一个未完成则都算未完成
|
||||
|
||||
Args:
|
||||
order_id: 工程号
|
||||
tray_id: 托盘号
|
||||
Returns:
|
||||
tuple: 工程号, 托盘号, 未完成检验的数量
|
||||
"""
|
||||
try:
|
||||
sql ="""
|
||||
select order_id, tray_id, count(case when status != 'pass' then null else status end) as unfinished_count
|
||||
from inspection_data
|
||||
where is_deleted = 0 and order_id = ? and tray_id = ?
|
||||
group by order_id, tray_id
|
||||
"""
|
||||
params = (order_id, tray_id)
|
||||
self.db.cursor.execute(sql, params)
|
||||
result = self.db.cursor.fetchone()
|
||||
if result:
|
||||
return result[0], result[1], result[2]
|
||||
return order_id, tray_id, 0
|
||||
except Exception as e:
|
||||
logging.error(f"获取未完成检验数据失败: {str(e)}")
|
||||
return order_id, tray_id, 0
|
||||
|
||||
def get_package_record(self, tray_id):
|
||||
"""根据托盘号获取包装记录
|
||||
|
||||
BIN
db/jtDB.db
BIN
db/jtDB.db
Binary file not shown.
9
from pymodbus.py
Normal file
9
from pymodbus.py
Normal file
@ -0,0 +1,9 @@
|
||||
from pymodbus.client import ModbusTcpClient
|
||||
|
||||
client = ModbusTcpClient('localhost', port=5020)
|
||||
client.connect()
|
||||
client.write_registers(address=11, values=[15])
|
||||
|
||||
result = client.read_holding_registers(address=11, count=1)
|
||||
print(result,"123===")
|
||||
client.close()
|
||||
@ -501,13 +501,13 @@ class MainWindowUI(QMainWindow):
|
||||
self.record_layout.addWidget(self.record_title)
|
||||
|
||||
# 创建表格
|
||||
self.record_table = QTableWidget(14, 8) # 14行7列:序号、订单、材质、规格、托号、轴包装号、重量
|
||||
self.record_table = QTableWidget(14, 8) # 14行7列:序号、订单、品名、规格、托号、轴包装号、重量
|
||||
|
||||
# 应用通用表格设置
|
||||
self.setup_table_common(self.record_table)
|
||||
|
||||
# 设置列标题
|
||||
record_headers = ["序号", "订单", "材质", "规格", "托号", "轴包装号", "重量", "完成时间"]
|
||||
record_headers = ["序号", "订单", "品名", "规格", "托号", "轴包装号", "重量", "完成时间"]
|
||||
for col, header in enumerate(record_headers):
|
||||
self.record_table.setItem(0, col, self.create_header_item(header))
|
||||
|
||||
|
||||
258
utils/modbus_monitor.py
Normal file
258
utils/modbus_monitor.py
Normal file
@ -0,0 +1,258 @@
|
||||
import time
|
||||
import logging
|
||||
from threading import Thread, Event
|
||||
from PySide6.QtCore import QObject, Signal
|
||||
from .modbus_utils import ModbusUtils
|
||||
|
||||
class RegisterValue:
|
||||
"""寄存器值对象,用于存储寄存器的值和状态"""
|
||||
def __init__(self, address, value=None):
|
||||
self.address = address
|
||||
self.value = value
|
||||
self.last_value = None
|
||||
self.error_count = 0
|
||||
self.last_read_time = None
|
||||
self.last_change_time = None
|
||||
|
||||
def update(self, new_value):
|
||||
"""更新寄存器值,并返回值是否发生变化"""
|
||||
self.last_read_time = time.time()
|
||||
if self.value != new_value:
|
||||
self.last_value = self.value
|
||||
self.value = new_value
|
||||
self.last_change_time = self.last_read_time
|
||||
return True
|
||||
return False
|
||||
|
||||
def record_error(self):
|
||||
"""记录错误次数"""
|
||||
self.error_count += 1
|
||||
return self.error_count
|
||||
|
||||
def reset_error(self):
|
||||
"""重置错误计数"""
|
||||
self.error_count = 0
|
||||
|
||||
|
||||
class RegisterHandler:
|
||||
"""寄存器处理器基类"""
|
||||
def handle_change(self, value):
|
||||
"""处理寄存器值变化的方法,由子类实现具体逻辑"""
|
||||
pass
|
||||
|
||||
|
||||
class ModbusMonitor(QObject):
|
||||
"""Modbus寄存器监控器"""
|
||||
# 定义信号:寄存器地址、新值
|
||||
register_changed = Signal(int, int)
|
||||
register_error = Signal(int, str)
|
||||
monitor_status_changed = Signal(bool, str)
|
||||
|
||||
def __init__(self, polling_interval=1.0, max_errors=3, retry_interval=5.0):
|
||||
"""
|
||||
初始化Modbus监控器
|
||||
|
||||
Args:
|
||||
polling_interval: 轮询间隔,单位秒
|
||||
max_errors: 最大错误次数,超过此次数将暂停特定寄存器的监控
|
||||
retry_interval: 重试间隔,单位秒
|
||||
"""
|
||||
super().__init__()
|
||||
self.polling_interval = polling_interval
|
||||
self.max_errors = max_errors
|
||||
self.retry_interval = retry_interval
|
||||
|
||||
# 初始化存储
|
||||
self.registers = {} # 存储寄存器值的字典
|
||||
self.handlers = {} # 存储寄存器处理器的字典
|
||||
self.stop_event = Event() # 用于停止监控线程的事件
|
||||
self.monitor_thread = None
|
||||
self.modbus = ModbusUtils()
|
||||
self.client = None
|
||||
self.running = False
|
||||
|
||||
# 初始化要监控的寄存器列表
|
||||
self._initialize_registers()
|
||||
|
||||
def _initialize_registers(self):
|
||||
"""初始化要监控的寄存器列表"""
|
||||
# 默认监控的寄存器地址
|
||||
register_addresses = [11, 13, 20, 21, 22, 23, 24]
|
||||
for address in register_addresses:
|
||||
self.registers[address] = RegisterValue(address)
|
||||
|
||||
def register_handler(self, address, handler):
|
||||
"""注册寄存器处理器
|
||||
|
||||
Args:
|
||||
address: 寄存器地址
|
||||
handler: RegisterHandler的实例
|
||||
"""
|
||||
if address not in self.registers:
|
||||
self.registers[address] = RegisterValue(address)
|
||||
|
||||
if address not in self.handlers:
|
||||
self.handlers[address] = []
|
||||
|
||||
self.handlers[address].append(handler)
|
||||
logging.info(f"已注册寄存器D{address}的处理器: {handler.__class__.__name__}")
|
||||
|
||||
def start(self):
|
||||
"""启动监控线程"""
|
||||
if self.monitor_thread and self.monitor_thread.is_alive():
|
||||
logging.warning("监控器已经在运行中")
|
||||
return
|
||||
|
||||
self.stop_event.clear()
|
||||
self.monitor_thread = Thread(target=self._monitor_loop, daemon=True)
|
||||
self.monitor_thread.start()
|
||||
self.running = True
|
||||
self.monitor_status_changed.emit(True, "监控器已启动")
|
||||
logging.info("Modbus监控器已启动")
|
||||
|
||||
def stop(self):
|
||||
"""停止监控线程"""
|
||||
if not self.monitor_thread or not self.monitor_thread.is_alive():
|
||||
return
|
||||
|
||||
self.stop_event.set()
|
||||
if self.monitor_thread:
|
||||
self.monitor_thread.join(timeout=5.0) # 给线程5秒时间完成
|
||||
|
||||
if self.client:
|
||||
self.modbus.close_client(self.client)
|
||||
self.client = None
|
||||
|
||||
self.running = False
|
||||
self.monitor_status_changed.emit(False, "监控器已停止")
|
||||
logging.info("Modbus监控器已停止")
|
||||
|
||||
def _monitor_loop(self):
|
||||
"""监控循环,在独立线程中运行"""
|
||||
try:
|
||||
while not self.stop_event.is_set():
|
||||
# 检查连接并根据需要重新连接
|
||||
if not self.client:
|
||||
self._reconnect()
|
||||
|
||||
if self.client:
|
||||
# 读取并处理所有注册的寄存器
|
||||
self._read_registers()
|
||||
|
||||
# 等待下一次轮询,或者直到收到停止信号
|
||||
self.stop_event.wait(self.polling_interval)
|
||||
except Exception as e:
|
||||
logging.error(f"监控线程发生异常: {str(e)}", exc_info=True)
|
||||
self.monitor_status_changed.emit(False, f"监控器异常: {str(e)}")
|
||||
finally:
|
||||
if self.client:
|
||||
self.modbus.close_client(self.client)
|
||||
self.client = None
|
||||
|
||||
def _reconnect(self):
|
||||
"""重新连接到Modbus服务器"""
|
||||
try:
|
||||
if self.client:
|
||||
self.modbus.close_client(self.client)
|
||||
|
||||
self.client = self.modbus.get_client()
|
||||
if self.client:
|
||||
logging.info("Modbus监控器成功连接到服务器")
|
||||
self.monitor_status_changed.emit(True, "已连接到Modbus服务器")
|
||||
# 重置所有寄存器的错误计数
|
||||
for reg in self.registers.values():
|
||||
reg.reset_error()
|
||||
else:
|
||||
logging.warning("Modbus监控器无法连接到服务器")
|
||||
self.monitor_status_changed.emit(False, "无法连接到Modbus服务器")
|
||||
# 等待重试间隔
|
||||
self.stop_event.wait(self.retry_interval)
|
||||
except Exception as e:
|
||||
logging.error(f"重新连接Modbus服务器时发生错误: {str(e)}")
|
||||
self.monitor_status_changed.emit(False, f"连接错误: {str(e)}")
|
||||
# 等待重试间隔
|
||||
self.stop_event.wait(self.retry_interval)
|
||||
|
||||
def _read_registers(self):
|
||||
"""读取所有注册的寄存器"""
|
||||
for address, reg_value in self.registers.items():
|
||||
if self.stop_event.is_set():
|
||||
break
|
||||
|
||||
# 如果错误次数超过阈值且未到重试时间,则跳过此寄存器
|
||||
if reg_value.error_count >= self.max_errors:
|
||||
current_time = time.time()
|
||||
last_read = reg_value.last_read_time or 0
|
||||
if current_time - last_read < self.retry_interval:
|
||||
continue
|
||||
|
||||
try:
|
||||
# 读取寄存器值
|
||||
result = self.modbus.read_holding_register(self.client, address)
|
||||
if result is None or len(result) == 0:
|
||||
error_count = reg_value.record_error()
|
||||
error_msg = f"读取寄存器D{address}失败,这是第{error_count}次失败"
|
||||
logging.warning(error_msg)
|
||||
self.register_error.emit(address, error_msg)
|
||||
|
||||
# 如果连续失败次数达到阈值,尝试重连
|
||||
if error_count >= self.max_errors:
|
||||
logging.error(f"寄存器D{address}连续{error_count}次读取失败,将在{self.retry_interval}秒后重试")
|
||||
# 下次将在retry_interval后尝试读取此寄存器
|
||||
continue
|
||||
|
||||
# 成功读取,重置错误计数
|
||||
reg_value.reset_error()
|
||||
|
||||
# 更新值并检查是否发生变化
|
||||
if reg_value.update(result[0]):
|
||||
logging.info(f"寄存器D{address}值变化: {reg_value.last_value} -> {reg_value.value}")
|
||||
# 发出信号
|
||||
self.register_changed.emit(address, reg_value.value)
|
||||
# 调用注册的处理器
|
||||
self._notify_handlers(address, reg_value.value)
|
||||
except Exception as e:
|
||||
error_count = reg_value.record_error()
|
||||
error_msg = f"读取寄存器D{address}时发生异常: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
self.register_error.emit(address, error_msg)
|
||||
|
||||
if error_count >= self.max_errors:
|
||||
logging.error(f"寄存器D{address}连续{error_count}次读取异常,将在{self.retry_interval}秒后重试")
|
||||
|
||||
def _notify_handlers(self, address, value):
|
||||
"""通知所有注册的处理器"""
|
||||
if address in self.handlers:
|
||||
for handler in self.handlers[address]:
|
||||
try:
|
||||
handler.handle_change(value)
|
||||
except Exception as e:
|
||||
logging.error(f"调用寄存器D{address}的处理器时发生异常: {str(e)}", exc_info=True)
|
||||
|
||||
def get_register_value(self, address):
|
||||
"""获取寄存器的当前值
|
||||
|
||||
Args:
|
||||
address: 寄存器地址
|
||||
|
||||
Returns:
|
||||
当前值,如果未读取过则返回None
|
||||
"""
|
||||
if address in self.registers:
|
||||
return self.registers[address].value
|
||||
return None
|
||||
|
||||
def is_running(self):
|
||||
"""返回监控器是否正在运行"""
|
||||
return self.running and self.monitor_thread and self.monitor_thread.is_alive()
|
||||
|
||||
|
||||
# 单例模式
|
||||
_instance = None
|
||||
|
||||
def get_instance():
|
||||
"""获取ModbusMonitor单例"""
|
||||
global _instance
|
||||
if _instance is None:
|
||||
_instance = ModbusMonitor()
|
||||
return _instance
|
||||
135
utils/register_handlers.py
Normal file
135
utils/register_handlers.py
Normal file
@ -0,0 +1,135 @@
|
||||
import logging
|
||||
from PySide6.QtCore import QObject, Signal
|
||||
from .modbus_monitor import RegisterHandler
|
||||
|
||||
class WeightDataHandler(RegisterHandler):
|
||||
"""寄存器D11处理器,处理称重数据值"""
|
||||
def __init__(self, callback=None):
|
||||
super().__init__()
|
||||
self.callback = callback
|
||||
self.last_weight = None
|
||||
|
||||
def handle_change(self, value):
|
||||
weight = value # 可能需要转换单位或格式,这里简单处理
|
||||
logging.info(f"称重数据变化: {self.last_weight} -> {weight}")
|
||||
self.last_weight = weight
|
||||
|
||||
# 如果有回调函数,则调用
|
||||
if self.callback:
|
||||
self.callback(weight)
|
||||
|
||||
|
||||
class LabelSignalHandler(RegisterHandler):
|
||||
"""寄存器D13处理器,处理贴标信号"""
|
||||
def __init__(self, callback=None):
|
||||
super().__init__()
|
||||
self.callback = callback
|
||||
self.status_map = {
|
||||
0: "无贴标",
|
||||
1: "贴标中",
|
||||
2: "贴标完成",
|
||||
3: "贴标错误"
|
||||
}
|
||||
|
||||
def handle_change(self, value):
|
||||
status = self.status_map.get(value, f"未知状态({value})")
|
||||
logging.info(f"贴标信号: {status}")
|
||||
|
||||
# 如果有回调函数,则调用
|
||||
if self.callback:
|
||||
self.callback(value, status)
|
||||
|
||||
|
||||
class MachineStatusHandlers(QObject):
|
||||
"""机器状态相关寄存器(D20-D24)处理器集合"""
|
||||
|
||||
# 定义信号
|
||||
loading_feedback_changed = Signal(int, str) # 上料信息反馈
|
||||
unloading_feedback_changed = Signal(int, str) # 下料信息反馈
|
||||
error_1_changed = Signal(int, str) # 故障信息1
|
||||
error_2_changed = Signal(int, str) # 故障信息2
|
||||
error_3_changed = Signal(int, str) # 故障信息3
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
# 上料信息反馈状态映射
|
||||
self.loading_feedback_map = {
|
||||
0: "无操作",
|
||||
1: "上料中",
|
||||
2: "上料完成",
|
||||
3: "上料错误"
|
||||
}
|
||||
|
||||
# 下料信息反馈状态映射
|
||||
self.unloading_feedback_map = {
|
||||
0: "无操作",
|
||||
1: "下料中",
|
||||
2: "下料完成",
|
||||
3: "下料错误"
|
||||
}
|
||||
|
||||
# 故障信息映射 - 可以根据实际设备故障码进行扩展
|
||||
self.error_map = {
|
||||
0: "正常",
|
||||
1: "急停触发",
|
||||
2: "通信错误",
|
||||
3: "伺服报警",
|
||||
4: "气压不足",
|
||||
5: "材料不足"
|
||||
}
|
||||
|
||||
|
||||
class LoadingFeedbackHandler(RegisterHandler):
|
||||
"""寄存器D20处理器,处理上料信息反馈"""
|
||||
def __init__(self, handlers):
|
||||
self.handlers = handlers
|
||||
|
||||
def handle_change(self, value):
|
||||
feedback = self.handlers.loading_feedback_map.get(value, f"未知状态({value})")
|
||||
logging.info(f"上料信息反馈: {feedback}")
|
||||
self.handlers.loading_feedback_changed.emit(value, feedback)
|
||||
|
||||
|
||||
class UnloadingFeedbackHandler(RegisterHandler):
|
||||
"""寄存器D21处理器,处理下料信息反馈"""
|
||||
def __init__(self, handlers):
|
||||
self.handlers = handlers
|
||||
|
||||
def handle_change(self, value):
|
||||
feedback = self.handlers.unloading_feedback_map.get(value, f"未知状态({value})")
|
||||
logging.info(f"下料信息反馈: {feedback}")
|
||||
self.handlers.unloading_feedback_changed.emit(value, feedback)
|
||||
|
||||
|
||||
class Error1Handler(RegisterHandler):
|
||||
"""寄存器D22处理器,处理故障信息1"""
|
||||
def __init__(self, handlers):
|
||||
self.handlers = handlers
|
||||
|
||||
def handle_change(self, value):
|
||||
error_desc = self.handlers.error_map.get(value, f"未知错误({value})")
|
||||
logging.info(f"故障信息1: {error_desc}")
|
||||
self.handlers.error_1_changed.emit(value, error_desc)
|
||||
|
||||
|
||||
class Error2Handler(RegisterHandler):
|
||||
"""寄存器D23处理器,处理故障信息2"""
|
||||
def __init__(self, handlers):
|
||||
self.handlers = handlers
|
||||
|
||||
def handle_change(self, value):
|
||||
error_desc = self.handlers.error_map.get(value, f"未知错误({value})")
|
||||
logging.info(f"故障信息2: {error_desc}")
|
||||
self.handlers.error_2_changed.emit(value, error_desc)
|
||||
|
||||
|
||||
class Error3Handler(RegisterHandler):
|
||||
"""寄存器D24处理器,处理故障信息3"""
|
||||
def __init__(self, handlers):
|
||||
self.handlers = handlers
|
||||
|
||||
def handle_change(self, value):
|
||||
error_desc = self.handlers.error_map.get(value, f"未知错误({value})")
|
||||
logging.info(f"故障信息3: {error_desc}")
|
||||
self.handlers.error_3_changed.emit(value, error_desc)
|
||||
@ -5,12 +5,23 @@ import json
|
||||
from datetime import datetime
|
||||
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 (
|
||||
WeightDataHandler,
|
||||
LabelSignalHandler,
|
||||
MachineStatusHandlers,
|
||||
LoadingFeedbackHandler,
|
||||
UnloadingFeedbackHandler,
|
||||
Error1Handler,
|
||||
Error2Handler,
|
||||
Error3Handler
|
||||
)
|
||||
# 导入PySide6
|
||||
from PySide6.QtWidgets import (
|
||||
QWidget, QMessageBox, QTableWidgetItem, QStackedWidget, QLabel, QMainWindow,
|
||||
QTableWidget, QMenu, QComboBox, QFormLayout, QDialog, QVBoxLayout, QHBoxLayout, QPushButton
|
||||
)
|
||||
from PySide6.QtCore import Qt, QTimer
|
||||
from PySide6.QtCore import Qt, QTimer, Slot
|
||||
from PySide6.QtGui import QBrush, QColor
|
||||
|
||||
# 导入UI
|
||||
@ -260,7 +271,7 @@ class MainWindow(MainWindowUI):
|
||||
layout = QVBoxLayout(dialog)
|
||||
|
||||
# 添加提示信息
|
||||
info_label = QLabel("请选择上料托盘类型:")
|
||||
info_label = QLabel("请选择拆垛层数:")
|
||||
info_label.setFont(self.normal_font)
|
||||
layout.addWidget(info_label)
|
||||
|
||||
@ -382,7 +393,7 @@ class MainWindow(MainWindowUI):
|
||||
|
||||
def handle_start(self):
|
||||
"""
|
||||
处理开始按钮点击事件
|
||||
处理开始按钮点击事件,并启动 modbus 监控
|
||||
"""
|
||||
# 创建对话框
|
||||
dialog = QDialog(self)
|
||||
@ -393,7 +404,7 @@ class MainWindow(MainWindowUI):
|
||||
layout = QVBoxLayout(dialog)
|
||||
|
||||
# 添加提示信息
|
||||
info_label = QLabel("请选择上料托盘类型:")
|
||||
info_label = QLabel("请选择拆垛层数:")
|
||||
info_label.setFont(self.normal_font)
|
||||
layout.addWidget(info_label)
|
||||
|
||||
@ -442,6 +453,9 @@ class MainWindow(MainWindowUI):
|
||||
modbus = ModbusUtils()
|
||||
client = modbus.get_client()
|
||||
try:
|
||||
# 启动Modbus监控
|
||||
self.setup_modbus_monitor()
|
||||
|
||||
success0 = modbus.write_register_until_success(client, 0, int(stow_num))
|
||||
success1 = modbus.write_register_until_success(client, 1, int(pallet_type))
|
||||
success2 = modbus.write_register_until_success(client, 2, 1)
|
||||
@ -460,7 +474,7 @@ class MainWindow(MainWindowUI):
|
||||
modbus.close_client(client)
|
||||
|
||||
def handle_stop(self):
|
||||
"""处理停止按钮点击事件"""
|
||||
"""处理停止按钮点击事件,并关闭 modbus 监控"""
|
||||
modbus = ModbusUtils()
|
||||
client = modbus.get_client()
|
||||
try:
|
||||
@ -474,6 +488,10 @@ class MainWindow(MainWindowUI):
|
||||
QMessageBox.critical(self, "错误", f"停止操作失败: {str(e)}")
|
||||
finally:
|
||||
modbus.close_client(client)
|
||||
# 停止Modbus监控
|
||||
if hasattr(self, 'modbus_monitor'):
|
||||
logging.info("停止Modbus监控")
|
||||
self.modbus_monitor.stop()
|
||||
|
||||
def handle_camera_status(self, is_connected, message):
|
||||
"""处理相机状态变化"""
|
||||
@ -509,13 +527,18 @@ class MainWindow(MainWindowUI):
|
||||
|
||||
def closeEvent(self, event):
|
||||
"""窗口关闭事件"""
|
||||
# 停止Modbus监控
|
||||
if hasattr(self, 'modbus_monitor'):
|
||||
logging.info("停止Modbus监控")
|
||||
self.modbus_monitor.stop()
|
||||
|
||||
# 只有在相机启用时处理相机关闭
|
||||
if self.camera_enabled and hasattr(self, 'camera_display'):
|
||||
# 停止相机显示
|
||||
self.camera_display.stop_display()
|
||||
|
||||
# 接受关闭事件
|
||||
event.accept()
|
||||
event.accept()
|
||||
|
||||
def handle_order_enter(self):
|
||||
"""处理工程号输入框按下回车事件"""
|
||||
@ -537,7 +560,7 @@ class MainWindow(MainWindowUI):
|
||||
self.central_widget.setFocus()
|
||||
|
||||
def add_new_inspection_row(self, order_id):
|
||||
"""在微丝产线表格中添加一条新记录
|
||||
"""在微丝产线表格中添加一条新记录,添加到表格末尾
|
||||
|
||||
Args:
|
||||
order_id: 工程号
|
||||
@ -546,35 +569,36 @@ class MainWindow(MainWindowUI):
|
||||
# 获取启用的检验配置
|
||||
enabled_configs = self.inspection_manager.get_enabled_configs()
|
||||
|
||||
# 固定的数据起始行索引
|
||||
data_start_row = 2 # 数据从第3行开始
|
||||
|
||||
# 断开单元格变更信号,避免加载过程中触发保存
|
||||
try:
|
||||
self.process_table.cellChanged.disconnect(self.handle_inspection_cell_changed)
|
||||
except:
|
||||
pass
|
||||
|
||||
# 在指定行索引插入新行 - 总是插入到第一个数据行
|
||||
# 计算新行的行索引(添加到末尾)
|
||||
data_start_row = self.process_table.rowCount()
|
||||
|
||||
# 在末尾添加新行
|
||||
self.process_table.insertRow(data_start_row)
|
||||
|
||||
# 更新序号 - 所有现有行序号+1
|
||||
for row in range(data_start_row + 1, self.process_table.rowCount()):
|
||||
seq_item = self.process_table.item(row, 0)
|
||||
if seq_item:
|
||||
# 计算新行的序号(最后一个序号+1)
|
||||
new_seq = 1 # 默认为1
|
||||
if data_start_row > 2: # 如果有其他数据行
|
||||
prev_seq_item = self.process_table.item(data_start_row - 1, 0)
|
||||
if prev_seq_item:
|
||||
try:
|
||||
current_seq = int(seq_item.text())
|
||||
seq_item.setText(str(current_seq + 1))
|
||||
prev_seq = int(prev_seq_item.text())
|
||||
new_seq = prev_seq + 1
|
||||
except ValueError:
|
||||
pass
|
||||
new_seq = data_start_row - 1 # 备选方案:使用行索引作为序号
|
||||
|
||||
# 添加工程号到表格的第二列
|
||||
item = QTableWidgetItem(order_id)
|
||||
item.setTextAlignment(Qt.AlignCenter)
|
||||
self.process_table.setItem(data_start_row, 1, item)
|
||||
|
||||
# 添加序号到表格的第一列 - 新行始终是第1条
|
||||
item = QTableWidgetItem("1")
|
||||
# 添加序号到表格的第一列
|
||||
item = QTableWidgetItem(str(new_seq))
|
||||
item.setTextAlignment(Qt.AlignCenter)
|
||||
self.process_table.setItem(data_start_row, 0, item)
|
||||
|
||||
@ -638,7 +662,7 @@ class MainWindow(MainWindowUI):
|
||||
}]
|
||||
inspection_dao.save_inspection_data(order_id, data)
|
||||
|
||||
logging.info(f"已添加工程号 {order_id} 的新记录,显示在第1条")
|
||||
logging.info(f"已添加工程号 {order_id} 的新记录,显示在第{new_seq}条")
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"添加新记录失败: {str(e)}")
|
||||
@ -672,7 +696,7 @@ class MainWindow(MainWindowUI):
|
||||
logging.error(f"限制表格行数失败: {str(e)}")
|
||||
|
||||
def handle_inspection_cell_changed(self, row, column):
|
||||
"""处理检验单元格内容变更
|
||||
"""处理微丝包装单元格内容变更
|
||||
|
||||
Args:
|
||||
row: 行索引
|
||||
@ -843,7 +867,8 @@ class MainWindow(MainWindowUI):
|
||||
try:
|
||||
from dao.inspection_dao import InspectionDAO
|
||||
inspection_dao = InspectionDAO()
|
||||
|
||||
modbus = ModbusUtils()
|
||||
client = modbus.get_client()
|
||||
# 记录保存前的详细日志
|
||||
logging.info(f"正在保存检验数据: 工程号={order_id}, 托盘号={tray_id}, 位置={position}, 配置ID={config_id}, 值={value}, 状态={status}")
|
||||
|
||||
@ -858,24 +883,24 @@ class MainWindow(MainWindowUI):
|
||||
}]
|
||||
|
||||
# 保存到数据库
|
||||
result = inspection_dao.save_inspection_data(order_id, data)
|
||||
if result:
|
||||
logging.info(f"已成功保存工程号 {order_id} 的检验数据,位置: {position}, 值: {value}")
|
||||
# 显示临时状态消息
|
||||
self.statusBar().showMessage(f"已保存检验数据:{value}", 3000)
|
||||
inspection_dao.save_inspection_data(order_id, data)
|
||||
# if result:
|
||||
# logging.info(f"已成功保存工程号 {order_id} 的检验数据,位置: {position}, 值: {value}")
|
||||
# # 显示临时状态消息
|
||||
# self.statusBar().showMessage(f"已保存检验数据:{value}", 3000)
|
||||
|
||||
# 如果是贴标字段且有值,直接写入包装记录
|
||||
if position == 11 and value:
|
||||
# 直接调用加载到包装记录的方法
|
||||
self.load_finished_record_to_package_record(order_id, tray_id)
|
||||
logging.info(f"检测到贴标字段有值,已自动写入包装记录")
|
||||
else:
|
||||
# 使用延迟调用,避免频繁刷新UI
|
||||
QTimer.singleShot(500, self.check_and_process_finished_records)
|
||||
else:
|
||||
logging.warning(f"保存工程号 {order_id} 的检验数据失败")
|
||||
# 显示错误消息
|
||||
self.statusBar().showMessage(f"保存检验数据失败", 3000)
|
||||
# #TODO: 如果是称重字段,生成贴标号,然后给打印机信号,进行贴标
|
||||
# if position == 12 and value:
|
||||
# # 直接调用加载到包装记录的方法
|
||||
# self.load_finished_record_to_package_record(order_id, tray_id)
|
||||
# logging.info(f"检测到称重字段有值,已自动写入包装记录")
|
||||
# else:
|
||||
# # 使用延迟调用,避免频繁刷新UI
|
||||
# QTimer.singleShot(500, self.check_and_process_finished_records)
|
||||
# else:
|
||||
# logging.warning(f"保存工程号 {order_id} 的检验数据失败")
|
||||
# # 显示错误消息
|
||||
# self.statusBar().showMessage(f"保存检验数据失败", 3000)
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"保存检验数据失败: {str(e)}")
|
||||
@ -929,7 +954,7 @@ class MainWindow(MainWindowUI):
|
||||
row_idx = 2
|
||||
|
||||
# 确保按工程号倒序排列,最新的工程号在最前面
|
||||
sorted_order_ids = sorted(orders_data.keys(), reverse=True)
|
||||
sorted_order_ids = sorted(orders_data.keys(), reverse=False)
|
||||
|
||||
for order_id in sorted_order_ids:
|
||||
items = orders_data[order_id]
|
||||
@ -967,16 +992,7 @@ class MainWindow(MainWindowUI):
|
||||
cell_item = QTableWidgetItem(str(value))
|
||||
cell_item.setTextAlignment(Qt.AlignCenter)
|
||||
# 存储配置ID,用于保存时确定是哪个检验项
|
||||
cell_item.setData(Qt.UserRole, config_id)
|
||||
|
||||
# 根据状态设置单元格颜色
|
||||
if status == 'fail':
|
||||
cell_item.setBackground(QBrush(QColor("#ffcdd2"))) # 浅红色
|
||||
elif status == 'warning':
|
||||
cell_item.setBackground(QBrush(QColor("#fff9c4"))) # 浅黄色
|
||||
elif status == 'pass':
|
||||
cell_item.setBackground(QBrush(QColor("#c8e6c9"))) # 浅绿色
|
||||
|
||||
cell_item.setData(Qt.UserRole, config_id)
|
||||
# 设置单元格
|
||||
self.process_table.setItem(row_idx, col_index, cell_item)
|
||||
# 添加贴标(11)和称重数据(12)
|
||||
@ -1358,4 +1374,262 @@ class MainWindow(MainWindowUI):
|
||||
# 调用原始的resizeEvent(如果有的话)
|
||||
original_resize = getattr(container, "_original_resize_event", None)
|
||||
if original_resize:
|
||||
original_resize(event)
|
||||
original_resize(event)
|
||||
|
||||
# ==================== Modbus监控系统相关方法 ====================
|
||||
|
||||
def setup_modbus_monitor(self):
|
||||
"""设置Modbus监控系统"""
|
||||
# 获取Modbus监控器实例
|
||||
self.modbus_monitor = get_modbus_monitor()
|
||||
|
||||
# 创建机器状态处理器实例
|
||||
self.machine_handlers = MachineStatusHandlers()
|
||||
|
||||
# 添加状态显示到状态栏
|
||||
self.modbus_status_label = QLabel("Modbus: 未连接")
|
||||
self.weight_label = QLabel("重量: --")
|
||||
self.label_status_label = QLabel("贴标: 无贴标")
|
||||
self.error_status_label = QLabel("故障: 无")
|
||||
|
||||
# 设置样式
|
||||
self.error_status_label.setStyleSheet("color: green; font-weight: bold;")
|
||||
|
||||
# 添加到状态栏
|
||||
self.statusBar().addPermanentWidget(self.modbus_status_label)
|
||||
self.statusBar().addPermanentWidget(self.weight_label)
|
||||
self.statusBar().addPermanentWidget(self.label_status_label)
|
||||
self.statusBar().addPermanentWidget(self.error_status_label)
|
||||
|
||||
# 注册寄存器处理器
|
||||
self._register_modbus_handlers()
|
||||
|
||||
# 连接信号槽
|
||||
self._connect_modbus_signals()
|
||||
|
||||
# 启动监控
|
||||
self.modbus_monitor.start()
|
||||
|
||||
logging.info("Modbus监控系统已设置")
|
||||
|
||||
def _register_modbus_handlers(self):
|
||||
"""注册寄存器处理器"""
|
||||
# 注册D11处理器,处理称重数据
|
||||
self.modbus_monitor.register_handler(11, WeightDataHandler(self.handle_weight_data))
|
||||
|
||||
# 注册D13处理器,处理贴标信号
|
||||
self.modbus_monitor.register_handler(13, LabelSignalHandler(self.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))
|
||||
|
||||
def _connect_modbus_signals(self):
|
||||
"""连接Modbus信号槽"""
|
||||
# 连接监控器状态信号
|
||||
self.modbus_monitor.monitor_status_changed.connect(self.handle_modbus_status)
|
||||
self.modbus_monitor.register_error.connect(self.handle_register_error)
|
||||
|
||||
# 直接连接寄存器变化信号
|
||||
self.modbus_monitor.register_changed.connect(self.handle_register_change)
|
||||
|
||||
# 连接机器状态信号
|
||||
self.machine_handlers.loading_feedback_changed.connect(self.handle_loading_feedback)
|
||||
self.machine_handlers.unloading_feedback_changed.connect(self.handle_unloading_feedback)
|
||||
self.machine_handlers.error_1_changed.connect(self.handle_error_1)
|
||||
self.machine_handlers.error_2_changed.connect(self.handle_error_2)
|
||||
self.machine_handlers.error_3_changed.connect(self.handle_error_3)
|
||||
|
||||
@Slot(int)
|
||||
def handle_weight_data(self, weight):
|
||||
"""处理称重数据变化"""
|
||||
logging.info(f"[处理] 称重数据: {weight}g")
|
||||
# 更新UI显示
|
||||
self.weight_label.setText(f"重量: {weight}g")
|
||||
|
||||
try:
|
||||
# 获取数据行数
|
||||
if self.process_table.rowCount() <= 2: # 没有数据行
|
||||
logging.warning("没有可用的数据行来写入称重数据")
|
||||
return
|
||||
|
||||
# 获取启用的检验配置
|
||||
enabled_configs = self.inspection_manager.get_enabled_configs()
|
||||
|
||||
# 计算称重列索引 - 称重位置在检验列之后的第二列(贴标后面)
|
||||
weight_col = 2 + len(enabled_configs) + 1
|
||||
|
||||
# 获取当前选中的行或第一个数据行
|
||||
current_row = self.process_table.currentRow()
|
||||
data_row = current_row if current_row >= 2 else 2 # 使用第一个数据行(索引为2)
|
||||
|
||||
# 确保行存在
|
||||
if data_row >= self.process_table.rowCount():
|
||||
logging.warning(f"选中的行 {data_row} 超出了表格范围")
|
||||
return
|
||||
|
||||
# 获取工程号
|
||||
order_id_item = self.process_table.item(data_row, 1)
|
||||
if not order_id_item:
|
||||
logging.warning("无法获取工程号")
|
||||
return
|
||||
|
||||
order_id = order_id_item.text().strip()
|
||||
if not order_id:
|
||||
logging.warning("工程号为空")
|
||||
return
|
||||
|
||||
# 断开单元格变更信号,避免程序自动写入时触发
|
||||
try:
|
||||
self.process_table.cellChanged.disconnect(self.handle_inspection_cell_changed)
|
||||
except:
|
||||
logging.warning("断开单元格变更信号失败,可能信号未连接")
|
||||
|
||||
# 创建并设置称重单元格
|
||||
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}]")
|
||||
|
||||
# 重新连接单元格变更信号
|
||||
self.process_table.cellChanged.connect(self.handle_inspection_cell_changed)
|
||||
|
||||
# 主动触发单元格变更事件
|
||||
self.handle_inspection_cell_changed(data_row, weight_col)
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"写入称重数据到表格失败: {str(e)}")
|
||||
# 确保信号重新连接
|
||||
try:
|
||||
self.process_table.cellChanged.connect(self.handle_inspection_cell_changed)
|
||||
except:
|
||||
pass
|
||||
|
||||
@Slot(int, str)
|
||||
def handle_label_signal(self, signal, status):
|
||||
"""处理贴标信号变化"""
|
||||
logging.info(f"[处理] 贴标状态: {status}")
|
||||
# 更新UI显示
|
||||
self.label_status_label.setText(f"贴标: {status}")
|
||||
# 在这里可以添加更多业务逻辑
|
||||
pass
|
||||
|
||||
@Slot(bool, str)
|
||||
def handle_modbus_status(self, is_connected, message):
|
||||
"""处理Modbus连接状态变化"""
|
||||
if is_connected:
|
||||
self.modbus_status_label.setText("Modbus: 已连接")
|
||||
self.modbus_status_label.setStyleSheet("color: green;")
|
||||
logging.info(f"Modbus已连接: {message}")
|
||||
else:
|
||||
self.modbus_status_label.setText("Modbus: 未连接")
|
||||
self.modbus_status_label.setToolTip(message)
|
||||
self.modbus_status_label.setStyleSheet("color: red;")
|
||||
logging.warning(f"Modbus连接断开: {message}")
|
||||
|
||||
@Slot(int, str)
|
||||
def handle_register_error(self, address, error_msg):
|
||||
"""处理寄存器读取错误"""
|
||||
logging.warning(f"[处理] 寄存器D{address}错误: {error_msg}")
|
||||
# 在这里可以添加错误处理逻辑
|
||||
pass
|
||||
|
||||
@Slot(int, int)
|
||||
def handle_register_change(self, address, value):
|
||||
"""处理寄存器变化"""
|
||||
logging.info(f"[处理] 寄存器D{address}变化: {value}")
|
||||
# 在这里可以添加通用寄存器变化处理逻辑
|
||||
pass
|
||||
|
||||
@Slot(int, str)
|
||||
def handle_loading_feedback(self, status, desc):
|
||||
"""处理上料信息反馈"""
|
||||
logging.info(f"[处理] 上料信息: {desc}")
|
||||
# 在这里添加业务逻辑
|
||||
pass
|
||||
|
||||
@Slot(int, str)
|
||||
def handle_unloading_feedback(self, status, desc):
|
||||
"""处理下料信息反馈"""
|
||||
logging.info(f"[处理] 下料信息: {desc}")
|
||||
# 在这里添加业务逻辑
|
||||
pass
|
||||
|
||||
def _update_error_status(self):
|
||||
"""更新故障状态显示"""
|
||||
# 收集所有故障信息
|
||||
error_codes = [
|
||||
getattr(self, 'error_1', 0),
|
||||
getattr(self, 'error_2', 0),
|
||||
getattr(self, 'error_3', 0)
|
||||
]
|
||||
|
||||
# 检查是否有故障
|
||||
has_error = any(code > 0 for code in error_codes)
|
||||
|
||||
if has_error:
|
||||
# 收集所有错误信息
|
||||
errors = []
|
||||
error_map = self.machine_handlers.error_map
|
||||
|
||||
if getattr(self, 'error_1', 0) > 0:
|
||||
errors.append(f"故障1: {error_map.get(self.error_1, '未知')}")
|
||||
if getattr(self, 'error_2', 0) > 0:
|
||||
errors.append(f"故障2: {error_map.get(self.error_2, '未知')}")
|
||||
if getattr(self, 'error_3', 0) > 0:
|
||||
errors.append(f"故障3: {error_map.get(self.error_3, '未知')}")
|
||||
|
||||
self.error_status_label.setText("故障: 有")
|
||||
self.error_status_label.setToolTip("\n".join(errors))
|
||||
self.error_status_label.setStyleSheet("color: red; font-weight: bold;")
|
||||
else:
|
||||
self.error_status_label.setText("故障: 无")
|
||||
self.error_status_label.setToolTip("")
|
||||
self.error_status_label.setStyleSheet("color: green; font-weight: bold;")
|
||||
|
||||
@Slot(int, str)
|
||||
def handle_error_1(self, error_code, error_desc):
|
||||
"""处理故障信息1"""
|
||||
logging.info(f"[处理] 故障信息1: {error_desc}")
|
||||
# 保存故障码
|
||||
self.error_1 = error_code
|
||||
self._update_error_status()
|
||||
|
||||
# 如果有故障,显示提示
|
||||
if error_code > 0:
|
||||
QMessageBox.warning(self, "设备故障", f"故障1: {error_desc}")
|
||||
# 在这里添加其他故障处理逻辑
|
||||
pass
|
||||
|
||||
@Slot(int, str)
|
||||
def handle_error_2(self, error_code, error_desc):
|
||||
"""处理故障信息2"""
|
||||
logging.info(f"[处理] 故障信息2: {error_desc}")
|
||||
# 保存故障码
|
||||
self.error_2 = error_code
|
||||
self._update_error_status()
|
||||
|
||||
# 如果有故障,显示提示
|
||||
if error_code > 0:
|
||||
QMessageBox.warning(self, "设备故障", f"故障2: {error_desc}")
|
||||
# 在这里添加其他故障处理逻辑
|
||||
pass
|
||||
|
||||
@Slot(int, str)
|
||||
def handle_error_3(self, error_code, error_desc):
|
||||
"""处理故障信息3"""
|
||||
logging.info(f"[处理] 故障信息3: {error_desc}")
|
||||
# 保存故障码
|
||||
self.error_3 = error_code
|
||||
self._update_error_status()
|
||||
|
||||
# 如果有故障,显示提示
|
||||
if error_code > 0:
|
||||
QMessageBox.warning(self, "设备故障", f"故障3: {error_desc}")
|
||||
# 在这里添加其他故障处理逻辑
|
||||
pass
|
||||
Loading…
Reference in New Issue
Block a user