# Run on a preparation machine matching the target OS and CPU, with Python 3.13.# Replace the version placeholders with your approved exact versions.python -m pip download --only-binary=:all: --dest ./wheelhouse "psycopg[binary]==<approved-version>" "PyMySQL==<approved-version>"python -m pip hash "<wheel-file>"# Optional local verification in a disposable preparation environment:python -m venv ./dependency-check# Use dependency-check/bin/python (Linux) or dependency-check\Scripts\python.exe (Windows):<venv-python> -m pip install --no-index --find-links=./wheelhouse "psycopg[binary]==<approved-version>" "PyMySQL==<approved-version>"<venv-python> -c "import psycopg, pymysql; print('Dependencies ready')"
复制本地点位 TagRef,直接替换 tags.read(...) 中的 URI 并运行。Run Test 仅从读取调用的字面量授予范围,变量不适用。对照 Tag 测试核对值与质量。tags.read_many([...]) 每次最多 256 个不重复输入,须逐项检查 ok。
准备已在 Tag 测试中显示有效数值的点位,记录其当前值与质量。
从设备目录取得当前本地站点的完整 hq://io/... TagRef;设备名称.Tag 编码与该 URI 是不同表示,不要混填。远端 Tag 不在 Run Test 的本地读取范围内。
在 scripts/ 创建 read_value,把下方 tags.read(...) 引号内的示例 URI 替换成实际 URI。
保存并通过 Run Test 运行 read_value.py,核对 Value 和 Quality。
如果现场值正在变化,以接近的采集时刻比较;先确认质量正常,再判断数值差异。
scripts/read_value.pyPython
# scripts/read_value.pyfrom hqcontrol import tagsdef main(ctx): response = tags.read("hq://io/<io-domain-id>/<device-uid>/<tag-uid>") if not response or response.get("ok") is not True: raise RuntimeError("Tag read failed") snapshot = response["value"] if not tags.is_good_quality(snapshot): raise RuntimeError("Tag quality is not good") print("Value:", snapshot.get("value"), "Quality:", snapshot.get("quality")) return {"value": snapshot.get("value")}if __name__ == "__main__": main({})
完成标志 输出目标值和 good 质量;缺值或质量异常时保留错误状态。
直接调用类型化方法
工作台也提供无需导入的 ReadTagBoolean、ReadTagInteger、ReadTagDouble、ReadTagString、ReadTagJson、ReadTagDateTime、ReadTagQuality 和对应 WriteTag 方法。Run Test 中每次读取的首个参数都应直接填写本地点位名称字面量;变量形式不授予读取范围。ReadTagQuality 将状态归为 good/bad;需要详细质量和时间戳时使用 tags.read。
PythonPython
if ReadTagQuality("<device-code>.<tag-code>") != "good": raise RuntimeError("Tag quality is not good")print(ReadTagDouble("<device-code>.<tag-code>", 0.0))calculated = ReadCalculatedTag("<calculated-tag-code>", None)if calculated is None: raise RuntimeError("Calculated value is unavailable")print(calculated)
11. 保存受控写入方法
保存为 common/tag_control.py。函数从完整读取响应取得 TagRef 和 expected 快照,写入一次并核对状态。0–100 须改为设备允许范围。Run Test 不授予写权限,仅由具备目标读写范围的正式动作调用。
# common/tag_control.pyfrom hqcontrol import tagsdef write_setpoint(read_response, value): if isinstance(value, bool) or not isinstance(value, (int, float)) or not 0 <= value <= 100: raise ValueError("Setpoint must be a number between 0 and 100") if not read_response or read_response.get("ok") is not True: raise RuntimeError("Cannot read the target Tag") tag_ref = read_response.get("tagRef") if not isinstance(tag_ref, str) or not tag_ref.startswith("hq://io/"): raise RuntimeError("Read response has no physical TagRef") snapshot = read_response["value"] if not tags.is_good_quality(snapshot): raise RuntimeError("Target quality is not good") result = tags.write(tag_ref, float(value), value_type="number", reason="Approved setpoint update", expected=snapshot) if (result.get("accepted") is not True or result.get("status") != "done" or result.get("outcomeUncertain") is True or result.get("operatorVerificationRequired") is True or result.get("transportOnly") is True): raise RuntimeError("Verify command " + str(result.get("commandId")) + "; status=" + str(result.get("status")) + "; accepted=" + str(result.get("accepted"))) return result
完成标志 保存完成;调用 write_setpoint 时才写入。
12. 正式动作中的受控写入参考
此入口仅供正式动作使用,Run Test 不授予写入范围。触发上下文须含目标 TagRef,并满足权限、设备和运行条件。