
已完成第一阶段基础优化未改动上料、搬运、测试、吹扫等具体工艺动作。主要改动[PLCController.cs]增加完整PlcSignalSnapshot包含采集序列号、时间、信号值、连接状态、数据有效性。批量读取完全部信号后才发布SnapshotChanged避免 U/V/W 等组合条件读取到半更新状态。PLC 断线时发布无效快照等待流程不再错误使用旧缓存判断联锁。新增StopPollingAsync()停止轮询时等待旧任务退出避免重启轮询产生短暂并发读取。[PlcSignalSnapshot.cs]新增 PLC 快照、信号变化和事件参数模型供后续工艺流程统一使用。[PlcCondition.cs]PlcConditionWaiter已由Task.Delay循环检查改为“PLC 完整快照变化时唤醒”。保留原有调用方式、超时、取消、仿真和每 5 秒未满足条件日志。等待前、订阅后均立即检查一次避免信号已到位但漏触发。读取无效或 PLC 断线时日志会明确显示“PLC快照无效”或“PLC未连接”。验证dotnet build MaxWell.sln --no-restore --verbosity:minimal已通过0个错误。项目原有警告仍存在未在本阶段扩散处理。上机先验证单站搬运的下降到位、顶升到位等待。PLC 断线后等待日志显示“PLC未连接”且不触发工艺动作。PLC 恢复连接后新的有效快照能正常继续满足等待条件。自动模式反复启动、停止、复位确认同站没有重复轮询或重复流程。六站并行运行确认 PLC 通讯无新增断连。本阶段通过后下一步建议只替换TransportProduct的测试位下降/顶升等待作为第一个低风险工艺验证点。第二阶段优化已完成。修改文件TransportProduct.cs第一阶段基础文件 PLCController.cs本阶段改动测试位下降到位等待改为统一快照事件等待。测试位顶升到位等待改为统一快照事件等待。删除TransportProduct内部的while Task.Delay判断。不再由搬运 Worker 重复读取 PLC。保留原有PLC 写入顺序WriteLoadingComplete搬运握手电学保护判断自动化 SOT 回调超时处理取消处理辅控错误日志。支持信号已经满足时立即继续避免等待事件订阅后漏掉当前状态。核心逻辑现在是先检查当前 PLC 快照 | |-- 已满足立即执行下一步 | |-- 未满足等待完整快照变化 | |-- 条件满足继续 |-- 超时返回失败 |-- 取消退出流程验证结果dotnet build MaxWell.sln --no-restore --verbosity:minimal 0 个错误本阶段上机验证建议测试位已经下降到位时确认立即执行搬运。测试位未下降时改变 PLC 下降到位信号确认能够被唤醒。搬运启动后改变顶升到位信号确认能够进入预测试。信号长时间不满足确认正常超时。搬运等待过程中点击停止或复位确认等待能够取消。六个工站同时执行搬运确认没有新增 PLC 或 socket 断连。连续执行多颗器件确认没有重复写入上料完成指令。本阶段上机验证通过后下一阶段建议优化PreTest.cs中“等待测试位顶升到位”的重复等待逻辑。第三阶段优化已完成。修改文件PreTest.cs本阶段改动将预测试前“等待测试位顶升到位”的while Task.Delay逻辑删除。改为使用统一的PlcConditionWaiter.WaitAsync。等待过程由 PLC 完整快照变化触发。保留原有超时配置LifterUpWaitTimeoutMs。保留取消机制。保留预测试超时异常等待测试位顶升到位超时预测试未开始。保留测试位已经到位时立即进入预测试的行为。删除不再使用的LifterUpPollIntervalMs。没有修改预测试命令顺序和主控板通讯逻辑。现在流程如下进入预测试 | 检查当前 PLC 快照 | |-- 顶升到位记录日志开始预测试 | |-- 未到位等待 PLC 快照变化 | |-- 顶升到位开始预测试 |-- 超时抛出预测试超时异常 |-- 停止/复位取消等待验证结果dotnet build MaxWell.sln --no-restore --verbosity:minimal 0 个错误第三阶段上机测试测试位已顶升到位确认预测试立即开始。测试位未顶升改变 PLC 顶升到位信号确认流程自动继续。顶升信号长时间不成立确认超时并进入原有故障处理。顶升等待过程中点击停止或复位确认流程可以取消。六个工站同时执行预测试确认没有新增 PLC 或主控板通讯断连。连续测试多颗器件确认不会重复进入预测试。本阶段上机验证通过后下一阶段建议优化UnLoadProduct.cs中的吹扫开始和吹扫完成等待。第四阶段优化已完成。修改文件UnLoadProduct.cs本阶段改动新增WaitForPurgeStartAsync等待开始吹扫标志位true。使用统一PlcConditionWaiter。由 PLC 完整快照变化触发不再由业务循环主动等待。新增WaitForPurgeCompleteAsync等待吹扫完成标志位5。明确使用数值精确匹配避免将其他非零状态误判为完成。修正吹扫超时时间计算原代码PurgeTimeoutMinutes*6000*10006分钟实际会被计算成约10小时。现改为privatestaticreadonlyintPurgeTimeoutMschecked((int)TimeSpan.FromMinutes(PurgeTimeoutMinutes).TotalMilliseconds);实际等待时间为 6 分钟。保留原有业务顺序等待开始吹扫 - 等待吹扫完成5 - 写非强制锁定 - 写吹扫完成 - 判断上料位光电 - 进入人工下料验证结果dotnet build MaxWell.sln --no-restore --verbosity:minimal 0 个错误第四阶段上机验证开始吹扫信号已经为真时确认立即进入吹扫等待。开始吹扫信号从假变真时确认流程自动唤醒。吹扫状态为1、2、3、4时确认不会误判完成。吹扫完成状态变为5时确认进入人工下料。6 分钟内未完成时确认返回吹扫超时错误。吹扫等待期间点击停止或复位确认可以取消。六个工站同时执行吹扫确认没有新增 PLC 或 socket 断连。本阶段验证通过后下一阶段建议优化ManualMaterialRemovalService的取料完成等待。第五阶段优化已完成。修改文件ManualMaterialRemovalService.cs改动内容删除人工/自动化取料阶段内部的while Task.Delay(200)PLC 条件轮询。取料完成条件改为统一PlcConditionWaiter.WaitAsync安全光幕恢复当前封装要求的 U/V/W 光电均无器件载盘条件成立。PLC 条件满足后仍按原顺序写WriteUnloadingCompleteWriteNonForceLockWriteRunLightOff自动化逻辑保持自动化开启才发送EQPEOUSend。发送失败最多重试 3 次。发送失败后继续等待现场取料不会卡设备。自动化关闭时不发送通知也不启动 20 分钟提醒。自动化开启时PLC 取料等待和 20 分钟提醒并行。取料完成后立即继续不会等待提醒计时器。提醒只显示一次提醒后仍继续等待 PLC 现场条件。核心流程发送自动化取料通知最多3次 | 启动 PLC 取料条件等待 | -- 自动化关闭只等待 PLC 条件 | -- 自动化开启PLC 条件等待 与 20分钟提醒并行 | -- 取料完成立即写PLC完成握手 -- 提醒到期弹窗一次继续等待 -- 超时不写取料完成返回失败 -- 停止/复位取消等待验证dotnet build MaxWell.sln --no-restore --verbosity:minimal 0 个错误上机验证自动化关闭时确认不发送EQPEOUSend也不出现 20 分钟提醒。自动化开启且取料完成时确认立即写取料完成、非强制锁定、关闭 RUN 灯。自动化发送失败 3 次时确认仍继续等待人员取料。到达提醒时间但未取料时确认只提示一次流程继续等待。取料等待期间关闭自动化确认不会再弹自动化提醒。取料等待期间停止、复位、结批确认等待正常取消。六工站同时等待取料确认不新增 PLC/socket 断连。下一阶段建议优化LoadProduct.cs的上料许可和器件到位等待。这是高风险流程建议只先迁移“初始上料许可”这一组条件确认通过后再处理多器件扫码。第六阶段优化已完成。修改文件LoadProduct.cs本阶段只处理“初始上料许可等待”强制锁定 - 等待允许上料 - 等待载盘到位 - 确认吹扫完成标志位 ! 5 - RUN蓝灯闪烁 - 允许操作员上料具体改动新增WaitForInitialLoadingPermitAsync方法。初始上料条件统一由PlcConditionWaiter判断。等待由 PLC 完整快照变化触发。PLC 条件已经满足时立即继续不会漏掉当前状态。保留原有超时值PlcPollingTimeoutMs。将超时时间转换为TimeSpan避免直接使用毫秒数字。保留原有强制锁定、RUN 蓝灯闪烁和后续扫码逻辑。本阶段未修改器件放置检测单器件扫码三器件顺序扫码扫码失败重试第 2、3 颗器件等待。验证结果dotnet build MaxWell.sln --no-restore --verbosity:minimal 0 个错误上机验证允许上料已经为真时确认立即进入上料提示。允许上料从假变真时确认自动唤醒。载盘未到位时确认不会进入扫码。吹扫完成标志为5时确认不会允许上料。等待期间点击停止或复位确认能够取消。六个工站同时等待初始上料许可确认无新增 PLC/socket 断连。连续开批、结批、重新开批确认没有残留等待任务。本阶段上机验证通过后下一阶段建议只优化LoadProduct的“第 2、3 颗器件等待上料条件”随后再处理扫码前器件到位等待。第七阶段优化已完成。修改文件LoadProduct.cs本阶段只优化三器件流程中第 2、3 颗的上料等待。新增方法WaitForNextDeviceLoadingPermitAsync等待条件允许上料标志位 true 上料位载盘检测 true流程变为第1颗扫码成功 - PLC切换下一颗位置 - 等待第2颗上料许可 - 扫码第2颗 - PLC切换下一颗位置 - 等待第3颗上料许可 - 扫码第3颗优化内容第 2、3 颗不再直接调用通用等待方法。使用明确的“下一颗上料许可”方法。通过 PLC 完整快照变化唤醒。当前条件已经满足时立即继续。日志明确显示等待第 2 颗或第 3 颗上料许可。保留原有超时、取消和失败处理。保留原有缺料报警和对应相位光电检测。没有修改扫码顺序和扫码结果写入逻辑。验证结果dotnet build MaxWell.sln --no-restore --verbosity:minimal 0 个错误上机验证第 1 颗扫码成功后确认等待第 2 颗上料许可。第 2 颗扫码成功后确认等待第 3 颗上料许可。允许上料已经为真时确认立即进入下一步。载盘未到位时确认不会提前扫码。PLC 信号从假变真时确认流程自动唤醒。等待过程中点击停止或复位确认流程能够取消。第 2 或第 3 颗超时确认进入原有退料和错误处理。六个工站同时执行三器件扫码确认没有新增 PLC/socket 断连。第七阶段上机验证通过后下一阶段建议优化LoadProduct的单器件和三器件“扫码前器件到位 安全光幕 缺料报警”组合等待。第八阶段优化已完成修改文件LoadProduct.cs主要内容新增CreateDevicePlacementBeforeScanConditions统一处理安全光幕、封装类型对应的 U/V/W 光电检测。新增WaitForDevicePlacementBeforeScanAsync人工输入和自动扫码共用器件到位等待逻辑。新增WaitForScanConditionsAsync统一处理允许扫码、安全光幕及第 2、3 颗器件的附加条件。WaitForPlcConditionsAsync增加operationName日志可明确区分当前等待步骤。保留原有扫码顺序、扫码失败重试、黄灯/红灯、退料和 PLC 握手时序。封装类型仍通过PackageType.ini决定检测哪些光电位置不再固定判断 U/V/W 全部信号。验证结果dotnet build MaxWell.sln --no-restore --verbosity:minimal 0 个错误 255 个已有警告建议上机验证单器件、UV/UVW 等不同封装类型上料分别测试人工输入、自动扫码、第 2/3 颗等待、扫码失败重试以及光幕触发场景。第九阶段优化已完成修改文件UnLoadProduct.cs本阶段内容将WaitForUnloadPermissionAsync从独立while Task.Delay循环改为统一使用PlcConditionWaiter。统一判断以下三个条件上料位载盘检测为真允许取料标志位为真安全光幕为假。等待过程中不再频繁读取 PLC减少通信压力。强制锁定只在进入等待前解除一次避免重复写 PLC。两个下料入口统一使用UnloadTimeoutMs。修复原代码超时时间错误原UnloadTimeoutMinutes * 6000 * 1000实际约为 5 小时现在统一为配置含义对应的 5 分钟。保留仿真模式、扫码失败退料、人工下料和 PLC 完成握手逻辑。验证结果dotnet build MaxWell.sln --no-restore --verbosity:minimal 0 个错误 255 个已有警告建议上机验证允许取料未到位、光幕触发、载盘缺失、正常允许取料及等待超时等场景。第十阶段优化已完成。修改文件StationInitializationService.csStationControlViewModel.Mode.cs主要优化初始化等待从while ReadSignalFresh Task.Delay改为PlcConditionWaiter快照事件等待。初始化支持两个结束条件初始化完成标志位为真允许清料标志位为真。允许清料信号出现时立即返回清料结果不需要继续等待初始化超时。统一使用PlcSignalValueConverter删除StationInitializationService中重复的 PLC 布尔转换代码。初始化等待日志增加正确的工站号避免多工站同时初始化时日志全部显示为站号0。保留仿真模式、取消机制、初始化失败返回及后续测试单元初始化逻辑。验证结果dotnet build MaxWell.sln --no-restore --verbosity:minimal 0 个错误 255 个已有警告建议上机验证初始化完成标志正常变为真初始化过程中允许清料标志变为真初始化超时多个工站同时初始化复位取消初始化流程。第十一阶段优化已完成。修改文件PlcSignalValueConverter.csBatchLifecycleService.cs主要优化新增公共方法PlcSignalValueConverter.TryGetBooleanbool按原值处理数值型只有 0才判定为真0、负数判定为假字符串支持true/false和数值无法解析、空值返回false不会误放行。BatchLifecycleService删除内部重复的TryToBoolean方法。开批检查统一使用公共转换方法允许清料标志位补盘标志位。结批检查统一使用公共转换方法封装类型对应的 U/V/W 光电吹扫位器件检测测试位器件检测。保留ReadSignalFresh开批和结批属于安全边界检查仍读取当前 PLC 实时值没有改动开批、结批的业务顺序。验证结果dotnet build MaxWell.sln --no-restore --verbosity:minimal 0 个错误 255 个已有警告第十一阶段建议上机验证负数、0、1、5、空值以及字符串型 PLC 信号的判定结果。第十一阶段优化已完成。修改文件PlcSignalValueConverter.csBatchLifecycleService.cs主要优化新增公共方法PlcSignalValueConverter.TryGetBooleanbool按原值处理数值型只有 0才判定为真0、负数判定为假字符串支持true/false和数值无法解析、空值返回false不会误放行。BatchLifecycleService删除内部重复的TryToBoolean方法。开批检查统一使用公共转换方法允许清料标志位补盘标志位。结批检查统一使用公共转换方法封装类型对应的 U/V/W 光电吹扫位器件检测测试位器件检测。保留ReadSignalFresh开批和结批属于安全边界检查仍读取当前 PLC 实时值没有改动开批、结批的业务顺序。验证结果dotnet build MaxWell.sln --no-restore --verbosity:minimal 0 个错误 255 个已有警告第十一阶段建议上机验证负数、0、1、5、空值以及字符串型 PLC 信号的判定结果。第十二阶段优化已完成。修改文件StationControlViewModel.Safety.cs主要优化WaitForAllStationPositionsEmptyAsync从while Task.Delay改为统一使用PlcConditionWaiter。复位清空条件统一为当前配方PackageType.ini对应的 U/V/W 光电均无器件吹扫位无器件测试位无器件。未选择封装类型时按 U/V/W 全相位检查避免误判为空站。超时后保留当前实际占用位置如上料位 U 相、吹扫位、测试位便于现场排查。补齐MaxWell.Driver.M.Model引用并移除重复 using。验证结果dotnet build MaxWell.sln --no-restore --verbosity:minimal 0 个错误 237 个已有警告建议上机验证不同封装类型的复位清料、吹扫位残留、测试位残留、无配方复位以及两分钟超时提示。第十三阶段优化已完成重点优化正式测试前AllowTestingFlag等待逻辑使用PlcConditionWaiter监听 PLC 快照变化减少无效轮询和线程占用。保留 10 秒 PLC 信号有效性检查。保留正式测试 33 分钟总超时。流量、温度、气密报警出现时立即退出并进入异常处理。统一使用PlcSignalValueConverter解析 PLC 布尔值。避免正式测试流程重复读取 PLC降低通信冲突风险。验证结果dotnet build MaxWell.sln --no-restore编译错误0git diff --check通过现有项目警告仍存在但不是本阶段新增的编译错误。第十四阶段优化已完成修改文件MainBoard.cs主要内容恢复MainBoardDriver.ExecuteAsync的连接级互斥锁。重试期间持续占用锁避免迟到响应被下一条指令读取。SendRawAsync原始报文接口也加入同一把锁。拆分SendRawCoreAsync避免重复加锁造成死锁。确保异常、取消、超时后始终释放锁。该优化可以降低多工站同时运行时出现以下问题的概率Socket 收发交叉。主控响应错帧。无响应。数据包解析失败。TCP 连接频繁断开。验证结果MainBoard.cs编译目标通过。git diff --check通过。完整解决方案编译时受到正在运行的MaxWell进程占用 DLL 文件影响未终止该进程。第十五阶段优化完成聚焦 TCP 断链与半包发送问题。修改TcpConnector.csSocket.Send改为循环发送确保整条报文完整写入。识别Receive0、远端 FIN/RST、SocketException。通信异常后作废旧 Socket下次请求自动建立新连接。Socket.Connected增加Poll Available校验避免误判连接仍有效。原始读写、关闭、重建连接统一加锁。WriteBufferSize2000仍可使用它仅作为单次分块大小不是 TCP 最大报文限制。MainBoard.cs主控响应超时、CRC 错误、帧错位时主动关闭当前连接。第十四阶段的命令级重试会在下一次尝试时使用新 Socket避免迟到旧响应污染新命令。验证通信项目和设备项目CoreCompile通过。git diff --check通过。完整解决方案仍无法构建因为运行中的MaxWell进程占用了bin\Debug\MaxWell.Models.dll。第十六阶段优化完成修改文件ElectricalTestDataCollector.cs本阶段优化内容主控返回大量数据时每次最多读取64组。避免SavedDataGroups9602时一次性构造超大报文。防止ReadDataLength转换为ushort时溢出。避免单个工站长时间占用主控通信锁。未读取完的数据由下一次采集周期继续读取。增加空数据保护避免空帧继续进入温度换算、曲线和 CSV。增加取消检查停止测试时不会继续发起读取。日志记录本次请求数量、实际接收数量和剩余数量。验证结果MaxWell.Driver.M项目构建通过。编译错误0git diff --check通过现有项目警告仍保留未新增编译错误。第十七阶段优化完成主要完善主控板批量数据读取的协议边界。修改内容DebugToolCommands.cs单次最多读取64组。单次最大数据长度为6400字节。防止读取数量过大导致ushort溢出或 Socket 报文过大。校验响应长度必须是100字节数据组的整数倍。解析失败改为抛出明确异常不再返回null掩盖通讯故障。ManualHardwareService.cs手动读取数据限制为最多64组。手动采集接口同步增加数量校验。超过限制时提示分批读取。FormMainDriver.cs调试工具读取前校验范围1~64。输入非法数量时不发送主控指令。验证结果MaxWell.Communication构建通过。MaxWell.Device构建通过。MaxWell.Driver.M构建通过。MaxWell.DebugTool构建通过。编译错误0git diff --check通过。建议上机验证输入64组应正常发送输入65或更大数量应直接提示分批读取。已完成第十九阶段优化重点解决 PLC 轮询与业务读写的竞态问题。主要修改批量读取原子化AuxPLC.cs整批 PLC 地址读取期间禁止其他写入插入。避免生成不同时间点混合的 PLC 快照。开批、结批统一使用有效快照BatchLifecycleService.cs移除业务流程中的ReadSignalFresh。开批前清料、补盘检查以及结批物料检查都基于同一份完整快照。PLC 未连接、快照无效或信号缺失时直接禁止操作并返回明确原因。修复 PLC 释放顺序DeviceManager.cs释放顺序调整为停止 PLC 轮询 - 等待轮询任务退出 - 释放 AuxPLC Socket避免关闭工站或重连时出现“已释放对象仍在读取 PLC”。保留ReadSignalFresh兼容能力该方法仍保留给 DebugTool 诊断使用。生产流程、等待条件、实时显示不再使用该方法。验证结果编译错误0 git diff --check通过现场建议验证PLC 正常轮询时执行开批、结批。PLC 断线后执行开批确认禁止操作并提示 PLC 快照无效。批量读取期间执行 PLC 写入确认不会出现报文交叉。关闭工站或重新连接工站确认不再出现释放对象和轮询线程冲突。