公司动态
一个优秀的工业级上位机,不只是“功能能运行”,还必须满足
一个优秀的工业级上位机不只是“功能能运行”还必须满足通讯稳定流程状态明确断线可恢复停止、复位、结批不会卡死多工站互不影响故障可追溯数据不丢失现场人员可诊断代码可以测试和扩展。结合当前项目结论是当前架构已经具备工业上位机的基础但还属于“功能型业务架构”尚未完全达到高可靠工业级架构标准。最大问题不是项目分层而是状态管理、生命周期、异常处理和通讯恢复机制还不够统一。一、当前架构梳理当前解决方案大致如下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.DevicePLCController负责 PLC 业务信号映射AutomaticStationPipeline使用 Channel 管理多阶段业务自动化和 EAP 已经逐渐分开配方校验、PackageType 光电位置、日志分类已经开始公共化。二、目前最需要优化的部分1. 工站状态分散容易产生状态冲突当前状态分散在多个位置StationControlViewModelAutomaticRealtimeAcquisitionServiceAutomaticStationPipelineEnvironmentDataUniverseDataPLCController自动化和 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 CancelledPLC 快照需要包含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. 全局静态状态较多影响多工站隔离和测试当前存在类似EnvironmentDataUniverseDataDeviceManager.InstanceLogHelper静态缓存和静态服务全局对象使用方便但工业设备中容易出现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。当前最应该优先解决的是工站状态统一PLC 快照和通讯有效性任务停止和取消设备命令串行化流程失败后的统一清理ViewModel 与业务解耦。完成这些后当前项目才会从“可以运行”逐步提升为“稳定运行、可恢复、可维护、可扩展”的工业级上位机架构。