# Current Handoff - Goal: 完成综合平台编程器的结构化梯形图、HMI、离线仿真和 Modbus RTU 真机链路 - Branch: `main` - Current status: 第 1~10 步的软件实现与自动化测试已完成,待连接 XDH-60T4-E 进行真机安全验证和整理最终交付资料 ## 当前能力 - 梯形图条件使用递归 `Node / Series / Parallel` 表达式树,可表示 `A OR (B AND C)` 和嵌套串并联 - 编辑器使用固定行列网格和正交连线,支持当前节点后串联、单节点并联、连续节点范围并联、删除节点或网络以及设置输出线圈 - 画布只选择可见节点,不暴露内部表达式容器;橡皮框或多选连续节点后可直接建立并联支路 - 执行器递归求值并生成节点、表达式、网络轨迹,离线运行时画布显示导通路径和故障位置 - HMI 和梯形图直接配置 M/D 地址,不依赖预先创建的数据点 - `ActiveRegisterRepository` 在离线虚拟仓库与 PLC 缓存仓库之间切换 - `PlcCommunicationService` 使用 Qt SerialBus 异步连接、轮询和单点写入,UI 不阻塞 - 真机连接收集 HMI 和梯形图实际引用地址,按 M/D 分区并合并相邻地址读取 - 真机模式要求首次读取完成,不复制离线值,不运行 PC 软件逻辑执行器 - 通信错误停止轮询并保留最后一次有效缓存,状态栏和日志显示错误 - 主窗口静态控件已迁入 `main_window.ui`,PLC 参数由独立配置对话框收集后再发起连接 - 已增加运行监控工作台:离线仿真同时显示 HMI、梯形图轨迹和自由监控,真机运行只显示 HMI 和自由监控 - 自由监控支持 `M0~M4000`、`D0~D4000` 地址输入、连续批量添加、去重、删除、清空和最多 64 项限制 - 自由监控读取活动寄存器仓库,离线使用虚拟 M/D,真机使用 PLC 缓存,通信故障保留并标记最后有效值 - PLC 轮询集合已扩展为 HMI、梯形图和自由监控地址的并集,连接后可动态增删监控地址 - 已在真实 `COM3 / 9600 / 8E1 / 站号 1` 上完成只读联机验证,项目通信服务可完成 M/D 首次读取并进入真机运行前置状态 ## 关键决策 - 工程格式继续使用 `1.0`,当前文件只保存 HMI 和梯形图表达式树,不保留 `dataPoints` 结构及兼容代码 - 不读取旧的 `stages/branches` 结构,不添加旧格式迁移和兼容层 - 梯形图编辑结构而不是自由线段,避免悬空线、环路和多个输出路径 - 网格仅作为编辑投影,不进入工程格式;服务层把连续范围操作转换为规范化表达式树 - 条件节点继续使用 `std::variant` 的独立配置类型,不向通用节点添加无关字段 - HMI、梯形图和通信共享 `M0~M4000`、`D0~D4000` 地址范围 - 已删除统一数据点表、主窗口数据点 Dock 和属性区数据点下拉框;软元件注释功能待后续按信捷业务单独设计 - PLC 读写使用从 `0` 开始的原始 Modbus 地址 - HMI 写请求不乐观修改 PLC 缓存,由下一次轮询确认真实值 - 真机运行时 PLC 内部程序是控制源,软件逻辑执行器保持停止 - 真机运行不显示本地梯形图导通轨迹,避免把本地工程误表示为 PLC 内部程序的真实执行状态 - 自由监控表属于当前调试会话,不进入工程 `1.0` JSON,不重新引入数据点表 ## 自动化验证 以下测试均已完成干净构建并通过: - `domain_tests` - `logic_editor_service_tests` - `offline_simulation_service_tests` - `project_management_tests` - `hmi_editor_service_tests` - `runtime_mode_service_tests` - `plc_runtime_tests` - `main_window_tests` - `register_monitor_service_tests` `main_window_tests` 还覆盖 PLC 配置参数往返、独立配置弹窗入口,以及主窗口不再内嵌串口参数控件。 2026-08-13 真机排查发现 `QModbusRtuSerialMaster::connectDevice()` 在当前 Windows 串口驱动上会同步触发 `ConnectedState`。旧实现随后再次写入 `Connecting`,导致已经发出的 读取响应因服务状态不是 `Connected` 而被丢弃,首次读取标志永远不能完成。现已把 `Connecting` 状态设置移动到 Qt 连接调用之前,并在真实 PLC 上验证首轮 `M0~M2`、`D0` 读取约 288 ms 完成,缓存值为 `M0=1`、`M1=1`、`M2=0`、`D0=0`。主窗口现在会显示 连接、首读完成和具体中文通信故障,生产代码中的业务错误提示已统一为中文,JSON 字段和协议标记保持不变。 PLC 连接初始化会连续通知首读重置、正在连接和已连接。旧主窗口把每次通知都排队处理, 队列执行时读取到的已经是同一个最终状态,因此输出区会连续追加三条相同的“正在首读”。 现已在主窗口合并同一事件循环内的 PLC 状态刷新,并拒绝连续追加完全相同的输出消息。 真实 `COM3` 主窗口联调确认“正在首读”和“首次读取完成”各输出一次。 本轮已完整删除统一数据点业务,包括领域模型、服务、主窗口 Dock、属性区下拉框、JSON 字段和独立测试工程。当前开发阶段不保留 `dataPoints` 旧结构的迁移或兼容逻辑。主窗口测试明确验证已删除控件不存在,PLC 轮询测试改为验证从 HMI 实际绑定收集地址。 本轮梯形图编辑重构还验证了:固定网格渲染、水平/垂直正交布线、工具栏直接建立并联支路,以及连续范围 `A AND ((B AND C) OR D)` 的结构变换和非连续范围拒绝。 本轮自由监控与运行工作台实现还验证了:地址字符串解析和边界、连续范围展开、去重和数量 上限、活动仓库切换、离线工作台三区域同时可见、真机工作台只显示 HMI 与自由监控、离线 监控读取虚拟 M/D,以及真机运行期间新增地址立即进入 PLC 聚合轮询集合。PLC 动态轮询在 读取请求空闲后应用新集合,连接首读完成后不会因新增监控地址而回退。 运行工作台的 HMI 和梯形图是独立于编辑画布的模型投影。此前同一页面或逻辑 ID 在编辑态 发生变化后,运行投影的 `setPageId()` / `setLogicId()` 会因 ID 未变化而跳过重建,导致新建 HMI 控件在离线运行工作台中显示为空白。现在每次同步运行对象都会显式重建两个投影,主窗口 测试会保留一个已配置 HMI 控件,并断言离线运行视图实际包含该控件,而不再只检查区域可见。 Qt Release 应用已完成干净构建,并执行了启动与正常退出冒烟验证。`git diff --check` 无空白错误。 ## 待完成事项 1. 在 PLC STOP 状态确认 COM2 参数和 RS-485 A/B 接线 2. 用安全测试地址读取 `M0`、`D0` 3. 写入 `M0`、`D0` 并由 PLC 监控和下一次轮询确认 4. 验证断线、超时和重新连接流程 5. PLC 切换 RUN 后执行完整 HMI 与设备联动测试 6. 整理测试记录、构建说明和演示工程 ## 建议下一步 运行 Release 应用,配置实际 COM 口、站号、波特率和校验方式,在 PLC STOP 状态完成 `M0`、`D0` 首次安全读写。未确认设备程序与负载安全前不要在 RUN 状态写控制地址。