ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

AVEVA系统平台界面定制:用模板与对象模型告别硬编码HMI

AVEVA系统平台界面定制:用模板与对象模型告别硬编码HMI 简介在工业数字化领域AVEVA System Platform作为主流集成平台其界面定制与开发教程面向工业软件实施工程师与二次开发人员帮助读者掌握从架构认知、仪表板设计到自定义应用及系统集成的完整路径。资源包内含1个docx文档大小约40KB便于随时查阅和传播文档系统梳理了平台主要组件、数据模型与统一框架并结合实际案例说明定制前的准备、常用界面控件使用以及Python与PI服务器交互的代码示例。对于需要为AVEVA平台做界面优化、业务看板开发或外部系统对接的读者可直接对照学习。目前已有86人学习下载适合正在接触AVEVA系统平台、希望快速建立定制开发思路的初中级工业软件工程师。全文结构清晰从基础概念到实践步骤循序渐进能有效缩短上手时间并降低试错成本。1. AVEVA系统平台界面定制到底在做什么别再硬编码你的HMI前阵子一个朋友的项目快验收了甲方提了个不算过分的需求某个设备状态框要从红色改成黄色异常时再闪三下。他在 InTouch 画面里找到那个图元改完动画链接保存、发布、重启 ViewApp结果第二天一看换了另一个设备实例颜色又不对了。问题出在他改的是“这一张画面”而系统里跑的是同一套模板下的上百个对象实例。AVEVA系统平台界面定制要解决的就是把界面从一组硬编码的按钮、颜色、数据链接里解放出来数据从 ArchestrA 对象来画面只负责把对象的属性投影出来改一处模板所有实例跟着变。这不是单纯“美化界面”而是把 HMI 的维护成本打下来的工程手段。这套东西适合三类人做实施交付的工程师、系统集成商里的二次开发人员、甲方负责运维和深化应用的工程师。后面按我实际干活的顺序从架构聊到代码再讲翻车记录。2. 定制先定架构ArchestrA对象模型与界面解耦界面定制失败的项目多数不是不会画图而是对象模型没立住。很多人第一次打开 AVEVA System Platform原 Wonderware 的 System Platform第一反应是“这不就是一个组态软件吗”于是直奔 InTouch 画画面等到后面要批量维护的时候才发现每一张画面都是孤岛。真正能撑住后续定制的是先理解 ArchestrA 这套对象模型再用它把界面和数据解耦。2.1 界面只是投影模板、实例、属性三层拆解ArchestrA 的核心运行环境叫 Galaxy所有对象都跑在 Application Server 上。你先在 IDE 里定义模板Template模板规定了结构和默认行为比如“离心泵模板”有运行状态、出口压力、远程启动这些属性再由模板生成实例Instance实例是现场具体的设备比如 P-101 泵实例上真正变的是属性Property的值。界面上的图元Symbol不存数据它只是属性的投影。很多人会把这三层混在一起。最常见的错误是直接在画面上放一个静态文本框把设备号写死再把数据源指向某个 OPC 点。这样做单个画面确实快但设备一多、点位一调整维护成本直接爆炸。更合理的方式是把画面里的图元做成模板图元上用“当前实例”这种相对引用运行时由平台自动解析到具体对象。这样新增一台设备只需要新建实例画面不用动。点对点绑定和基于模板的绑定差别很直观我整理了个表对比项点对点绑定硬编码基于模板绑定数据来源画面标记名直接指向具体设备点图元引用当前实例的通用属性新增设备复制画面、重新链接、逐个改新建对象实例画面自动匹配改样式或逻辑每张画面逐张改改模板一处重新发布运行期追踪链路藏在几十个动画链接里Object Viewer 里一眼看到对象值这个差别就是我说的“界面只是投影”的含义。界面定制如果从架构上就选了硬编码后面不管你脚本写得再好、控件做得再精致维护成本都压不下来。所以做 AVEVA系统平台界面定制第一步不是打开画面编辑器而是先在 IDE 里把对象模型理清楚。2.2 先建对象后画画面Galaxy初始化与最小模板创建步骤我一般会按下面这套最小操作建一个设备模板。装完 System Platform 后先用 Galaxy Management Console 新建一个 Galaxy这一步要定的主要是认证方式和运行用户。认证方式默认用 Windows 集成认证对实施项目来说最省事运行用户建议单独建一个服务账号不要拿管理员账号跑运行环境后面安全策略调整时你会感谢这个决定。接着打开 ArchestrA IDE连接到刚建的 Galaxy。在模型视图里新建一个设备模板然后添加属性。属性是后面所有绑定的基础我的习惯是把属性分三类状态类只读、控制类可读写、统计类只读。以离心泵为例属性名数据类型读写权限初始值说明RunStatusBooleanReadOnlyFalse运行状态来自 OPCRemoteStartBooleanReadWriteFalse远程启动命令界面可写TotalRunHoursInt32ReadOnly0累计运行时间LastAlarmTimeDateTimeReadOnly空最近报警时间属性建好后先导出模型做一次目检再创建实例。不要一上来就建实例模板结构错了后面所有实例都要跟着返工。导出后你会看到类似下面的结构字段按工程习惯梳理过不是平台原始导出文件!-- 模板对象导出的结构示意重点核对属性名、数据类型、读写权限 -- ObjectTemplate NameDevicePump TypeDevice Properties Property NameRunStatus DataTypeBoolean AccessReadOnly InitValueFalse/ Property NameRemoteStart DataTypeBoolean AccessReadWrite InitValueFalse/ Property NameTotalRunHours DataTypeInt32 AccessReadOnly InitValue0/ Property NameLastAlarmTime DataTypeDateTime AccessReadOnly/ /Properties Scripts !-- 这里放置对象端脚本只放数据逻辑不放界面显隐逻辑 -- /Scripts /ObjectTemplate这里逻辑说明一下导出的 XML 里DataType 和 Access 是最核心的两个字段。DataType 写错了画面上显示的类型会截断数值Access 写错了按钮写属性会被运行时拒绝。平台里经常出现“按钮点了没反应”的问题一半以上是这里 Access 设成了 ReadOnly。脚本区域的原则是对象端脚本只做数据处理和跨系统通信界面显隐、颜色变化这类视觉逻辑不要放进来否则部署时会把一个纯数据对象变成界面耦合对象。模型目检通过后创建 P-101、P-102 两个实例各自填初始值然后 Deploy 到运行环境。这一步做完你才有第一批可以被画面绑定的数据。2.3 把图元绑定到对象接入点、标记名和#引用的用法对象部署完接下来才是画面侧。在 System Platform 里画面应用InTouch 应用通过“接入点”Access Node指向 Application Server。新手容易在这里漏一步建了应用但不配接入点画面里的数据源全是空的。接入点配置好后在 InTouch 标记名数据库里新建标记标记名对应“对象.属性”比如 P101.RunStatus。我习惯把标记名命名规范和对象属性名保持一致不要另起一套中文别名否则后期排查数据链路时对不上。画布上放图元后动画链接里直接引用这个标记名。再进一步如果做的是可复用模板图元就不要写具体对象名用 # 代表当前实例比如 #.RunStatus。这个 # 引用是整个模板化画面的关键# 当前实例引用模板图元标准写法 数据源: #.RunStatus 闪烁条件: #.AlarmActive TRUE 颜色条件: #.RunStatus FALSE ? 灰色 : #.AlarmActive ? 红 : 绿 # 具体实例引用单点画面才用 数据源: P101.RunStatus参数说明在这里要讲清楚模板图元里必须用 #这样同一个图元放到 P-101 和 P-102 上解析出来的是完全不同的两个数据源。如果你在模板图元里硬写了 P101那 P-102 画面上永远显示的是 P101 的值。有 AVEVA 设计端经验的人应该眼熟——AVEVA PML 里做界面动作用的是 !! 和 % 引用符号和这里 # 的定位类似但语法完全不同别把两套引用混着写。在 System Platform 里模板化就是靠 # 撑起来的。3. 用脚本把画面盘活QuickScript关键写法与三个必调参数对象和画面绑定打通后界面能显示数据了但还不会“动”。按钮点击、条件显隐、报警闪烁这些交互靠脚本实现。这里最大的误区是一上来就写复杂脚本动不动几十行把界面脚本当成业务逻辑仓库。脚本在 AVEVA系统平台界面定制里是调味料不是主菜。主菜始终是对象模型和数据绑定脚本只在需要表达交互意图时才出现。3.1 QuickScript和C#脚本怎么选超过50行就往下沉经典 InTouch 环境里有两套脚本体系QuickScript类 VB 语法和 C# 风格脚本ArchestrA 图形里用的。两者边界很清楚。按钮置数、颜色变化、窗口切换这类轻交互用 QuickScript它和标记名深度绑定写起来最快复杂算法、调用外部 SDK、批量数据整理用 C# 脚本或者干脆下沉到 ArchestrA 对象脚本里执行。我给自己定了一条线界面脚本超过 50 行就要考虑把逻辑挪到对象方法里。道理很简单界面脚本的生命周期和窗口绑定窗口关了脚本就没了而对象脚本跑在 Application Server 上有完整的调度、重试和日志。把业务逻辑放在界面层等于把系统的稳定性押在操作员会不会误关窗口上。选型的时候可以参考这个表场景推荐写法理由按钮写对象属性QuickScript两行搞定和标记名绑定自然窗口打开时初始化QuickScript生命周期短适合一次性的初始化动作跨系统 REST 调用C# 脚本或对象脚本要处理连接池、超时、异常批量修改多个对象属性ArchestrA 对象方法可以在引擎端执行不依赖界面3.2 设备启停控制画面按钮脚本、颜色动画和报警闪烁拿刚才的 DevicePump 模板做一张操作画面。画面上放启动按钮、停止按钮、运行指示、报警指示。启动按钮的触发动作脚本写在 LeftMouseUp 事件里QuickScript 写法 启动按钮 LeftMouseUp 事件 P101.RemoteStart 是 InTouch 标记名对应 ArchestrA 对象属性 P101.RemoteStart TRUE LogMessage(ODS:ACTION, 操作员 $OperatorName 远程启动 P101, 1)停止按钮对应P101.RemoteStart FALSE逻辑对称。这里有个细节值得单独说为什么用 LeftMouseUp 不用 LeftMouseDown。操作类按钮用 Up允许操作员在按下的瞬间反悔划走误触概率低用 Down 响应快但工业现场误触一次可能就是一条报警。确认类操作还要加一个二次确认弹窗这是行业的常规要求。动画绑定部分运行指示用颜色动画报警指示用闪烁动画。表达式设置在动画链接里颜色动画: P101.RunStatus FALSE ? 灰色 : #.AlarmActive ? 红色 : 绿色 闪烁动画: #.AlarmActive TRUE逻辑说明这个写法把三种状态压缩在一个表达式里减少动画链接数量。运行时表达式的值变化会触发图元刷新不需要额外脚本。这里参数的关键点是动画表达式里属性名必须和标记名完全一致大小写都不能差模板模式下优先用 # 开头避免表达式在实例复制后失效。3.3 三个必调参数触发事件、扫描周期和执行上下文脚本能不能稳定跑和业务逻辑关系不大反而是三个参数决定生死。第一个是触发事件。按钮类选 LeftMouseUp 我已说过数据变化类选“值变化触发”而不是时间触发很多卡顿就是因为在用时间轮询的方式检查一个几小时才变一次的值。第二个是扫描周期。如果是周期型脚本默认 1 秒刷新通常太激进。页面图元多、客户机配置一般我会把周期调整到 3 到 5 秒只有需要实时反馈的数值比如电流、温度曲线才单独设 1 秒。全局脚本里尤其要克制一个全局周期脚本每 1 秒扫描一遍全部对象十几个画面全开客户机 CPU 必然飙高。第三个是执行上下文。QuickScript 分全局脚本、窗口脚本、标记事件脚本作用域完全不同。新手常犯的错误是把窗口初始化逻辑放在全局脚本里结果每个窗口打开都执行一遍数据被反复覆盖。我的原则是窗口脚本只干窗口自己的事全局脚本只放跨窗口的公共逻辑比如操作员登录状态同步。3.4 脚本出问题先看日志LogMessage定位三段链路System Platform 的脚本调试能力比现代开发工具弱得多QuickScript 没有单步调试器脚本跑没跑、跑到哪一行全靠日志。我在关键动作里都会写 LogMessage这是最朴素的“打桩”。上面的启动脚本里那行 LogMessage 就是干这个用的。日志查的时候分三段看第一段在 InTouch 的日志查看器里看标记事件脚本有没有触发第二段去 Galaxy Management 看对象属性有没有收到写入第三段看 Application Server 日志里对象方法有没有抛异常。三段对上了链路才通。排查三段链路: 1. InTouch 日志: 脚本是否触发、标记名是否有效 2. 对象属性: Object Viewer 里 RemoteStart 是否变成 TRUE 3. 引擎日志: 对象端脚本是否正常执行如果第三段报了异常拿异常堆栈去搜比猜快得多。不要相信“重启一下就好了”重启只能解决缓存类问题解决不了逻辑错误。4. 图元不够就上控件.NET自定义控件从代码到发布脚本解决交互但界面上有些东西脚本画不出来复杂表格、甘特图、专业趋势组件、自定义输入表单。默认图元库在这些场景下很吃力硬用基础图元拼界面卡、维护难。这时候就该写自定义控件。很多人把这个想得很玄其实就是做一个小型 .NET 程序集嵌入到系统平台的画面容器里数据由平台喂给它它只负责把数据呈现出来。4.1 什么时候该写自定义控件默认图元做不到的三种场景我判断要不要写控件就三条默认图元做不出的、做出来交互太别扭的、同一个功能要用在五个以上画面的。典型如报警统计列表默认图元只能一行一行摆排序、筛选、分页全要手动做用自定义表格控件一次搞定。技术选型上要区分平台版本。经典 InTouch 环境通过 ActiveX 容器嵌控件用 WinForms UserControl 最稳妥新版 AVEVA InTouch Unlimited、Operations Hub 这类 Web 端界面则走 REST API 加自定义 HTML 组件。规划阶段先确认现场用的是哪一套不要一上来就做 WPF 控件WPF 在 ActiveX 容器里的互操作问题很多资源加载、输入焦点都容易出幺蛾子。如果是新项目我更倾向于先用平台原生能力把自定义控件留到确实过不去的场景因为控件是要维护的代码资产。4.2 写一个报警摘要控件WinForms骨架与运行参数下面这个报警摘要控件的骨架是从一个实际项目里抽出来的。它只做一件事定时从数据源拉报警列表显示在一个表格里。完整代码由你按实际数据接入方式补充这里给的是稳定的骨架// AlarmSummaryControl.csWinForms UserControl 骨架 using System; using System.Windows.Forms; public partial class AlarmSummaryControl : UserControl { public string ObjectSource { get; set; } // 由嵌入方传入如 P101,P102 private Timer _refreshTimer; public AlarmSummaryControl() { InitializeComponent(); _refreshTimer new Timer { Interval 5000 }; _refreshTimer.Tick (s, e) RefreshAlarms(); _refreshTimer.Start(); } private void RefreshAlarms() { // 调用 AVEVA 历史库或实时库接口拉取 ObjectSource 范围内的报警 // 填充到控件内的 DataGridView只做展示不做写操作 } }逻辑说明控件里放一个 Timer 每 5 秒刷新一次而不是让外界反复触发重绘。5 秒对报警列表足够工业界面不需要秒级刷新写操作一律不放在控件里权限全部由平台的 ArchestrA 对象安全体系去管控件只做只读展示这是安全边界。ObjectSource 属性由嵌入方传入是为了让同一个 DLL 可以复用在不同的画面上不需要每换一组设备就重编一版。4.3 注册和分发DLL进画面要过的三道门控件编译出来只是个 DLL要进系统平台的画面得过三道门。第一道是程序集签名生成 DLL 时勾选强签名否则目标机器加载 .NET 控件可能直接被拒。第二道是在目标机器上注册经典 InTouch 环境下要用 RegAsm 注册成 COM 组件命令如下C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe AlarmSummaryControl.dll /codebase /tlb参数说明/codebase 告诉运行时从注册表里找当前路径不用装到 GAC方便项目期反复替换 DLL/tlb 生成类型库ActiveX 容器才能识别控件的接口。如果你想让这台机器上的所有工程通用这个控件再把它装进 GAC但我一般建议先 /codebase等版本稳定了再进 GAC省得升级时清不干净。第三道门是分发。System Platform 支持通过 SMS 把控件部署到多台客户机不要手动一台一台去注册。项目交付时把 DLL、注册命令、使用说明打包成一份文档现场照着执行能少接很多电话。这里有个很容易踩的坑开发机上控件运行正常一发布到现场就红叉。绝大多数原因是开发机装过 Visual Studio机器上 .NET Framework 组件齐全现场机器没有所以分发包里要把运行库组件带齐。4.4 新版Web端控件集成REST API与经典环境的差异如果你做的项目是新版 Web 端界面上面的 WinForms 路线不适用改成 REST API 加前端组件。平台暴露接口后前端用 fetch 直接拉数据渲染交给组件库。写法和做前端开发教程里的常规做法类似但认证逻辑要按平台的令牌体系来// 新版 AVEVA Web 界面里拉报警列表的示例 const res await fetch(/aveva/api/alarmlist?area${areaId}from${fromTime}, { headers: { Authorization: Bearer ${await getToken()} } }); const list await res.json(); renderTable(list);这个写法只适用于新版 Web 架构经典 InTouch 环境里没有这个入口。做跨版本支持时我习惯先问清楚现场的部署版本再决定走 ActiveX 还是 REST别拿新版方案套旧环境那是翻车的重灾区。5. 界面定制避坑5个高频翻车点和排查路径界面定制做得多了会发现翻车来来回回就那么几类。我把高频问题整理成五条每条按现象、原因、解决三段写这是我自己排查时走的顺序。5.1 画面显示旧值部署成功但缓存和接入点没跟上现象IDE 里改了模板属性默认值Deploy 成功确认过没有报错但打开 ViewApp 后画面显示的数值还是原来的。原因三个地方都有可能。一是对象运行时的缓存没有刷新二是 InTouch 标记名的 ArchestrA 访问节点没有重连画面上连的还是旧接入点三是 ViewApp 的本地缓存没有清理加载的还是旧画面包。解决先在 Object Viewer 里看对象属性运行时值如果运行时值是对的问题就在画面侧再查 ViewApp 接入点配置确认指向当前的 Application Server最后做一次强制发布清掉本地缓存再启动。我遇到过的案例里接入点配置错误占比最高因为换机器时最容易漏改这里。5.2 .NET控件加载失败十字叉、程序集路径和版本三连查现象画面能正常打开但控件位置是红叉或者灰块客户端事件日志报“无法加载程序集”。原因目标机器没注册控件、.NET Framework 版本不匹配、DLL 不在探测路径里。这三个原因经常同时存在。解决按顺序查。先确认目标机器装了 .NET Framework 4.x 而不是 .NET Core这块平台不认再用第 4 章的 RegAsm 命令重新注册确认 /codebase 参数没漏最后检查 DLL 是否放在 InTouch 程序的私有目录里或者已注册到 GAC。我自己的习惯是控件升级后第一时间被测试机验证而不是直接上生产机否则红叉会出现在用户眼前。5.3 脚本把CPU拉满周期脚本和写操作的隐形循环现象某窗口打开后客户机 CPU 持续飙高其他画面切换都卡关掉窗口后恢复正常。原因窗口脚本里放了周期执行逻辑脚本里又写了对象属性属性变化触发了另一个脚本那个脚本又写回同一属性形成隐形循环。这种循环在 IDE 里不看运行时监控很难发现。解决打开脚本编辑器把时间触发的周期脚本改成数据变化触发检查脚本里是否有对同一个属性反复写入的代码。界面脚本只读属性、不下发命令这个原则能避开大部分循环。如果循环逻辑确实需要放在界面侧至少加一个防抖标志位值变化但结果相同时不继续执行。5.4 对象被签出锁死多人协同下的IDE排他机制现象A 工程师在 ArchestrA IDE 里改了模板B 工程师在另一台电脑上发布时提示“对象被签出”无法部署。原因ArchestrA IDE 的签出机制默认是排他的A 改了模板没有签入整个 Galaxy 里这个模板就被锁住了。解决联系 A 撤销签出或者由管理员在 Galaxy Management Console 里强制释放对象锁。但强制释放有风险未保存的修改会丢所以规范做法是下班前把不需要改的对象全部签入并在项目组里约定模板对象由专人改其他人只改实例参数。这个问题在项目冲刺阶段最容易爆影响范围是整个发布流程。5.5 换服务器绑定全断Galaxy迁移时的接入点清单现象从开发环境把工程导入到生产机后所有画面数据源变成问号标记名全部失效。原因机器的服务名、IP、安全上下文都变了画面里的接入点字符串还停留在开发机状态。Galaxy 导入导出工具不会自动帮你改接入点。解决迁移前导出模型做一个接入点清单列出哪个应用连哪个 Application Server迁移后逐个更新接入点再对画面标记名做批量替换。这里不要手动改用脚本批量替换服务名能少很多事。操作顺序上先改接入点再导入模型最后发布可以避免中间状态污染运行时环境。6. 用数值追踪做端到端验收一个数据源到底的核对技巧界面开发完怎么验收别只看画面好不好看要看一条数据从源头到画面每一步都在不在。我每次做界面定制交付前都会做一次端到端数值核对三步走。第一步在数据源头造一个测试值。模拟量就写一个斜波或者固定值开关量就强制置位一次用平台自带的 Simulation 对象最省事。第二步打开 Object Viewer看对象属性实时值确认数据确实进到了 ArchestrA 对象这一层。第三步回到画面看图元上显示的值。三步一致性对了数据链路才是通的。核对环节怎么查常见异常信号数据源头Simulator / OPC 客户端值一直不动源头就没数据ArchestrA 对象Object Viewer源头有值属性没变查通讯配置InTouch 标记名Tag Browser值变了但类型截断查标记名类型图元动画链接打开动画绑定属性绑定项写错属性名查动画表达式我有一个养成的习惯在对象模板里加一个专门用于验收的 DiagnosticValue 属性界面上留一个很小的调试文本显示它交付验证时直接对比这个值和现场表计读数验收完再隐藏。这个值平时不参与业务逻辑只做链路校验很多扯皮都能省掉。界面定制这件事最后拼的不是画图技巧是这一套从数据源头查到界面末端的耐心。希望帮到你。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进