跳到主要内容

QG 流程程序

QG 用来表达有顺序的自动化行为:调用 Object、判断条件、等待、记录状态,并处理故障和恢复。当前唯一源码格式是 .qg;编辑器的 SourceFlow 只是同一份程序的两种视图。

如果你第一次使用 QG,先完成QG 流程、对象调用与调试,再回来查本页。

什么时候使用 QG

适合放进 QG 的内容:

  • 设备或业务动作的先后顺序;
  • 条件、分支、有界等待和超时;
  • 多个 Object 之间的协调;
  • App 启动、周期更新和停止时需要执行的流程;
  • 需要通过 Debug 断点观察的控制逻辑。

不适合放进 QG 的内容:

  • Page 布局和按钮外观;
  • 设备协议、寄存器解析或驱动实现;
  • 急停、安全回路或认证安全功能;
  • 项目未管理的第三方代码、动态脚本或无限后台任务。

创建并打开 QG

  1. Resources 右键 Scripts
  2. 选择新建 QG 程序,使用清楚、稳定的文件名,例如 packaging-station.qg
  3. 编辑器会在 graphs/ 下创建源码,并为它建立对应的 Object 实例;在 Resources → Objects 中确认 Object ID 和名称。
  4. Source 编写或审阅源码;需要结构化浏览时切到 Flow
  5. 保存后先处理当前文档的实时诊断;需要完整结果时执行 Build。

每个 QG 文件开头应有一段简短 JSDoc,说明它对 App 提供的能力。描述应面向工程用途,例如“编排包装周期并处理超时恢复”,不要写实现历史或易变参数。

Source 与 Flow

  • Source 是唯一源码,可以由人工或 AI 直接编辑。
  • Flow 从当前 Source 生成,并把函数、条件、循环和 Object 调用投影成结构化流程。
  • 在 Flow 中接受的修改会更新同一份 Source;不存在另一份连线文件、坐标文件或待同步草稿。
  • Source 与 Flow 使用同一组断点。源码位置变化后应重新 Build Debug,再开始新的调试会话。

如果 Flow 无法显示,先看 Source 和 Problems。上游 QG 或 Object 错误没有解决前,不要通过删除类型或猜测方法名来强行生成空流程。

程序结构

一个 QG 通常包含三类内容:

内容用途
顶层状态当前运行实例内共享的短期状态;重新加载实例后会重置
普通函数拆分计算和流程步骤,只在当前 QG 内使用
export function该 QG Object 对 Page、其他 QG 或在线工具公开的方法

可选生命周期函数只有:

  • Init(): void:App 开始时执行一次;
  • Update(): void:运行期间由 Runtime 周期调用;
  • Dispose(): void:停止或故障清理时执行。

不要在 QG 中创建自己的周期定时器或永久循环。把一次 Update 控制在可预测时长内,并为所有外部等待设置明确的超时和恢复路径。

使用 Object 能力

QG 通过 objects.<引用名>.<方法>(...) 调用当前 App 已绑定的 Object。正确流程是:

  1. 在 Flow 使用添加 Object 引用,或在 Object 属性中选择目标实例。
  2. 从编辑器提供的当前方法列表选择能力。
  3. 按显示的参数顺序、类型和单位传值。
  4. 保存并处理 Object 或 QG 诊断。
  5. Build 后在模拟器或受控设备状态下验证真实结果。

Object 方法必须来自当前 App 已安装的能力。不要根据旧项目、截图或类似设备猜测方法名、单位、极性和允许条件。AI 也应先检查当前 Object catalog,再只展开实际要使用的 Provider 接口。

常用语言规则

QG 使用便于 TypeScript 工具理解的语法,但不是通用 JavaScript 运行环境。

需要表达的内容当前写法
布尔值bool
有符号整数i8i16i32i64
无符号整数u8u16u32u64
浮点数f32f64
文本和无返回值stringvoid
固定记录顶层 TypeScript interface,字段使用精确标量类型
一维列表T[],支持长度、索引、赋值、pushfor...of

关键限制:

  • 不使用 numberbooleananyunknownnull
  • 数值转换要显式,例如 u32(value)
  • 不使用 asyncawaitPromise、异常、class、import 或动态模块;
  • Object 调用按源码顺序完成,即使底层操作需要等待,源码也不添加异步标记;
  • 循环必须有清楚的退出条件;QG 不会自动给无限循环增加迭代上限。

以编辑器诊断为准。不要用类型断言、忽略注释或生成代码绕过错误。

时间、日志和持久状态

QG 提供少量内建能力:

  • QG.clock.monotonicMilliseconds():读取单调时间;
  • QG.clock.delay(milliseconds):执行可取消等待;
  • QG.log.debug/info/warn/error(...):写入运行日志;
  • QG.mathQG.bitsQG.array:精确数值、位运算和数组辅助;
  • QG.saved.get/set:保存需要跨运行实例保留的标量或固定记录。

持久状态属于当前运行目标,不会写回 App 工程,也不会随着 Git 自动迁移。一次成功的 QG.saved.set 不会因为后续故障自动回滚;修改状态结构时,应规划显式迁移或使用新的名称。

示例:

export function IncrementTotal(): u64 {
let total: u64 = QG.saved.get("totalCycles", u64(0));
total = total + u64(1);
QG.saved.set("totalCycles", total);
return total;
}

Page 需要持久值时,应调用 QG Object 的公开方法,不直接拥有另一份存储逻辑。

调试 QG

  1. 保存 QG 和相关 Object 修改。
  2. 在 Source 或 Flow 的目标语句上设置断点。
  3. 确认 App 已 Stopped,选择 Build Debug
  4. 点击 Debug。缺少适用 Build 时,编辑器会询问是否 Build and continue;只有确认后才继续。
  5. 从 Page、另一个 QG 或允许的在线入口触发目标方法。
  6. 命中断点后检查当前语句、参数、状态、Console 和设备反馈,再点击 Continue
  7. 使用 Stop 结束调试,并确认清理后的设备状态。

当前提供断点和 Continue,不提供源码单步或条件断点。Debug 不会模拟设备、跳过真实输出或自动保证流程安全。

保存、Build 与运行边界

  • 保存只更新编辑态;Flow 和实时诊断也只反映源码。
  • Build 使用磁盘上已保存的文件,并把结果部署到当前运行目标。
  • Preview 不会 Build 或 Deploy。它只使用专用 Previewing 状态,其中的 Object 调用可能产生真实副作用。
  • Start 和 Debug 运行已部署版本;当编辑器提示 Build 时,由用户明确确认后才会先 Build 再继续。
  • 运行中不会热替换 QG 或 Object。修改后使用 Stop → 保存 → Build → Start/Debug

常见问题

Flow 为空或方法缺失

先修复 Source 和 Object 的上游错误。确认引用已经绑定到正确实例,再重新打开 Flow;不要手写一份接口或使用旧方法名填空。

Page 找不到 QG 方法

确认 QG 方法使用 export function、文件已保存、对应 Object 已绑定,并重新执行 Build。Page 只会获得当前已解析 Object model 中的公开方法。

断点不命中

确认使用了当前源码对应的 Build Debug,断点位于实际执行的方法内,并且 Debug 的目标与当前编辑器绑定目标一致。

修改后设备仍是旧行为

保存不会替换运行实例。先 Stop,再 Build 并重新 Start/Debug;同时核对顶栏运行目标。

故障后 App 回到 Stopped

这是统一清理行为。记录故障阶段、消息、触发动作和 Console,再修复根因。不要通过反复 Start 掩盖未查明的故障。

工程与安全检查

在连接真实设备前,逐项确认:

  • Object 身份、地址、单位、极性和量程;
  • 启动允许条件和停止后的安全状态;
  • 每个等待的超时、取消和恢复路径;
  • InitDispose 和故障清理是否符合设备要求;
  • 重试是否可能重复产生不可逆副作用;
  • 急停、安全门和硬限位是否由独立、合适的安全系统保证。

QG 负责流程编排,不替代设备驱动、后端授权或认证安全控制。

相关页面