This commit is contained in:
2025-11-01 17:33:26 +08:00
parent bd0815d0e7
commit 32c14c2e7b
15 changed files with 543 additions and 102 deletions

View File

@ -15,6 +15,14 @@ class ArtifactBll:
"""获取官片任务数据""" """获取官片任务数据"""
return self.dal.get_top_artifact(5,"ArtifactID asc") return self.dal.get_top_artifact(5,"ArtifactID asc")
def get_artifacting_task(self) -> ArtifactInfoModel:
"""获取正在进行的官片任务数据"""
loc_item= self.dal.get_top_artifact(1,"","Status=2")
if loc_item:
return loc_item[0]
else:
return None
class PDRecordBll: class PDRecordBll:
def __init__(self): def __init__(self):
"""初始化数据访问层,创建数据库连接""" """初始化数据访问层,创建数据库连接"""
@ -31,8 +39,10 @@ if __name__ == "__main__":
artifact_dal = ArtifactBll() artifact_dal = ArtifactBll()
artifacts = artifact_dal.get_artifact_task() artifacts = artifact_dal.get_artifact_task()
print("\n打印artifacts数据:") print("\n打印artifacts数据:")
for i, artifact in enumerate(artifacts): for i, artifact in enumerate(artifacts):
artifact_id = artifact.ArtifactID
# 如果是数据类对象,转换为字典输出 # 如果是数据类对象,转换为字典输出
if hasattr(artifact, '__dataclass_fields__'): if hasattr(artifact, '__dataclass_fields__'):
print(f"{i+1}条: {artifact.__dict__}") print(f"{i+1}条: {artifact.__dict__}")

View File

@ -69,6 +69,7 @@ class ArtifactDal(BaseDal):
artifact.BetonVolume=row["BetonVolume"] artifact.BetonVolume=row["BetonVolume"]
artifact.BetonTaskID=row["BetonTaskID"] artifact.BetonTaskID=row["BetonTaskID"]
artifact.Status=row["Status"] artifact.Status=row["Status"]
artifact.BeginTime=row["BeginTime"]
artifacts.append(artifact) artifacts.append(artifact)
return artifacts return artifacts
@ -92,6 +93,7 @@ class ArtifactDal(BaseDal):
print(f"根据ID获取构件任务失败: {e}") print(f"根据ID获取构件任务失败: {e}")
return None return None
def insert_artifact(self, artifact_data: dict) -> Optional[int]: def insert_artifact(self, artifact_data: dict) -> Optional[int]:
"""插入一条构件任务记录""" """插入一条构件任务记录"""
try: try:

View File

@ -1,7 +1,6 @@
# config/settings.py # config/settings.py
import os import os
class Settings: class Settings:
def __init__(self): def __init__(self):
# 项目根目录 # 项目根目录
@ -49,7 +48,13 @@ class Settings:
self.visual_check_interval = 1.0 # 视觉检查间隔(秒) self.visual_check_interval = 1.0 # 视觉检查间隔(秒)
self.alignment_check_interval = 0.5 # 对齐检查间隔(秒) self.alignment_check_interval = 0.5 # 对齐检查间隔(秒)
self.max_error_count = 3 # 最大错误计数 self.max_error_count = 3 # 最大错误计数
self.lower_feeding_interval = 1.0 # 下料轮询间隔(秒)
# RFID配置
self.rfid_host = '192.168.1.190'
self.rfid_port = 6000
#是否在线生产 #是否在线生产
self.is_online_control = True # 是否API在线 self.is_online_control = True # 是否API在线

View File

@ -1,10 +1,19 @@
from view.main_window import MainWindow from view.main_window import MainWindow
from config.settings import Settings
from core.system import FeedingControlSystem
class MainController: class MainController:
def __init__(self): def __init__(self):
# 加载配置
settings = Settings()
# 主界面 # 主界面
self.main_window = MainWindow() self.main_window = MainWindow()
# 初始化系统
system = FeedingControlSystem(settings)
# 系统初始化
system.initialize()
# 初始化子界面 # 初始化子界面
self._initSubViews() self._initSubViews()

View File

@ -1,12 +1,18 @@
# core/state.py from PySide6.QtCore import Signal, QObject
class SystemState: import threading
from enum import IntEnum
class SystemState(QObject):
"""状态中以_开头的属性会发送信号通知,不需要的不要加_开头"""
state_updated=Signal(str,object)
def __init__(self): def __init__(self):
super().__init__()
# 系统运行状态 # 系统运行状态
self.running = False self.running = False
# 下料控制相关 # 下料控制相关
self.upper_door_position = 'default' # default(在搅拌楼下接料), over_lower(在下料斗上方), returning(返回中) self._upper_door_position = 'default' # default(在搅拌楼下接料), over_lower(在下料斗上方), returning(返回中)
self.lower_feeding_stage = 0 # 0:未下料, 1:第一阶段, 2:第二阶段, 3:第三阶段, 4:等待模具车对齐 self._lower_feeding_stage = 0 # 0:未下料, 1:第一阶段, 2:第二阶段, 3:第三阶段, 4:等待模具车对齐
self.lower_feeding_cycle = 0 # 下料斗下料循环次数 self.lower_feeding_cycle = 0 # 下料斗下料循环次数
self.upper_feeding_count = 0 # 上料斗已下料次数 self.upper_feeding_count = 0 # 上料斗已下料次数
self.upper_feeding_max = 2 #上料斗最大下料次数 self.upper_feeding_max = 2 #上料斗最大下料次数
@ -26,3 +32,46 @@ class SystemState:
self.door_opening_large = False # 夹角 self.door_opening_large = False # 夹角
self.vehicle_aligned = False # 模具车是否对齐 self.vehicle_aligned = False # 模具车是否对齐
self.last_angle = None # 上次检测角度 self.last_angle = None # 上次检测角度
#当前RFID的内容格式为 模块编号,分块号,尺寸规格,方量
self.rfid_current=None
#当前生产的管片
self.current_artifact=None
#当前生产状态
self.feed_status=FeedStatus.FNone
# 记录需要监听的属性名(筛选掉不需要发信号的内部变量)
#是否破拱
self._upper_is_arch_=False
self._lower_is_arch_=False
self.lock = threading.RLock()
self._watched_props = [k for k in self.__dict__ if k.startswith('_')]
def __setattr__(self, name, value):
super().__setattr__(name, value)
if name in self._watched_props:
with self.lock:
public_name = name.lstrip('_')
self.state_updated.emit(public_name, value)
class FeedStatus(IntEnum):
#初始值
FNone = 0
# 检查模车(模车到位)
FCheckM = 1
#RFID检测或匹配
FRFID=2,
# 开始(管片待生产任务)
FStart = 3
# 检查盖板(盖板到位)
FCheckGB = 4
#下料1
FFeed1 = 5
# 下料2
FFeed2 = 6
# 下料3
FFeed3 = 7
#完成(管片生产完成)
FFinished = 11

View File

@ -7,6 +7,7 @@ from core.state import SystemState
from hardware.relay import RelayController from hardware.relay import RelayController
from hardware.inverter import InverterController from hardware.inverter import InverterController
from hardware.transmitter import TransmitterController from hardware.transmitter import TransmitterController
from hardware.RFID.rfid_service import rfid_service
from vision.camera import CameraController from vision.camera import CameraController
from vision.detector import VisionDetector from vision.detector import VisionDetector
from feeding.controller import FeedingController from feeding.controller import FeedingController
@ -37,14 +38,22 @@ class FeedingControlSystem:
self.transmitter_controller, self.transmitter_controller,
self.vision_detector, self.vision_detector,
self.camera_controller, self.camera_controller,
self.rfid_controller,
self.state, self.state,
settings settings
) )
# 初始化RFID控制器
self.rfid_controller = rfid_service(
host=settings.rfid_host,
port=settings.rfid_port
)
# 线程管理 # 线程管理
self.monitor_thread = None self.monitor_thread = None
self.visual_control_thread = None self.visual_control_thread = None
self.alignment_check_thread = None self.alignment_check_thread = None
self.lower_feeding_thread = None
def initialize(self): def initialize(self):
"""初始化系统""" """初始化系统"""
@ -68,6 +77,9 @@ class FeedingControlSystem:
if not self.vision_detector.load_models(): if not self.vision_detector.load_models():
raise Exception("视觉模型加载失败") raise Exception("视觉模型加载失败")
if not self.check_device_connectivity():
raise Exception("设备连接失败")
# 启动系统监控 # 启动系统监控
self.start_monitoring() self.start_monitoring()
@ -77,6 +89,10 @@ class FeedingControlSystem:
# 启动对齐检查 # 启动对齐检查
self.start_alignment_check() self.start_alignment_check()
# 启动下料轮询线程
self.start_lower_feeding()
print("控制系统初始化完成") print("控制系统初始化完成")
def start_monitoring(self): def start_monitoring(self):
@ -131,7 +147,7 @@ class FeedingControlSystem:
"""对齐检查循环""" """对齐检查循环"""
while self.state.running: while self.state.running:
try: try:
if self.state.lower_feeding_stage == 4: # 等待对齐阶段 if self.state._lower_feeding_stage == 4: # 等待对齐阶段
current_frame = self.camera_controller.capture_frame() current_frame = self.camera_controller.capture_frame()
if current_frame is not None: if current_frame is not None:
self.state.vehicle_aligned = self.vision_detector.detect_vehicle_alignment(current_frame) self.state.vehicle_aligned = self.vision_detector.detect_vehicle_alignment(current_frame)
@ -146,7 +162,54 @@ class FeedingControlSystem:
def start_lower_feeding(self): def start_lower_feeding(self):
"""启动下料流程""" """启动下料流程"""
self.lower_feeding_thread = threading.Thread(
target=self._start_lower_feeding,
daemon=True
)
self.lower_feeding_thread.start()
def _start_lower_feeding(self):
"""启动下料流程"""
while self.state.running:
self.feeding_controller.start_feeding() self.feeding_controller.start_feeding()
time.sleep(self.settings.lower_feeding_interval)
def check_device_connectivity(self) -> bool:
"""检查关键设备连接状态"""
try:
# 检查网络继电器连接
test_response = self.relay_controller.send_command(self.relay_controller.read_status_command)
if not test_response:
print("网络继电器连接失败")
return False
# 检查变频器连接
if not self.relay_controller.modbus_client.connect():
print("无法连接到网络继电器Modbus服务")
return False
# 尝试读取变频器一个寄存器(测试连接)
test_result = self.relay_controller.modbus_client.read_holding_registers(
address=0x00,
count=1,
slave=self.inverter_controller.config['slave_id']
)
if isinstance(test_result, Exception):
print("变频器连接测试失败")
return False
# 检查下料斗变送器连接
test_weight = self.transmitter_controller.read_data(2)
if test_weight is None:
print("下料斗变送器连接失败")
return False
self.relay_controller.modbus_client.close()
return True
except Exception as e:
print(f"设备连接检查失败: {e}")
return False
def stop(self): def stop(self):
"""停止系统""" """停止系统"""
@ -160,6 +223,8 @@ class FeedingControlSystem:
self.visual_control_thread.join() self.visual_control_thread.join()
if self.alignment_check_thread: if self.alignment_check_thread:
self.alignment_check_thread.join() self.alignment_check_thread.join()
if self.lower_feeding_thread:
self.lower_feeding_thread.join()
# 释放摄像头资源 # 释放摄像头资源
self.camera_controller.release() self.camera_controller.release()

Binary file not shown.

Binary file not shown.

Binary file not shown.

260
doc/md/Arch.md Normal file
View File

@ -0,0 +1,260 @@
## 子系统关系图示例
### 1. 系统上下文图System Context Diagram
```mermaid
graph TD
subgraph 外部实体
User[用户]
CustomerSystem[客户系统]
SupplierSystem[供应商系统]
PaymentGateway[支付网关]
end
subgraph 核心系统
MainSystem[主系统]
subgraph 子系统A[子系统A - 订单管理]
OrderService[订单服务]
InventoryService[库存服务]
PricingService[定价服务]
end
subgraph 子系统B[子系统B - 用户管理]
AuthService[认证服务]
ProfileService[用户档案服务]
PermissionService[权限服务]
end
subgraph 子系统C[子系统C - 数据分析]
ReportService[报表服务]
AnalyticsService[分析服务]
DashboardService[仪表盘服务]
end
subgraph 子系统D[子系统D - 通知中心]
EmailService[邮件服务]
SMSGateway[短信网关]
PushService[推送服务]
end
end
subgraph 数据存储
DB[(数据库)]
Cache[(缓存)]
LogStorage[(日志存储)]
end
%% 外部实体连接
User --> MainSystem
CustomerSystem <--> MainSystem
SupplierSystem <--> MainSystem
PaymentGateway <--> MainSystem
%% 主系统与子系统连接
MainSystem --> OrderService
MainSystem --> AuthService
MainSystem --> ReportService
MainSystem --> EmailService
%% 子系统内部连接
OrderService --> InventoryService
OrderService --> PricingService
AuthService --> ProfileService
AuthService --> PermissionService
ReportService --> AnalyticsService
ReportService --> DashboardService
EmailService --> SMSGateway
EmailService --> PushService
%% 子系统与数据存储连接
OrderService --> DB
InventoryService --> DB
ProfileService --> DB
PermissionService --> DB
AnalyticsService --> DB
PricingService --> Cache
AuthService --> Cache
EmailService --> LogStorage
SMSGateway --> LogStorage
PushService --> LogStorage
```
### 2. 子系统交互流程图
```mermaid
sequenceDiagram
participant Client as 客户端
participant Main as 主系统
participant Order as 订单子系统
participant User as 用户子系统
participant Payment as 支付子系统
participant Notify as 通知子系统
participant DB as 数据库
Client->>Main: 请求创建订单
Main->>User: 验证用户身份和权限
User->>DB: 查询用户信息
DB-->>User: 返回用户数据
User-->>Main: 验证通过
Main->>Order: 创建订单请求
Order->>DB: 查询库存
DB-->>Order: 返回库存状态
alt 库存充足
Order->>DB: 锁定库存
Order->>Payment: 发起支付请求
Payment->>DB: 创建支付记录
DB-->>Payment: 支付记录创建成功
Payment-->>Order: 支付已发起
Order->>DB: 更新订单状态为"等待支付"
Order-->>Main: 订单创建成功
Main->>Notify: 发送订单确认通知
Notify-->>Client: 推送订单确认消息
else 库存不足
Order-->>Main: 库存不足
Main-->>Client: 返回错误信息
end
```
### 3. 子系统依赖关系图
```mermaid
graph LR
subgraph 基础服务层
ConfigSvc[配置服务]
LogSvc[日志服务]
SecuritySvc[安全服务]
CommonLib[公共库]
end
subgraph 核心业务层
UserMgmt[用户管理子系统]
ProductMgmt[产品管理子系统]
OrderMgmt[订单管理子系统]
PaymentMgmt[支付管理子系统]
end
subgraph 应用服务层
API_Gateway[API网关]
MobileApp[移动应用服务]
WebPortal[Web门户服务]
ReportSvc[报表服务]
end
subgraph 集成层
ExternalAPI[外部API集成]
MessageQueue[消息队列]
EventBus[事件总线]
end
%% 依赖关系
UserMgmt --> ConfigSvc
UserMgmt --> LogSvc
UserMgmt --> SecuritySvc
UserMgmt --> CommonLib
ProductMgmt --> ConfigSvc
ProductMgmt --> LogSvc
ProductMgmt --> CommonLib
OrderMgmt --> UserMgmt
OrderMgmt --> ProductMgmt
OrderMgmt --> LogSvc
OrderMgmt --> ConfigSvc
OrderMgmt --> CommonLib
PaymentMgmt --> OrderMgmt
PaymentMgmt --> LogSvc
PaymentMgmt --> SecuritySvc
PaymentMgmt --> ConfigSvc
API_Gateway --> UserMgmt
API_Gateway --> ProductMgmt
API_Gateway --> OrderMgmt
API_Gateway --> PaymentMgmt
API_Gateway --> SecuritySvc
MobileApp --> API_Gateway
WebPortal --> API_Gateway
ReportSvc --> UserMgmt
ReportSvc --> OrderMgmt
ReportSvc --> ProductMgmt
UserMgmt --> ExternalAPI
PaymentMgmt --> ExternalAPI
OrderMgmt --> MessageQueue
PaymentMgmt --> MessageQueue
UserMgmt --> EventBus
OrderMgmt --> EventBus
ProductMgmt --> EventBus
PaymentMgmt --> EventBus
```
### 4. C4模型系统上下文图
```mermaid
graph TD
subgraph 系统边界
System[企业资源规划系统]
subgraph 功能模块
HR[人力资源管理]
Finance[财务管理]
Inventory[库存管理]
Sales[销售管理]
Production[生产管理]
end
System --> HR
System --> Finance
System --> Inventory
System --> Sales
System --> Production
end
%% 系统间关系
HR <--> Finance: 薪资数据
Sales <--> Finance: 订单数据
Sales <--> Inventory: 库存查询
Production <--> Inventory: 物料需求
Production <--> Finance: 成本核算
%% 外部系统
ExtCRM[外部CRM系统] <--> Sales: 客户数据
ExtSupplier[供应商系统] <--> Inventory: 采购数据
ExtBank[银行系统] <--> Finance: 支付结算
%% 用户
HR_User[HR人员] --> HR
Finance_User[财务人员] --> Finance
Inventory_User[仓库人员] --> Inventory
Sales_User[销售人员] --> Sales
Prod_User[生产人员] --> Production
```
### 说明
以上子系统关系图展示了不同类型的系统间关系表示方法:
1. **系统上下文图**:展示了系统的整体架构,包括核心子系统、外部实体和数据存储之间的关系。适合高层次架构设计。
2. **子系统交互流程图**:使用时序图展示子系统之间的交互过程和消息传递顺序,适合描述业务流程中的系统协作。
3. **子系统依赖关系图**:展示了子系统之间的依赖关系,包括基础服务、核心业务、应用服务和集成层的层次结构。
4. **C4模型系统上下文图**遵循C4模型方法论展示了企业级系统中的子系统边界和它们之间的关系。
### Mermaid图表类型选择建议
对于展示子系统之间的关系推荐使用以下Mermaid图表类型
- **graph TD/LR**:适用于系统上下文图、依赖关系图等静态关系展示
- **sequenceDiagram**:适用于展示子系统间的交互流程和消息传递
- **flowchart**:适用于展示更复杂的业务流程和子系统协作
- **classDiagram**:如果需要展示子系统的类结构和它们之间的关系
选择图表类型时,应根据具体需求考虑:是需要展示静态结构关系,还是动态交互过程;是需要高层次概览,还是详细的交互细节。

View File

@ -1,19 +1,22 @@
# feeding/controller.py # feeding/controller.py
import time import time
from feeding.process import FeedingProcess from feeding.process import FeedingProcess
from busisness.blls import ArtifactBll
class FeedingController: class FeedingController:
def __init__(self, relay_controller, inverter_controller, def __init__(self, relay_controller, inverter_controller,
transmitter_controller, vision_detector, transmitter_controller, vision_detector,
camera_controller, state, settings): camera_controller, rfid_controller,state, settings):
self.relay_controller = relay_controller self.relay_controller = relay_controller
self.inverter_controller = inverter_controller self.inverter_controller = inverter_controller
self.transmitter_controller = transmitter_controller self.transmitter_controller = transmitter_controller
self.vision_detector = vision_detector self.vision_detector = vision_detector
self.camera_controller = camera_controller self.camera_controller = camera_controller
self.rfid_controller = rfid_controller
self.state = state self.state = state
self.settings = settings self.settings = settings
self.artifact_bll = ArtifactBll()
# 初始化下料流程 # 初始化下料流程
self.process = FeedingProcess( self.process = FeedingProcess(
@ -22,21 +25,28 @@ class FeedingController:
camera_controller, state, settings camera_controller, state, settings
) )
def start_feeding(self): def start_feeding(self):
#获取当前的管片任务
#API读取生产任务 --》RFID读取模具配对检测--数据库入库》生产-》同步到数据库
#API读取生产任务--》未读到--》RFID读取模具-数据库入库》生产 --》同步到数据库
#从数据库获取当前的管片任务
"""启动下料流程""" """启动下料流程"""
self.process.start_feeding() self.process.start_feeding()
def check_upper_material_request(self): def check_upper_material_request(self):
"""检查是否需要要料""" """检查是否需要要料"""
current_weight = self.transmitter_controller.read_data(1) current_weight = self.transmitter_controller.read_data(1)
if current_weight is None: if current_weight is None:
self.state.upper_weight_error_count += 1 self.state.upper_weight_error_count += 1
print(f"上料斗重量读取失败,错误计数: {self.state.upper_weight_error_count}") print(f"上料斗重量读取失败,错误计数: {self.state.upper_weight_error_count}")
if self.state.upper_weight_error_count >= self.settings.max_error_count: if self.state.upper_weight_error_count >= self.settings.max_error_count:
print("警告:上料斗传感器连续读取失败,请检查连接") print("警告:上料斗传感器连续读取失败,请检查连接")
return False return False
#需要搅拌楼通知下完料后移到上料斗上方
if self.state._upper_door_position != 'over_lower':
self.state._upper_door_position = 'over_lower'
self.state.upper_weight_error_count = 0 self.state.upper_weight_error_count = 0
# 判断是否需要要料:当前重量 < 目标重量 + 缓冲重量 # 判断是否需要要料:当前重量 < 目标重量 + 缓冲重量
if current_weight < (self.settings.single_batch_weight + self.settings.min_required_weight): if current_weight < (self.settings.single_batch_weight + self.settings.min_required_weight):
@ -50,6 +60,8 @@ class FeedingController:
请求搅拌楼下料 请求搅拌楼下料
""" """
print("发送要料请求至搅拌楼...") print("发送要料请求至搅拌楼...")
# self.settings.
self.process.return_upper_door_to_default() self.process.return_upper_door_to_default()
# 这里需要与同事对接具体的通信方式 # 这里需要与同事对接具体的通信方式
# 可能是Modbus写寄存器、TCP通信、HTTP请求等 # 可能是Modbus写寄存器、TCP通信、HTTP请求等
@ -60,31 +72,35 @@ class FeedingController:
current_time = time.time() current_time = time.time()
# 检查下料斗破拱(只有在下料过程中才检查) # 检查下料斗破拱(只有在下料过程中才检查)
if self.state.lower_feeding_stage in [1, 2, 3]: # 在所有下料阶段检查 if self.state._lower_feeding_stage in [1, 2, 3]: # 在所有下料阶段检查
lower_weight = self.transmitter_controller.read_data(2) lower_weight = self.transmitter_controller.read_data(2)
if lower_weight is not None: if lower_weight is not None:
# 检查重量变化是否过慢小于0.1kg变化且时间超过10秒 # 检查重量变化是否过慢小于0.1kg变化且时间超过10秒
if (abs(lower_weight - self.state.last_lower_weight) < 0.1) and \ if (abs(lower_weight - self.state.last_lower_weight) < 0.1) and \
(current_time - self.state.last_weight_time) > 10: (current_time - self.state.last_weight_time) > 10:
print("下料斗可能堵塞,启动破拱") print("下料斗可能堵塞,启动破拱")
self.state._lower_is_arch_=True
self.relay_controller.control(self.relay_controller.BREAK_ARCH_LOWER, 'open') self.relay_controller.control(self.relay_controller.BREAK_ARCH_LOWER, 'open')
time.sleep(2) time.sleep(2)
self.relay_controller.control(self.relay_controller.BREAK_ARCH_LOWER, 'close') self.relay_controller.control(self.relay_controller.BREAK_ARCH_LOWER, 'close')
self.state._lower_is_arch_=False
self.state.last_lower_weight = lower_weight self.state.last_lower_weight = lower_weight
# 检查上料斗破拱(在上料斗向下料斗下料时检查) # 检查上料斗破拱(在上料斗向下料斗下料时检查)
if (self.state.upper_door_position == 'over_lower' and if (self.state._upper_door_position == 'over_lower' and
self.state.lower_feeding_stage in [0, 1, 2, 3, 4]): # 在任何阶段都可能需要上料斗破拱 self.state._lower_feeding_stage in [0, 1, 2, 3, 4]): # 在任何阶段都可能需要上料斗破拱
upper_weight = self.transmitter_controller.read_data(1) upper_weight = self.transmitter_controller.read_data(1)
if upper_weight is not None: if upper_weight is not None:
# 检查重量变化是否过慢小于0.1kg变化且时间超过10秒 # 检查重量变化是否过慢小于0.1kg变化且时间超过10秒
if (abs(upper_weight - self.state.last_upper_weight) < 0.1) and \ if (abs(upper_weight - self.state.last_upper_weight) < 0.1) and \
(current_time - self.state.last_weight_time) > 10: (current_time - self.state.last_weight_time) > 10:
print("上料斗可能堵塞,启动破拱") print("上料斗可能堵塞,启动破拱")
self.state._upper_is_arch_=True
self.relay_controller.control(self.relay_controller.BREAK_ARCH_UPPER, 'open') self.relay_controller.control(self.relay_controller.BREAK_ARCH_UPPER, 'open')
time.sleep(2) time.sleep(2)
self.relay_controller.control(self.relay_controller.BREAK_ARCH_UPPER, 'close') self.relay_controller.control(self.relay_controller.BREAK_ARCH_UPPER, 'close')
self.state._upper_is_arch_=False
self.state.last_upper_weight = upper_weight self.state.last_upper_weight = upper_weight

View File

@ -1,75 +1,105 @@
from enum import IntEnum
from core.state import FeedStatus
from service.mould_service import MouldService
from busisness.blls import ArtifactBll
from busisness.models import ArtifactInfoModel
class FeedingProcess: class FeedingProcess:
def __init__(self, relay_controller, inverter_controller, def __init__(self, relay_controller, inverter_controller,
transmitter_controller, vision_detector, transmitter_controller, vision_detector,
camera_controller, state, settings): camera_controller, state, settings):
self.relay_controller = relay_controller self.relay_controller = relay_controller
self.artifact_bll = ArtifactBll()
self.inverter_controller = inverter_controller self.inverter_controller = inverter_controller
self.transmitter_controller = transmitter_controller self.transmitter_controller = transmitter_controller
self.vision_detector = vision_detector self.vision_detector = vision_detector
self.camera_controller = camera_controller self.camera_controller = camera_controller
self.state = state self.state = state
self.state.feed_status = FeedStatus.FNone
self.settings = settings self.settings = settings
def start_feeding(self): def start_feeding(self):
"""开始分步下料""" """开始生产管片"""
if self.state.lower_feeding_stage != 0: if self.state.feed_status == FeedStatus.FNone:
print("下料已在进行中") self.state.feed_status = FeedStatus.FCheckM
return
elif self.state.feed_status == FeedStatus.FCheckM:
self.state._lower_feeding_stage = 4
self.wait_for_vehicle_alignment()
self.state.feed_status = FeedStatus.FStart
print("生产已检查模车")
return
elif self.state.feed_status == FeedStatus.FStart:
print("生产已开始")
time.sleep(2)
loc_modules = MouldService.get_not_pour_artifacts()
if loc_modules:
# 取第一个未浇筑的管片
loc_module = loc_modules[0]
self.state.current_artifact = loc_module
else:
#未读取到AIP接口数据.
self.state.current_artifact = None
return
elif self.state.feed_status == FeedStatus.FRFID:
print("生产已检查RFID")
#RFID格式模具编号,分块号,尺寸规格,方量
rfid_info =''
loc_MouldCode='SHZB1-4'
loc_SizeSpecification='6600*1200'
loc_BlockNumber='B1'
loc.BetonVolume=1.56
if self.state.current_artifact:
#检测是否和RFID识别的管理一致
self.state.feed_status = FeedStatus.FCheckGB
else:
#以RFID为准
loc_module= ArtifactInfoModel()
loc_module.MouldCode=loc_MouldCode
loc_module.SizeSpecification=loc_SizeSpecification
loc_module.BlockNumber=loc_BlockNumber
loc_module.BetonVolume=loc.BetonVolume
self.state.current_artifact = loc_module
#确认是否保存到数据库
self.state.feed_status = FeedStatus.FCheckGB
return
elif self.state.feed_status == FeedStatus.FCheckGB:
print("生产已检查盖板")
time.sleep(10)
self.state.feed_status = FeedStatus.FFeed
return
elif self.state.feed_status == FeedStatus.FFeed:
self._start_feeding_stage()
print("生产已下料")
return
elif self.state.feed_status == FeedStatus.FFinished:
print("生产已完成")
self.state.feed_status = FeedStatus.FCheckM
return return
# 检查关键设备是否可连接 def _start_feeding_stage(self):
if not self._check_device_connectivity(): """启动指定下料阶段"""
print("关键设备连接失败,无法开始下料") """开始分步下料"""
if self.state._lower_feeding_stage != 0:
print("下料已在进行中")
return return
print("开始分步下料过程") print("开始分步下料过程")
# 重置计数器 # 重置计数器
#下料斗下料循环次数
self.state.lower_feeding_cycle = 0 self.state.lower_feeding_cycle = 0
#上料斗已下料次数
self.state.upper_feeding_count = 0 self.state.upper_feeding_count = 0
#上料斗最大下料次数
self.state.upper_feeding_max = 2 self.state.upper_feeding_max = 2
# 第一次上料 # 第一次上料
self.transfer_material_from_upper_to_lower() self.transfer_material_from_upper_to_lower()
# 等待模具车对齐并开始第一轮下料 # 等待模具车对齐并开始第一轮下料
self.state.lower_feeding_stage = 4 # self.state._lower_feeding_stage = 4
self.wait_for_vehicle_alignment() # self.wait_for_vehicle_alignment()
def _check_device_connectivity(self):
"""检查关键设备连接状态"""
try:
# 检查网络继电器连接
test_response = self.relay_controller.send_command(self.relay_controller.read_status_command)
if not test_response:
print("网络继电器连接失败")
return False
# 检查变频器连接
if not self.relay_controller.modbus_client.connect():
print("无法连接到网络继电器Modbus服务")
return False
# 尝试读取变频器一个寄存器(测试连接)
test_result = self.relay_controller.modbus_client.read_holding_registers(
address=0x00,
count=1,
slave=self.inverter_controller.config['slave_id']
)
if isinstance(test_result, Exception):
print("变频器连接测试失败")
return False
# 检查下料斗变送器连接
test_weight = self.transmitter_controller.read_data(2)
if test_weight is None:
print("下料斗变送器连接失败")
return False
self.relay_controller.modbus_client.close()
return True
except Exception as e:
print(f"设备连接检查失败: {e}")
return False
def transfer_material_from_upper_to_lower(self): def transfer_material_from_upper_to_lower(self):
"""上料斗向下料斗下料""" """上料斗向下料斗下料"""
@ -81,7 +111,7 @@ class FeedingProcess:
# 如果无法读取重量,直接报错 # 如果无法读取重量,直接报错
if initial_upper_weight is None: if initial_upper_weight is None:
raise Exception("无法读取上料斗重量传感器数据,下料操作终止") raise Exception("无法读取上料斗重量传感器数据,下料操作终止")
# 单次下料重量(kg),self.settings.single_batch_weight
target_upper_weight = initial_upper_weight - self.settings.single_batch_weight target_upper_weight = initial_upper_weight - self.settings.single_batch_weight
target_upper_weight = max(target_upper_weight, 0) # 确保不低于0 target_upper_weight = max(target_upper_weight, 0) # 确保不低于0
@ -136,14 +166,14 @@ class FeedingProcess:
def wait_for_vehicle_alignment(self): def wait_for_vehicle_alignment(self):
"""等待模具车对齐""" """等待模具车对齐"""
print("等待模具车对齐...") print("等待模具车对齐...")
self.state.lower_feeding_stage = 4 self.state._lower_feeding_stage = 4
import time import time
while self.state.lower_feeding_stage == 4 and self.state.running: while self.state._lower_feeding_stage == 4 and self.state.running:
if self.state.vehicle_aligned: if self.state.vehicle_aligned:
print("模具车已对齐,开始下料") print("模具车已对齐,开始下料")
self.state.lower_feeding_stage = 1 self.state._lower_feeding_stage = 1
self.feeding_stage_one() # self.feeding_stage_one()
break break
time.sleep(self.settings.alignment_check_interval) time.sleep(self.settings.alignment_check_interval)
@ -168,7 +198,7 @@ class FeedingProcess:
target_weight = initial_weight + self.settings.single_batch_weight target_weight = initial_weight + self.settings.single_batch_weight
while self.state.lower_feeding_stage == 1: while self.state._lower_feeding_stage == 1:
current_weight = self.transmitter_controller.read_data(2) current_weight = self.transmitter_controller.read_data(2)
if current_weight is None: if current_weight is None:
self.state.lower_weight_error_count += 1 self.state.lower_weight_error_count += 1
@ -180,7 +210,7 @@ class FeedingProcess:
self.state.lower_weight_error_count = 0 self.state.lower_weight_error_count = 0
if (current_weight is not None and current_weight >= target_weight) or (time.time() - start_time) > 30: if (current_weight is not None and current_weight >= target_weight) or (time.time() - start_time) > 30:
self.state.lower_feeding_stage = 2 self.state._lower_feeding_stage = 2
self.feeding_stage_two() self.feeding_stage_two()
break break
time.sleep(2) time.sleep(2)
@ -205,7 +235,7 @@ class FeedingProcess:
target_weight = initial_weight + self.settings.single_batch_weight target_weight = initial_weight + self.settings.single_batch_weight
while self.state.lower_feeding_stage == 2: while self.state._lower_feeding_stage == 2:
current_weight = self.transmitter_controller.read_data(2) current_weight = self.transmitter_controller.read_data(2)
if current_weight is None: if current_weight is None:
self.state.lower_weight_error_count += 1 self.state.lower_weight_error_count += 1
@ -217,7 +247,7 @@ class FeedingProcess:
self.state.lower_weight_error_count = 0 self.state.lower_weight_error_count = 0
if (current_weight is not None and current_weight >= target_weight) or (time.time() - start_time) > 30: if (current_weight is not None and current_weight >= target_weight) or (time.time() - start_time) > 30:
self.state.lower_feeding_stage = 3 self.state._lower_feeding_stage = 3
self.feeding_stage_three() self.feeding_stage_three()
break break
time.sleep(2) time.sleep(2)
@ -242,7 +272,7 @@ class FeedingProcess:
target_weight = initial_weight + self.settings.single_batch_weight target_weight = initial_weight + self.settings.single_batch_weight
while self.state.lower_feeding_stage == 3: while self.state._lower_feeding_stage == 3:
current_weight = self.transmitter_controller.read_data(2) current_weight = self.transmitter_controller.read_data(2)
if current_weight is None: if current_weight is None:
self.state.lower_weight_error_count += 1 self.state.lower_weight_error_count += 1
@ -254,7 +284,7 @@ class FeedingProcess:
self.state.lower_weight_error_count = 0 self.state.lower_weight_error_count = 0
if (current_weight is not None and current_weight >= target_weight) or (time.time() - start_time) > 30: if (current_weight is not None and current_weight >= target_weight) or (time.time() - start_time) > 30:
self.state.lower_feeding_stage = 4 self.state._lower_feeding_stage = 4
self.finish_current_batch() self.finish_current_batch()
break break
time.sleep(2) time.sleep(2)
@ -288,19 +318,19 @@ class FeedingProcess:
# 继续等待当前模具车对齐(不需要重新等待对齐,因为是同一辆模具车) # 继续等待当前模具车对齐(不需要重新等待对齐,因为是同一辆模具车)
print("第二次上料完成,继续三阶段下料") print("第二次上料完成,继续三阶段下料")
self.state.lower_feeding_stage = 1 # 直接进入第一阶段下料 self.state._lower_feeding_stage = 1 # 直接进入第一阶段下料
self.feeding_stage_one() # 开始第二轮第一阶段下料 self.feeding_stage_one() # 开始第二轮第一阶段下料
def finish_feeding_process(self): def finish_feeding_process(self):
"""完成整个下料流程""" """完成整个下料流程"""
print("整个下料流程完成") print("整个下料流程完成")
self.state.lower_feeding_stage = 0 self.state._lower_feeding_stage = 0
self.state.lower_feeding_cycle = 0 self.state.lower_feeding_cycle = 0
self.state.upper_feeding_count = 0 self.state.upper_feeding_count = 0
self.return_upper_door_to_default() # self.return_upper_door_to_default()
def return_upper_door_to_default(self): def return_upper_door_to_default(self):
"""上料斗回到默认位置(搅拌楼下接料位置)""" """上料斗回到默认位置(搅拌楼下接料位置)"""
print("上料斗回到默认位置") print("上料斗回到默认位置")
self.relay_controller.control(self.relay_controller.DOOR_UPPER, 'close') self.relay_controller.control(self.relay_controller.DOOR_UPPER, 'close')
self.state.upper_door_position = 'default' self.state._upper_door_position = 'default'

View File

@ -3,7 +3,7 @@ from typing import Optional, Dict, Any
import time import time
import threading import threading
import requests import requests
from models import LoginResponse from busisness.models import LoginResponse
from config.ini_manager import ini_manager from config.ini_manager import ini_manager

View File

@ -1,14 +1,9 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
""" """
RFID RFID
""" """
import sys import sys
import os import os
import time import time
# 添加项目根目录到Python路径
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from hardware.RFID.rfid_service import rfid_service from hardware.RFID.rfid_service import rfid_service
@ -72,25 +67,25 @@ def test_rfid_functions():
# 测试数据接收功能 (注意:这会启动一个后台线程) # 测试数据接收功能 (注意:这会启动一个后台线程)
# print("\n5. 测试数据接收功能 (启动接收线程5秒后停止):") # print("\n5. 测试数据接收功能 (启动接收线程5秒后停止):")
try: try:
rfid._callback = test_data_callback # rfid._callback = test_data_callback
rfid._data_buffer = [] # rfid._data_buffer = []
rfid._data_buffer.append('SHR2B2-12,B2,6600 * 1500,1.910') # rfid._data_buffer.append('SHR2B2-12,B2,6600 * 1500,1.910')
rfid._data_buffer.append('SHR2B2-12,B2,6600 * 1500,1.910') # rfid._data_buffer.append('SHR2B2-12,B2,6600 * 1500,1.910')
rfid._data_buffer.append('SHR2B2-12,B2,6600 * 1500,1.910') # rfid._data_buffer.append('SHR2B2-12,B2,6600 * 1500,1.910')
rfid._data_buffer.append('SHR2B2-12,B2,6600 * 1500,1.910') # rfid._data_buffer.append('SHR2B2-12,B2,6600 * 1500,1.910')
rfid._data_buffer.append('SHR2B2-12,B2,6600 * 1500,1.910') # rfid._data_buffer.append('SHR2B2-12,B2,6600 * 1500,1.910')
rfid._data_buffer.append('SHR2B2-12,B2,6600 * 1500,1.910') # rfid._data_buffer.append('SHR2B2-12,B2,6600 * 1500,1.910')
rfid._data_buffer.append('THR B1-12,B1,6600 * 1500,1.900') # rfid._data_buffer.append('THR B1-12,B1,6600 * 1500,1.900')
rfid._data_buffer.append('THR B1-12,B1,6600 * 1500,1.900') # rfid._data_buffer.append('THR B1-12,B1,6600 * 1500,1.900')
rfid._data_buffer.append('THR B1-12,B1,6600 * 1500,1.900') # rfid._data_buffer.append('THR B1-12,B1,6600 * 1500,1.900')
rfid._data_buffer.append('THR B1-12,B1,6600 * 1500,1.900') # rfid._data_buffer.append('THR B1-12,B1,6600 * 1500,1.900')
rfid._data_buffer.append('THR B1-12,B1,6600 * 1500,1.900') # rfid._data_buffer.append('THR B1-12,B1,6600 * 1500,1.900')
rfid._data_buffer.append('THR B1-12,B1,6600 * 1500,1.900') # rfid._data_buffer.append('THR B1-12,B1,6600 * 1500,1.900')
rfid._data_buffer.append('THR B1-12,B1,6600 * 1500,1.900') # rfid._data_buffer.append('THR B1-12,B1,6600 * 1500,1.900')
rfid._data_buffer.append('THR B1-12,B1,6600 * 1500,1.900') # rfid._data_buffer.append('THR B1-12,B1,6600 * 1500,1.900')
rfid._data_buffer.append('THR B1-12,B1,6600 * 1500,1.900') # rfid._data_buffer.append('THR B1-12,B1,6600 * 1500,1.900')
rfid._process_collected_data() # rfid._process_collected_data()
# rfid.start_receiver(callback=test_data_callback) rfid.start_receiver(callback=test_data_callback)
# print("接收线程已启动,等待接收数据...") # print("接收线程已启动,等待接收数据...")
# 等待5秒模拟接收过程 # 等待5秒模拟接收过程
time.sleep(60*60) time.sleep(60*60)