准备:控制字、位号与页面
Tag 是 Mingcedar 中已配置的数据点。整数控制字用不同的位表示不同开关状态;Bit Index 从 0 编号。Set 将某位置为 1,Reset 置为 0,Toggle 反转当前位。本教程假设 PLC_LINE01.PUMP01.CTRL_WORD 和 PLC_LINE01.PUMP02.CTRL_WORD 是可写的 WORD(16 位整数),质量为 good,初始值为 0。只在练习设备上使用第 3、5 位;实际位含义由设备点表决定。
- 先完成示例 1,再复制页面做后续示例。示例 2、3、4 是三种目标选择方案,分别保留副本;不要把所有 Page Script 叠加在一页。
- 在 PowerPoint 插入矩形作为按钮。点击 MX Design → Behaviors → Browse,打开行为浏览器,从右侧目录把指定行为拖到左侧的这个组件节点,再双击该行为填写字段。
- 脚本标注 Page Script 时,打开 MX Design → Scripts → Page Script,写入当前页脚本文档;标注 Click Script 时,写在按钮的 Click Script 行为中。字段清单不是 JavaScript,不要整段粘进脚本。
- 完成各示例的全部步骤后保存 PPT,执行 MX Design → Export → Export HTML 整包导出,再在 Mingcedar 打开对应页面。写入由运行页上的真实操作触发。
完成标志 本例使用 WORD 的第 3 位和第 5 位;对应数值分别为 8 和 32。示例中的整数变化以初始值 0、没有其他程序同时写入为前提。
准备:显示两个控制字的读回值
插入两个文本框,标注 PUMP01、PUMP02,为各自添加 Tag Text 并按下表填写 Target tag,其余字段保持默认。后续复制页面时保留。
左右滑动查看完整表格
完成标志 导出并在 Mingcedar 打开后,两个文本框应显示各自控制字的当前整数值。先确认两者为 0,再开始下一个示例。
如果结果不一致
- 没有读到值:核对 Tag 名称及通信质量。确认读回正常后再进行写入练习。
示例 1:固定目标位写入
给矩形添加 Write Tag Bit,按清单配置并保存,文字设为 Set。复制两份,将文字和 Action 改为 Reset、Toggle。清单的 Bit Action 对应编辑器 Bit write → Action;Target Tag 填父整数名,不加 [3]。
Write Tag Bit → 字段配置(逐项填写)Text
Target Tag: PLC_LINE01.PUMP01.CTRL_WORD
Bit Index: 3
Bit Action: Set
Condition: true
完成标志 依次点击 Set、Set、Reset、Toggle、Toggle,每次等待读回显示更新后再进行下一次。初始为 0 的父值应为 8、8、0、8、0。Set / Reset 可重复执行;Toggle 的结果取决于点击前的位值。
如果结果不一致
- 保存失败:检查 Target Tag 没有 [3];Bit Index 只填写整数,不能写 <BIT>、bitIndex 或 =bitIndex。
- 按钮能点但写入失败:检查目标是否存在、是否为可写整数、当前值和质量是否可用,并查看运行平台返回的权限或写入错误。
示例 2:配置两个设备模板实例
复制示例 1 的页面。在三个按钮的 Write Tag Bit 中,把 Target Tag 都改成 <PLC>.<PUMP>.CTRL_WORD,位号仍为 3。<PLC>、<PUMP> 是制作模板时的占位符,在插入实例时填写实际值;它们不是运行中可切换的页面变量。
- 添加设备标题文本框,将它与三个按钮组合。选中整个组合,打开 MX Design → Templates → Library,点击 Save selection;Template name 填 Pump bit controls,确认 Captured variables 中有 PLC、PUMP,再点击 Save。
- 确认模板保存成功后,从当前页删除仍带占位符的原始组合;Save selection 只保存到库,不会移除原稿。仅隐藏或移到同一 PPT 的其他页,整包导出时仍会处理它。
- 双击 Pump bit controls 卡片两次,插入两份实例。分别选中整个实例组合,点击 MX Design → Templates → Edit Instance,在 Template variables 中填写下列值并 Save;值不加引号。导出后分别点击两组按钮,查看前面配置的两个读回值。
Template Edit → 两个实例的 Template variables 填写例Text
// 实例一的 Template variables
PLC = PLC_LINE01
PUMP = PUMP01
// 实例二的 Template variables
PLC = PLC_LINE01
PUMP = PUMP02
完成标志 实例一只操作 PLC_LINE01.PUMP01.CTRL_WORD 的第 3 位;实例二只操作 PLC_LINE01.PUMP02.CTRL_WORD 的第 3 位。外观和位号相同,目标设备不同。
如果结果不一致
- 导出仍有 <PLC> 或 <PUMP>:检查选中的是实例根组、Captured variables 是否包含它们,以及两份实例是否分别保存了值。
示例 3:用页面变量切换目标
另存示例 1,保留普通按钮,将下方代码放入 Page Script。selectedControlTag 保存名称字符串;HQVISU_DECLARE_TAGS 声明候选 Tag,供导出检查生成读写依赖,不创建 Tag 或授予权限。
- 三个 Write Tag Bit 按钮的 Target Tag 都改为 =selectedControlTag;Bit Index 仍为 3。开头的 = 明确表示求表达式的值,不能把这一行粘进 Page Script。声明的 expression 则不带 =。
- 另外画两个选择按钮,分别添加 Interactions → Set Variable on Click。Variable 都填 selectedControlTag;Value 分别填 "PLC_LINE01.PUMP01.CTRL_WORD" 和 "PLC_LINE01.PUMP02.CTRL_WORD",保留字符串引号。
- 在运行平台中先选择 PUMP02,再点 Set;然后选择 PUMP01,再点 Set。选择按钮本身只改当前页变量,写位按钮才提交设备写入。
Page Script → 示例 3 目标页(完整代码)JavaScript
var selectedControlTag = "PLC_LINE01.PUMP01.CTRL_WORD";
HQVISU_DECLARE_TAGS({
expression: "selectedControlTag",
read: ["PLC_LINE01.PUMP01.CTRL_WORD", "PLC_LINE01.PUMP02.CTRL_WORD"],
write: ["PLC_LINE01.PUMP01.CTRL_WORD", "PLC_LINE01.PUMP02.CTRL_WORD"]
});
完成标志 同一套写位按钮先操作 PUMP02,再操作 PUMP01。重新打开页面时恢复 Page Script 的初始选择。
如果结果不一致
- 目标没有切换:检查 Variable 拼写、Value 的字符串引号和 Target Tag 的 =;不要在按钮的 Setup Script 重复初始化 selectedControlTag。新增候选设备时同时更新声明与选择按钮。
示例 4A:从入口页传入要操作的设备
复制示例 3 目标页并删除设备选择按钮。在 MX Design → Page → Nav Path 将 Page Code 设为 pump_bits。另建入口页按钮,配置下方 Click Script,传入 pump=PUMP02。
Click Script → 入口页的“打开 PUMP02”按钮JavaScript
return hqVisuDesigner.openPage("pump_bits", {
parameters: [{ key: "pump", value: "PUMP02" }]
});
完成标志 浏览器中的目标页收到 pump 参数;它不会改写 Template Edit 中的 <PUMP>。还需完成下一步,把参数转换成目标名称。
如果结果不一致
- 没有打开目标页:核对实际 Page Code 和导出包中是否包含 pump_bits;脚本放在入口按钮上,不放在目标页 Page Script。
示例 4B:校验页面参数并选择目标
用下方代码完整替换 pump_bits 的 Page Script,不要追加到原初始化之后。只允许两台已配置设备;参数缺失或未知时不初始化目标,即使页面显示也不建立写入目标。三按钮保留 Target Tag =selectedControlTag、Bit Index 3。
Page Script → pump_bits 目标页(替换原脚本)JavaScript
var pumpCode = GetPageParameter("pump", "");
if (pumpCode !== "PUMP01" && pumpCode !== "PUMP02") {
throw new Error("请选择 PUMP01 或 PUMP02 后打开页面");
}
var selectedControlTag = "PLC_LINE01." + pumpCode + ".CTRL_WORD";
HQVISU_DECLARE_TAGS({
expression: "selectedControlTag",
read: ["PLC_LINE01.PUMP01.CTRL_WORD", "PLC_LINE01.PUMP02.CTRL_WORD"],
write: ["PLC_LINE01.PUMP01.CTRL_WORD", "PLC_LINE01.PUMP02.CTRL_WORD"]
});
完成标志 复制入口按钮,将代码中的 PUMP02 改为 PUMP01;分别打开并写位,核对对应读回值。再临时把一个入口的参数值改为 PUMP99,重新导出后打开:写位按钮不应产生设备写入。完成后恢复有效参数。
如果结果不一致
- 看到参数错误:检查 key 必须为 pump,值必须精确为 PUMP01 或 PUMP02。页面参数用于选择上下文,不是写权限凭证。
示例 5A:配置位号与动作选择
复制示例 3,保留 Page Script 和选择按钮,在脚本末尾追加下方两行。删除三个 Write Tag Bit 按钮,改建“执行”按钮并添加 Click Script,下一步填写。Bit Index 不接受变量,动态位号须用脚本 API。
- 画“第 3 位”和“第 5 位”两个选择按钮,添加 Set Variable on Click;Variable 填 selectedBitIndex,Value 分别填数字 3、5,不加引号。
- 画 Set、Reset、Toggle 三个选择按钮,同样添加 Set Variable on Click;Variable 填 selectedBitAction,Value 分别填 "Set"、"Reset"、"Toggle",保留引号。
- 这些选择按钮只改变量。一次写入由“执行”按钮完成,不要同时在它上面保留 Write Tag Bit 行为。
Page Script → 示例 5 页面(追加到末尾)JavaScript
var selectedBitIndex = 3;
var selectedBitAction = "Set";
完成标志 页面持有三项选择:设备名称、位号、动作。它们改变时尚未写入设备。
如果结果不一致
- 变量未定义:确认两行代码追加在示例 3 的 Page Script,而不是某个选择按钮的局部脚本里。
示例 5B:校验选择并执行写入
将下方代码放入“执行”按钮的 Click Script,仅允许两台设备、第 3/5 位和 Set/Reset/Toggle;这是示例范围。函数参数直接传变量,不加 = 或变量名引号。
Click Script →“执行”按钮JavaScript
if (["PLC_LINE01.PUMP01.CTRL_WORD", "PLC_LINE01.PUMP02.CTRL_WORD"].indexOf(selectedControlTag) < 0) {
throw new Error("目标设备不在允许列表中");
}
var rawBit = selectedBitIndex;
if ((typeof rawBit !== "number" && typeof rawBit !== "string") || String(rawBit).trim() === "") {
throw new Error("请选择有效位号");
}
var bit = Number(rawBit);
if (!Number.isInteger(bit) || [3, 5].indexOf(bit) < 0) {
throw new Error("本页只允许第 3 位或第 5 位");
}
var action = selectedBitAction;
if (["Set", "Reset", "Toggle"].indexOf(action) < 0) {
throw new Error("请选择 Set、Reset 或 Toggle");
}
return WriteTagBit(selectedControlTag, bit, action);
完成标志 选 PUMP02、第 5 位、Set,再点执行:初始为 0 的 PUMP02 父值变为 32,PUMP01 不变。把选择改为 Reset 再执行,PUMP02 回到 0。第 4 位、空白位号、未知动作都会在提交前被拒绝。
如果结果不一致
- 提示需要可信用户操作:写入应由用户真实点击触发,不放到 Page Script 初始化、颜色求值或定时器里。声明仍需覆盖 selectedControlTag 的全部候选;允许列表检查不能代替运行平台授权。
示例 6A:用状态灯和文字读取第 3 位
复制示例 1,保留写位按钮,添加圆形灯和文本框。State Color 与 Tag Text 显示读回状态,写位仍由按钮提交。
- 给圆形添加 Visual States → State Color。Setup Script 留空,Condition 填下方表达式;Action 中启用 TRUE、FALSE 和 Fill color,TRUE 设绿色 #22C55E,FALSE 设灰色 #94A3B8。
- 在 State Color 的 Quality Override 勾选 Follow data quality (border / hide),Bad 设橙色;质量异常时不要把回退 false 当作设备确认停止。
- 给文本框添加 Text → Tag Text。Target tag 填 PLC_LINE01.PUMP01.CTRL_WORD[3];Fallback value 填 "--",Prefix 填 "Bit 3 = ",Suffix 填 ""。这里是读位,名称可以带 [3]。
State Color → ConditionJavaScript
ReadTagBoolean("PLC_LINE01.PUMP01.CTRL_WORD[3]", false)
完成标志 点击 Set 后等待运行平台读回,状态灯变绿,文本显示该位的布尔值;Reset 后灯变灰。即使把写位按钮删除,外部改变父 Tag 时显示仍会更新。
如果结果不一致
- 文本出现整个整数 8:Target tag 漏了 [3]。灯一直绿或一直灰:检查 Condition 是读位表达式、TRUE/FALSE 都已启用;不要把父整数名称直接当成布尔条件。
示例 6B:动态位状态显示
复制示例 5 的页面,把示例 6A 的状态灯和文本框复制过来。保留原 Page Script,在末尾追加下面的只读声明。它覆盖两台设备 × 第 3/5 位四个读位名称;写声明仍只列父 Tag。
- State Color 的 Condition 改为 ReadTagBoolean(selectedControlTag + "[" + selectedBitIndex + "]", false)。
- Tag Text 的 Target tag 改为 =selectedControlTag + "[" + selectedBitIndex + "]";Prefix 改为 "Selected bit = "。开头的 = 只写在目标配置字段中。
- 在运行平台切换 PUMP01/PUMP02 和第 3/5 位,不点击执行按钮,也应看到相应位的读回状态。
Page Script → 示例 6B 页面(追加只读声明)JavaScript
HQVISU_DECLARE_TAGS({
expression: 'selectedControlTag + "[" + selectedBitIndex + "]"',
read: [
"PLC_LINE01.PUMP01.CTRL_WORD[3]", "PLC_LINE01.PUMP01.CTRL_WORD[5]",
"PLC_LINE01.PUMP02.CTRL_WORD[3]", "PLC_LINE01.PUMP02.CTRL_WORD[5]"
]
});
完成标志 显示和执行共用同一组选择;切换选择只更新观察目标,点击执行才提交写入。
如果结果不一致
- 导出报告动态读目标不确定:核对声明 expression 与两个显示行为使用的拼接表达式一致,read 包含四个候选位名称。不要把带 [3]/[5] 的名称加入 write。
示例 7A:按住置位,松开复位
从示例 1 另存一页,给一个新的普通按钮添加 Interactions → Press/Release Script。它没有单独的 Condition;本例固定目标和位号,避免按住期间切换设备。不要给同一个按钮再绑定 Click Script 或 Write Tag Bit。将下列代码只放到 Pointer Press 框。
Press/Release Script → Pointer PressJavaScript
return WriteTagBit("PLC_LINE01.PUMP01.CTRL_WORD", 3, "Set");
完成标志 在运行平台用主指针左键按住按钮后,第 3 位收到 Set 请求。保持按住不会自动重复调用脚本。
如果结果不一致
- 没有触发:确认是在导出的运行平台页面真实按下主指针,而不是 PowerPoint 编辑画布;检查按下请求的运行平台结果。
示例 7B:配置与验证释放动作
在同一个 Press/Release Script 行为的 Pointer Release 框填写下面代码,再保存。释放使用 Reset,不能用 Toggle 代替复位。配上示例 6A 的状态显示,验证按住、松开和移出按钮后松开的结果。
Press/Release Script → Pointer ReleaseJavaScript
return WriteTagBit("PLC_LINE01.PUMP01.CTRL_WORD", 3, "Reset");
完成标志 正常情况下,按下后第 3 位为 1,松开后为 0。运行端还处理匹配指针的 pointercancel 和 lostpointercapture 释放事件;它们不是设备已经复位的证明。
如果结果不一致
- 浏览器退出、页面被销毁、网络中断或运行平台写入结果不确定时,不能保证释放写入到达设备。需要保持或点动控制时,最终复位必须由 PLC 超时、联锁等设备侧机制保证。
设备应用限制
- 按父 Tag 的实际整数位宽选位号:8 位用 0–7,16 位用 0–15,32 位用 0–31。当前位写不支持 64 位父整数。
- WriteTagBit 返回写入结果;画面显示以运行平台读回为准。多个客户端或 PLC 同时改同一父字时,不能把此功能理解成所有协议都保证原子位写入。
- 模板替换、页面变量、页面传参和允许列表各有用途;最终设备写权限、确认和审计由运行平台执行。