综合平台编程器项目的远程存储
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 

8.6 KiB

综合平台编程器架构

目标与范围

项目是单工程、单 PLC、多 HMI 页面和多控制逻辑的 Qt 桌面编程器,提供 HMI 编辑、结构化梯形图、离线仿真和 Modbus RTU 真机联机。

本项目不生成、编译或下载 PLC 程序,不读取 PLC 内部程序与网络轨迹,不实现完整 XDPPro 指令集,也不支持任意自由画线。真机运行时 PLC 内部程序是唯一控制源,PC 只读写工程实际引用的 M/D 地址。

分层与依赖

app/src/
├── domain/          无 Qt 依赖的模型、值对象、校验和仓库接口
├── services/        编辑、工程、仿真、运行模式和通信契约
├── infrastructure/  JSON、PLC 缓存、Qt Modbus RTU 实现
├── ui/              Qt Widgets 视图、对话框和界面控制器
└── main.cpp         对象创建与依赖注入

生产代码依赖方向固定为:

UI -> Services -> Domain
Infrastructure -> Services contracts + Domain
main.cpp -> UI + Services + Infrastructure
  • domain 不依赖 Qt、文件系统或串口
  • services 执行业务用例和原子编辑,通过接口使用工程存储与 PLC 通信
  • infrastructure 实现 JSON 工程存储、PLC 缓存和异步 Modbus RTU
  • ui 只提交命令并投影模型、轨迹和错误,不直接读写串口或承载业务校验
  • main.cpp 只组合对象,不实现业务规则

主窗口静态布局由 main_window.ui 管理。UI 协调分为:

组件 职责
ProjectWorkspaceController 工程树、当前页面/逻辑会话选择和编辑对象刷新
PropertyPanelController HMI/梯形图选择、属性表单和编辑服务调用
RuntimePanelController 运行工作台、运行值刷新、仿真轨迹和故障反馈
MainWindow 窗口级动作、工程文件操作、控制器组合和模式切换

工程模型与持久化

Project
├── metadata
├── hmiPages[] + initialHmiPageId
├── alarmDefinitions[]
├── registerComments[]
└── controlLogics[]
    └── rungs[]
        ├── condition
        └── output
  • 页面、逻辑和节点使用稳定 ID;名称可修改,数组顺序决定工程树顺序和离线扫描顺序
  • 当前编辑页面和当前逻辑是 UI 会话状态,不写入工程
  • HMI 控件类型、默认值、绑定规则和运行值类型由无 Qt 依赖的 hmi_control_registry 统一描述
  • 需要寄存器的 HMI 控件、报警条件和梯形图节点直接保存 M/D 地址;项目不再维护统一 dataPoints
  • registerComments 只是 M/D 地址元数据,不保存当前值或引用位置,也不会让地址自动进入 PLC 轮询

工程 JSON 格式固定为严格的 1.0。加载顺序为 JSON 解析、版本检查、字段解析、领域校验,全部成功后才能替换当前工程;保存使用原子提交。当前版本不读取旧 dataPointsstages/branches 或缺少必填字段的同版本草稿。字段定义见 docs/工程格式说明.md

校验分两级:

  • validate() 保证可保存结构合法,允许未绑定控件、待配置节点和未完成网络作为编辑草稿
  • validateForRunning() 检查运行所需绑定和已启用逻辑;禁用草稿不阻止运行

数量常量集中在 domain/project_limits.h,最终业务口径见 docs/用户使用/数量边界确认方案.md。领域、服务、JSON 和 UI 入口必须使用同一组常量,不能各自维护数字。

结构化梯形图

网络条件保存为规范化表达式树:

ConditionExpression
├── Node       触点、边沿或比较条件
├── Wire       无地址横线,保存条件区列跨度
├── Series     子表达式执行 AND
└── Parallel   子表达式执行 OR

输出是网络最右侧的单独节点。LogicEditorService 把串联、并联、旁路、替换和删除转换为表达式树操作,失败时回退整个编辑;LogicEditorWidget 只把树投影成正交网格。竖线由 Parallel 边界派生,网格坐标和自由线段不持久化,因此领域模型不会产生悬空线、环路或多输出路径。

单网络前 10 列为条件区,输出最多位于第 11 列;横线只能占条件区。第 11 个条件、过深表达式或过多并联行会在编辑和加载阶段被拒绝,具体数值以数量边界文档为准。

网络运行语义:

  • 空网络不执行
  • 有条件但没有输出的已启用网络不能运行
  • 有输出但没有条件的网络是恒真网络,每次扫描执行输出
  • Wire 的逻辑值为真,但运行轨迹是否导通仍取决于上游电流

节点配置使用 std::variant 的独立类型。当前条件包括 M 触点与上下沿、T/C 触点和 D 比较;输出包括普通/置位/复位 M 线圈、TON、CTU/CTD、MOVE、ADD/SUB。新增指令必须增加独立配置、校验、JSON、执行、编辑和测试分支,不能向通用节点堆叠无关字段。

SoftwareLogicExecutorcontrolLogics 和网络数组顺序扫描已启用逻辑,前面网络的 M/D 写入在同一扫描周期对后面网络可见。T/C 是离线执行器内部资源,不映射 PLC T/C 区,也不进入 Modbus 轮询;计数器 CV/PV 等显式 M/D 引用仍使用统一仓库。扫描轨迹按逻辑 ID 分区,避免不同逻辑中的重复节点 ID 相互覆盖。

数据源与运行模式

运行界面只访问 RegisterRepositoryActiveRegisterRepository 根据模式切换实际数据源:

编辑:UI -> Editor Services -> ProjectService -> Project
                                  └── ProjectStorage -> JSON

离线:Runtime UI -> ActiveRegisterRepository -> VirtualRegisterRepository
                                               ^
                          OfflineSimulationService(SoftwareLogicExecutor)

真机:Runtime UI -> ActiveRegisterRepository -> PlcRegisterRepository(cache)
                                                   ^
PLC <-> PlcCommunicationService <------------------┘
模式 允许工程编辑 寄存器来源 软件逻辑执行器 进入条件
编辑态 无运行数据源 停止 运行态先退出
离线运行 虚拟 M/D 运行 工程通过运行校验
真机运行 PLC 读回缓存 停止 PLC 已连接并完成本次首读

离线和真机不能直接互切。进入真机不复制或下发离线值,也不显示本地梯形图导通轨迹。

自由监控是会话级诊断工具,不属于 Project,不写入 JSON。它通过活动仓库读取和单点写入 M/D;真机写入仍必须经过连接与首读门槛。

Modbus RTU 通信

PlcCommunicationService 使用 QModbusRtuSerialMaster 异步连接、轮询和单点写入,UI 线程不等待串口响应。Modbus 地址使用从 0 开始的原始地址。

轮询集合由 HMI、报警、梯形图中的显式 M/D 引用和自由监控地址合并,按区域去重并合并相邻地址。T/C 内部资源、横线和注释不进入轮询。动态修改监控地址时,当前请求按旧快照解析,空闲后再应用新集合。

PLC 缓存只保存最后一次成功读回值。写请求受理后不乐观修改缓存,界面等待后续轮询确认真实值。真机运行资格属于当前连接代次:必须完成完整首读,旧连接的异步回复不能污染重连后的状态。

通信状态包括 Disconnected / Connecting / Connected / Recovering / Faulted。连接失败或物理断线会关闭串口会话并进入 Disconnected;超时、协议或读写故障会停止正常轮询、保留最后有效缓存并进入 Faulted。所有通信故障都会撤销首读资格;若当时处于真机运行,运行模式服务立即返回编辑态。可恢复超时探测成功后进入 Recovering 并重新完整首读,但不会自动重新进入真机运行。

扩展规则

  • 新业务先确定所属领域模型和服务用例,再添加 UI;不得从 UI 直接改工程容器或串口状态
  • 编辑操作必须在服务层校验并原子提交,失败不能污染撤销历史或留下半成品
  • 新持久化字段必须同步领域校验、严格 JSON 往返、缺失/非法字段测试和格式说明;是否升级格式版本必须明确决定
  • 新数量边界必须进入 project_limits.h、数量边界文档和上下界测试
  • 新 HMI 类型优先扩展 hmi_control_registry,专用交互留在对应服务和图元
  • 不重新引入数据点表、自由线段、UI 直连串口或真机执行本地梯形图
  • 自动化测试按风险覆盖领域、服务、存储、通信和 UI;真实串口、接线和设备 RUN 联动必须现场验证