☰
一个优秀的工业级上位机,不只是“功能能运行”,还必须满足
2026/10/23 2:48:23 网站建设 项目流程

一个优秀的工业级上位机,不只是“功能能运行”,还必须满足:

  • 通讯稳定;
  • 流程状态明确;
  • 断线可恢复;
  • 停止、复位、结批不会卡死;
  • 多工站互不影响;
  • 故障可追溯;
  • 数据不丢失;
  • 现场人员可诊断;
  • 代码可以测试和扩展。

结合当前项目,结论是:

当前架构已经具备工业上位机的基础,但还属于“功能型业务架构”,尚未完全达到高可靠工业级架构标准。最大问题不是项目分层,而是状态管理、生命周期、异常处理和通讯恢复机制还不够统一。


一、当前架构梳理

当前解决方案大致如下:

MaxWell WPF界面 ViewModel 窗体、按钮、弹窗、显示状态 MaxWell.Driver.M 工站业务 自动测试流程 上料、搬运、预测试、正式测试、吹扫、下料 PLCController 工站流水线 MaxWell.Device AuxPLC MainBoard Scanner RFID LoadUnit 设备协议和报文解析 MaxWell.Communication TCP连接 Socket 通讯队列 底层连接管理 MaxWell.Automation 自动化 TCP/JSON 协议 AutomationBusinessHandler MaxWell.SecsGem SECS/GEM 通讯 MaxWell.Models 配方、状态、结果、配置、公共数据模型

这个分层方向是正确的,尤其是:

  • AuxPLC已经放到MaxWell.Device;
  • PLCController负责 PLC 业务信号映射;
  • AutomaticStationPipeline使用 Channel 管理多阶段业务;
  • 自动化和 EAP 已经逐渐分开;
  • 配方校验、PackageType 光电位置、日志分类已经开始公共化。

二、目前最需要优化的部分

1. 工站状态分散,容易产生状态冲突

当前状态分散在多个位置:

  • StationControlViewModel
  • AutomaticRealtimeAcquisitionService
  • AutomaticStationPipeline
  • EnvironmentData
  • UniverseData
  • PLCController
  • 自动化和 EAP Handler

同时存在很多布尔字段,例如:

_stopRequested _isResetting _isBatchClosing _allowLoading _allowUnloading _automationControlsSot _waitingForNextAllowLoadingCycle _automaticLoadReleased

这些字段可以组合出大量非法状态,例如:

正在复位 + 允许上料 正在结批 + 自动化仍可投料 停止中 + 流水线仍可接收新请求

这也是“复位后不再触发”“结批后重新开批卡住”“收到 SOTReq 但不搬运”等问题的根本来源之一。

优化方向

每个工站应该只有一个统一的运行状态对象:

设备状态: Offline Connecting Initializing Idle Running Stopping Resetting ClosingBatch Faulted 工艺阶段: WaitingLoad Loading Transfer Testing Purging WaitingUnload Completed Failed 控制来源: Manual Automation Eap

业务只通过状态转换改变状态,不再由多个布尔值自由组合。


2. PLC 轮询、事件和业务流程没有统一

当前PLCController有SignalChanged,但业务主要仍使用while + Task.Delay等待。

这会造成:

  • 每个流程都有自己的等待代码;
  • 超时逻辑重复;
  • 取消逻辑重复;
  • 日志格式不统一;
  • 多个流程可能同时等待同一个信号;
  • 条件判断容易漏掉当前已经成立的信号。

另外,当前单个信号变化事件不适合复杂组合条件。U、V、W 等信号可能在同一次轮询中分批更新,业务可能读到不完整状态。

优化方向

建立每站唯一的:

PlcPollingService -> 读取一批 PLC 信号 -> 生成完整 PlcSnapshot -> 标记采集时间、序列号、通讯质量 -> 发布 SnapshotChanged

业务统一使用:

WaitForStateAsync WaitForRisingEdgeAsync WaitForFallingEdgeAsync WaitForConditionsAsync

注意:这不是取消 PLC 轮询,而是让业务由“快照变化”唤醒。


3. 通讯层错误处理过于宽松

AuxPLC中有多处捕获异常后直接返回null或错误码。

这种做法虽然可以避免程序崩溃,但会隐藏真正故障:

PLC断线 读取超时 响应格式错误 地址配置错误 设备拒绝请求

最后业务只能看到:

条件不满足 无响应 执行失败

还可能继续使用旧缓存值,产生危险误判。

优化方向

每次通讯结果必须明确区分:

Success Timeout Disconnected ProtocolError InvalidAddress DeviceRejected Cancelled

PLC 快照需要包含:

Sequence ReadTime IsValid LastSuccessfulReadTime ConsecutiveFailureCount ErrorMessage

读取失败后,安全信号应变为“未知/无效”,不能继续使用旧值执行上料、搬运和测试。


4. 设备通讯虽然有队列,但缺少统一的设备命令调度策略

当前AuxPLC有EnqueueExecute,主控板也有自己的执行器或命令队列。方向是正确的,但工业级设备通常还需要:

  • 每个设备只有一个命令出口;
  • 读写命令不能相互交叉;
  • 停止、复位、急停类命令具有更高优先级;
  • 普通实时查询不能阻塞安全命令;
  • 每个命令必须有超时和唯一请求编号;
  • 重试必须区分幂等命令和非幂等命令。

优化方向

每个物理设备建立独立的DeviceCommandScheduler:

高优先级: 停止 复位 关闭测试使能 关闭高压 普通优先级: 测试命令 配方下发 状态读取 实时查询

同一个物理设备不能由多个业务类直接调用底层发送方法。


5. 任务生命周期不完整

当前部分Stop()方法只调用取消,没有等待后台任务真正退出。例如:

  • PLC 轮询任务;
  • 自动实时采集任务;
  • 自动流水线 Worker;
  • 等待信号任务。

这样会出现:

旧任务尚未退出 新任务已经启动 旧任务继续写日志、更新状态或执行 PLC 命令

这会直接导致:

  • 重复上料;
  • 复位后旧流程重新触发;
  • 同一个 PLC 出现多个轮询任务;
  • 结批后_automaticPipeline仍然有活动记录。

优化方向

所有后台服务统一实现:

StartAsync StopAsync DisposeAsync

停止流程必须是:

禁止接收新任务 取消等待 等待 Worker 完成 清理活动产品 解除事件订阅 释放资源

不能只调用Cancel()就认为流程已经停止。


6.AutomaticStationPipeline的方向正确,但需要强化清理

当前 Channel 多 Worker 适合工业流程,但需要重点确认:

  • 失败时是否一定从活动产品表删除;
  • 取消时是否一定执行清理;
  • 队列中的产品是否能被取消;
  • 停止时是否等待所有 Worker;
  • 下料等待时是否阻塞其他产品;
  • 结批后是否允许旧请求重新进入。

建议建立统一的产品生命周期:

Created Loading Loaded Transferring Testing Purging WaitingUnload Completed Failed Cancelled Cleaned

无论成功、失败还是取消,最终都必须进入Cleaned。

Finish()不能只在正常路径调用,异常和取消也必须经过统一收尾。


7. ViewModel 业务职责过重

StationControlViewModel目前同时承担:

  • 按钮状态;
  • PLC 判断;
  • 自动模式;
  • EAP;
  • 自动化;
  • 复位;
  • 停止;
  • 结批;
  • 测试;
  • 取料;
  • 弹窗;
  • 日志;
  • 状态显示。

即使拆成多个.partial.cs文件,本质仍然是一个巨大类。

优化方向

建议逐步拆成:

StationLifecycleService 初始化、复位、停止、结批 StationMaterialService 上料、搬运、清料、取料 StationTestService 预测试、正式测试、结果保存 StationRuntime 当前工站唯一状态 StationAutomationService 自动化协议 StationEapService SECS/GEM协议 StationUiAdapter WPF属性、灯态、弹窗

ViewModel 只做:

接收按钮命令 调用业务服务 订阅状态变化 更新界面

8. 全局静态状态较多,影响多工站隔离和测试

当前存在类似:

  • EnvironmentData
  • UniverseData
  • DeviceManager.Instance
  • LogHelper
  • 静态缓存和静态服务

全局对象使用方便,但工业设备中容易出现:

  • A 站状态污染 B 站;
  • 上一批数据残留到下一批;
  • 单元测试无法构造独立环境;
  • 关闭工站后对象仍被引用;
  • 多线程访问没有明确边界。

优化方向

尽量采用:

IStationRuntimeContext IClock IDeviceManager ILogger IRecipeProvider IDataFileService

每个工站创建独立上下文,公共服务只负责无状态能力。

全局数据可以保留用于 UI 汇总,但不能作为核心业务状态的唯一来源。


9. 日志已经分类,但还缺少统一事件模型

当前已经区分:

PrintElectricalErrorLog PrintAuxControlErrorLog PrintAutomationErrorLog

这是正确方向,但还需要统一日志字段:

时间 工站 批次 器件 设备 流程阶段 命令名称 发送/接收 请求编号 错误码 耗时 重试次数 异常类型

日志不能只保存一段中文字符串,否则很难检索和统计。

建议采用:

结构化日志 + 现场可读日志

原始报文单独保存,业务日志保存解析后的信息。


10. 数据保存应采用“先写缓存,再正式归档”的可靠模型

当前已经有缓存文件、正式文件和备份文件的概念,这是工业数据保存的正确方向。

还需要进一步保证:

  • 每条实时采集数据写入成功后才能确认;
  • 文件写入不能阻塞测试线程;
  • 写入失败必须进入重试队列;
  • 进程崩溃后可以恢复未完成文件;
  • 结批复制必须支持断点和校验;
  • 目标目录不存在时自动创建;
  • 数据文件需要校验记录数和文件大小;
  • 备份失败不能静默忽略。

推荐:

测试线程 -> 有界 Channel CSV后台写入线程 -> 缓存文件 测试完成 -> 单器件文件归档 结批 -> 汇总文件归档

三、工业级目标架构

建议目标架构如下:

┌─────────────────────────────┐ │ WPF UI │ │ 页面、按钮、属性、弹窗 │ └──────────────┬──────────────┘ │ ┌──────────────▼──────────────┐ │ Application Layer │ │ 工站服务、批次服务、流程服务 │ └──────────────┬──────────────┘ │ ┌──────────────▼──────────────┐ │ Station Runtime │ │ 状态机、快照、流水线、取消机制 │ └──────────────┬──────────────┘ │ ┌──────────────▼──────────────┐ │ Device Abstraction │ │ PLC、主控板、负载、扫描器、RFID │ └──────────────┬──────────────┘ │ ┌──────────────▼──────────────┐ │ Communication Layer │ │ TCP、Modbus、SECS/GEM、重连 │ └─────────────────────────────┘

自动化和 EAP 应该是协议适配器:

AutomationAdapter EapSecsGemAdapter │ ▼ StationApplicationService │ ▼ StationRuntime

两种协议可以不同,但不能各自复制一套上料、测试、下料逻辑。


四、目前距离工业级标准的评价

模块当前情况评价
项目分层已有基础分层基本合理
设备驱动隔离AuxPLC、主控板已独立较合理
多工站并行有独立流水线需要强化生命周期
PLC状态判断缓存和轮询已有需要统一快照事件
通讯串行化部分设备已有队列需要统一调度和优先级
断线恢复有部分重试不够统一
状态机主要依赖多个布尔值需要重点重构
取消机制有多个取消源生命周期不够清晰
异常处理部分异常被吞掉需要结构化错误
日志已分类需要结构化和关联请求
数据存储有缓存和归档需要可靠写入和恢复
UI与业务解耦ViewModel仍较重需要拆分
自动化/EAP扩展已分开需要统一业务入口
自动化测试需要增加当前不足

五、推荐优化顺序

严格按照下面顺序,每完成一步后上机验证,再进入下一步:

1. 建立基线和通讯日志 2. 修复设备连接、轮询和任务停止生命周期 3. 增加PLC完整快照和通讯质量 4. 统一PlcCondition等待器 5. 先替换一个低风险等待点 6. 逐个替换上料、搬运、测试、吹扫、取料等待 7. 优化自动流水线取消和产品清理 8. 集中工站状态,减少布尔字段 9. 拆分StationControlViewModel 10. 完善自动化和EAP协议适配器 11. 完善数据恢复、权限、审计和自动化测试

六、最终判断

当前项目不需要改成微服务,也不建议拆成多个独立进程。工业设备上位机更适合:

单进程、模块化、每个工站独立运行时、每个设备单独通讯队列、流程使用状态机和 Channel。

当前最应该优先解决的是:

  1. 工站状态统一;
  2. PLC 快照和通讯有效性;
  3. 任务停止和取消;
  4. 设备命令串行化;
  5. 流程失败后的统一清理;
  6. ViewModel 与业务解耦。

完成这些后,当前项目才会从“可以运行”逐步提升为“稳定运行、可恢复、可维护、可扩展”的工业级上位机架构。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询