基于HTML5 技术的开放自动化HMI

news/2024/5/4 0:01:30/文章来源:https://blog.csdn.net/yaojiawan/article/details/128436660

        人机交互接口(HMI)是自动化系统中不可或缺的一部分。传统的做法是提供一个HMI 显示屏,并且通过组态软件来配置显示屏的功能,通过modbus 或者以太网与PLC 连接。

       现在,事情变得复杂了许多,用户不仅需要通过专用的HMI 面板操控设备,而且需要使用标准化的设备与设备打交道,比如PC,iPAD 或者智能手机。与此同时,显示屏的性能提升和价格下降,在生产现场和公司管理部门也会安装更多的HMI设备。并且希望显示的内容传统的嵌入式HMI屏更加丰富。

   传统的HMI 屏幕的软件通常是使用windows, QT作为技术平台,使用C#或者C语言实现。嵌入式HMI屏提供的组态工具缺乏足够的灵活性,而且局限性比较大。支持开放性协议的HMI 屏并不多见,例如OPC UA ,MQTT 等协议。

     有一个发展趋势是使用HTML5 技术来构建开放自动化系统中的HMI 管理系统。本文探讨其中的一些技术细节。

HMI 的运行环境

      HMI 管理系统在下列几种平台上运行

  • WebServer

                基于NodeJS 的Web服务器

  • Windows PC HMI应用程序
  • 基于Electron 跨平台HMI

                能够在Android ,Linux ,Windows 平台上运行的HMI

  • 基于嵌入式QT 的HMI
  • 基于Go,C++ 等语言实现的web服务器。

                轻量级的web 可以使用Golang实现

系统架构

以web 服务器为例

         web服务器使用NodeJS 实现,前端UI组件能够使用多种技术实现,为了简单起见,我们使用Jquery /Bootstrap 构建UI组件,也可以使用vue 来构建UI组件。

        使用Web socket 协议的原因是因为Web socket 是一种双向协议,而Restful 是Client/Server协议。事件通信需要双向通信。另外,Web socket 能够实现加密。

 响应式布局

         传统 HMI 的页面设计大多数采用了固定定位的方式实现。但是这种设计方法无法适应多种显示屏。而且要开发一种基于图形化的方式来设计页面的布局并不是一种轻松的工作,需要组态的参数非常多。传统的HMI 通常基于了Windows图形系统实现。灵活性受到限制。而且HMI 页面比较丑陋。比较合适的方式是采用web 页面响应式布局。所谓响应式布局是页面能够根据屏幕的类型自动地调整页面布局。

   bootstrap 支持响应式布局。下面是我们构建的一个HMI 的例子。

 

bootstrap 的栅格技术

Bootstrap包含了一个强大的移动优先的网格系统,它是基于一个12列的布局、有5种响应尺寸(对应不同的屏幕)

  1. xs:超小屏幕 手机 (<768px)
  2. sm:小屏幕 平板 (≥768px)
  3. md:中等屏幕 桌面显示器 (≥992px)
  4. lg:大屏幕 大桌面显示器 (≥1200px)

bootstrap 将屏幕分成容器,行和列。并且将列分成为12等分。

一个页面包含若干个容器

容器内包含了若干行。

行包含若干列。

        与表格不同的是,行内的列并不一定是在一行中排列的。它们从左到右地排列,当超过屏幕时,会自动地转向下一行。因此,在大屏幕上三列的内容,到了中等屏幕可能变成2 列,到了智能手机中,可能便成为一列。这就是所谓的“响应式”设计。

bootstrap的许多技术细节可以参考bootstrap 网站的文档。

组件式HMI

     在我们的设计中,希望HMI 的设计与开放自动化系统中的其它信息模型的构建方式相似,这样能够降低系统的学习难度。具体地讲,就是要与OPC UA 信息系统,IEC61499 功能块,工业4.0 AAS 等模型的构建方式一致。在我们的实验系统中,采取了基于组件的设计方法(Component Based Engineering)。因此,我们需要设计一种web 页面组件化的架构。

   依据Bootstrap 的格栅方案,我们将HMI 按如下分层架构来构建:

  • HMI 的基本组件称为面板(Panel)和UI对象组成。
  • HMI 页面由若干面板组成
  • 面板是可以嵌套的。

根据面板的嵌套关系对应不同的Bootstrap 类

层级

Bootstrap 对象

第一层面板

容器container

第二层面板

第三层面板

UI对象

        从此可见,同样的面板组件,可能是行,也可能是列。它们交替变化。而UIObject 确定是列。 这是一种web 页面组件化的一种简单和有效的方法。可以使用Panel 和UIObject两种主要的组件就能够构建HMI面板。

功能组件与HMI 组件的接口

HMI 是一种信息组件,它们能够与功能组件交互,为了简单起见,功能组件将HMI组件看作为IO资源就可以。而IO服务组件包括:

  • HMI_Configuration
  • HMI_Write
  • HMI_Read
  • HMI_Input 

HMI 服务器中有一个运行时,支持OPC UA ,接口和IEC61499 功能块应用和一些标准功能组件库。

HMI 模型的模板

HMI 模型设计完成后,可以导出HMI模型,它们能够使用XML,JSON 格式描述,下面是一个JSON 描述的文件:

page={"panels":[{   "id":"panel_1","style":"height:280px;background-color: yellowgreen;color:white","title":"参数","panels":[{ "id":"panel_2", "panels":[{"id":"panels_211","style":"height:60px;background-color: blueviolet;color:white","UIObject":{"id":"UI_11","Name":"Temperature","Type":"Text","Value":"32"} },{"id":"panels_212","style":"height:60px;background-color: blue;color:white","UIObject":{"id":"UI_11","Name":"Voltage","Type":"Text","Value":"43"} },{"id":"panels_213","style":"height:60px;background-color: orange;color:white","UIObject":{"id":"UI_11","Name":"Description","Type":"Text","Value":"64"} }]}]},{ "id":"panel_3","style":"height:280px;background-color: red;color:white","title":"Panel2","panels":[{ "id":"panel_4","UIObject":{"id":"UI_2","Name":"Description","Type":"Text","Value":"HTML2 description"}}]},{  "id":"panel_5","style":"height:280px;background-color: blue;","title":"Panel3","panels":[{"id":"panel_6","UIObject":{"id":"UI_3","Name":"Description","Type":"Text","Value":"HTML3 description"}       }]},{ "id":"panel_7","style":"height:280px;background-color: green;","title":"Panel4","panels":[{"id":"panel_8",                 "UIObject":{"id":"UI_4","Name":"温度阀值","Type":"Input","Value":"HTML4 description"}},]},{ "id":"panel_9","style":"height:280px;background-color:gold;","title":"Panel5","panels":[{ "id":"panel_10","UIObject":{"id":"highchart_01","Name":"Description","Type":"guage","Value":"HTML5 description"}}]},{ "id":"panel_11","style":"height:280px;background-color: blueviolet;","title":"Panel6","panels":[{"id":"panel_12",                     "UIObject":{"id":"UI_6","Name":"Description","Type":"Text","Value":"HTML6 description"}},{"id":"panel_12",            "UIObject":{"id":"UI_7","Name":"Description","Type":"Text","Value":"HTML7 description"}},{"id":"panel_12",            "UIObject":{"id":"UI_8","Name":"Setting","Type":"Text","Value":"HTML8 description"}}]},]}

支持的页面

 前端JavaScript 程序

 function LoadUIObject(ParentNodeId,UIObject){if (UIObject.Type=="Text"){$("#"+ParentNodeId).append("<div "+"id="+UIObject.id+">"+UIObject.Value+"</div>");}else if (UIObject.Type=="guage"){$("#"+ParentNodeId).append("<div "+"id="+UIObject.id+" style='height:240px'></div>");guageInit(UIObject.id);} else if (UIObject.Type=="Input"){$("#"+ParentNodeId).append('<div class="input-group mb-3">');$(".input-group").append('<div style="margin:5px">'+UIObject.Name+'</div>');$(".input-group").append('<input type="text" class="form-control" id="name" placeholder="Recipient username" aria-label="Recipient  username" aria-describedby="basic-addon2">') ;                               $("input").append('<input type="text" class="form-control" id="name" placeholder="Recipient username" aria-label="Recipient username" aria-describedby="basic-addon2">')  ;$(".input-group").append('<div class="input-group-append">');$(".input-group-append").append('<button class="btn btn-info" type="button">确认</button>');                                                                  }}function Load(parentNodeId,panels,level){console.log("level:"+level);for (var panel in panels){if(level%2==0){ if (level==0)$("#"+parentNodeId).append("<div "+"id="+panels[panel].id+" class='col-xs-6 col-lg-4 col-md-6 ' style='"+panels[panel].style+"'></div>");else$("#"+parentNodeId).append("<div "+"id="+panels[panel].id+" class='col' style='"+panels[panel].style+"'></div>");}else { $("#"+parentNodeId).append("<div "+"id="+panels[panel].id+" class='row' style='"+panels[panel].style+"'></div>");}if (panels[panel].title)$("#"+panels[panel].id).append("<div class='row' >"+panels[panel].title+" </div>");if (panels[panel].panels!=null){Load(panels[panel].id,panels[panel].panels,level+1);}else if (panels[panel].UIObject!=null) {LoadUIObject(panels[panel].id,panels[panel].UIObject);} }}function guageInit(id){console.log("id="+id);$( '#' +id).highcharts({chart: {type: 'gauge',alignTicks: false,plotBackgroundColor: null,plotBackgroundImage: null,plotBorderWidth: 0,plotShadow: false},title: {text: 'Temperature'},pane: {startAngle: -150,endAngle: 150},yAxis: [{min: 0,max: 200,lineColor: '#339',tickColor: '#339',minorTickColor: '#339',offset: -25,lineWidth: 2,labels: {distance: -20,rotation: 'auto'},tickLength: 5,minorTickLength: 5,endOnTick: false}, {min: 0,max: 124,tickPosition: 'outside',lineColor: '#933',lineWidth: 2,minorTickPosition: 'outside',tickColor: '#933',minorTickColor: '#933',tickLength: 5,minorTickLength: 5,labels: {distance: 12,rotation: 'auto'},offset: -20,endOnTick: false}],series: [{name: 'Speed',data: [80],dataLabels: {formatter: function () {var kmh = this.y,mph = Math.round(kmh * 0.621);return '<span style="color:#339">' + kmh + ' km/h</span><br/>' +'<span style="color:#933">' + mph + ' mph</span>';},backgroundColor: {linearGradient: {x1: 0,y1: 0,x2: 0,y2: 1},stops: [[0, '#DDD'],[1, '#FFF']]}},tooltip: {valueSuffix: ' km/h'}}]}); }console.log("start");console.log(page.panels);Load("top",page.panels,0);

结束语

这是为系统方案做的预研工作,还有许多问题有待研究,例如智能化响应式页面设计。让布局更加符合自动化系统的要求。德国有一家公司Helio 的HMI 做的不错,可惜还没有上市。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_240067.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux共享内存的使用

共享内存可以由多个程序同时访问的内存&#xff0c;能够避免进程间通信过程中的冗余数据拷贝&#xff0c;是IPC中最快的一种,特别适合用来作大块数据的传输。共享内存可以映射到不同的进程空间&#xff0c;这些进程间的数据传递就不再涉及内核。这个过程其实是把同一块物理内存…

FMOC-PEG-COOH,FMOC-PEG-acid,芴甲氧羰基-聚乙二醇-羧基试剂供应

英文名称&#xff1a;FMOC-PEG-COOH&#xff0c;FMOC-PEG-acid 中文名称&#xff1a;芴甲氧羰基-聚乙二醇-羧基 蛋白质、肽和其他材料通过氨基酸或其他酸活性化学组&#xff0c;增加溶解度和稳定性&#xff0c;降低免疫原性&#xff1b;药物修饰或缓释药物研发&#xff0c;新…

ARM_SMMU_下

SMMU驱动代码分析 本文主要分析linux kernel中SMMUv3的代码(drivers/iommu/arm-smmu-v3.c) linux kernel版本是linux 5.7, 体系结构是aarch64 SMMU的作用是把CPU提交给设备的VA地址&#xff0c;直接作为设备发出的地址&#xff0c;变成正确的物理地址&#xff0c;访问到物理内…

[~/vulhub]/log4j/CVE-2021-44228-20221225

[~/vulhub]/log4j/CVE-2021-44228 ┌──(kwkl㉿kwkl)-[~/vulhub] └─$ cd log4j/CVE-2021-44228 ┌──(kwkl㉿kwkl)-[~/vulhub/log4j/CVE-2021-44228] └─$ dir 1.png 2.png docker-compose.yml README.md README.zh-cn.md┌──(kwkl㉿kwkl)-[~/vulhub/log4j/CVE-2021…

_15LeetCode代码随想录算法训练营第十五天-C++二叉树

_15LeetCode代码随想录算法训练营第十五天-C二叉树 题目列表 110.平衡二叉树257.二叉树的所有路径404.左叶子之和 110.平衡二叉树 题目 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a; 一个二叉树每…

SpringBoot-2 读取properties;自动加载127个类原理总结;全部加载,按需配置

读取properties 方式一&#xff1a;非配置类填写&#xff1a;ComponentConfigurationProperties 1)建立bean&#xff1a; /只有在容器中的组件才拥有springboot提供的强大功能 Component ConfigurationProperties(prefix "mycar") public class Car {private Stri…

NetSuite Decode函数

昨天是平安夜&#xff0c;小家伙仍然为圣诞老人的到来准备了礼物&#xff0c;这是他的传统。每年为了感谢圣诞老人和驯鹿的到来&#xff0c;他都会准备上点心、水果。今年&#xff0c;他认为驯鹿可能需要电力&#xff0c;所以准备了电池给它们享用。 真希望天真一直伴随他的成长…

互联网技术不再是统领,当下正在发生着一场深刻的变革

拥抱实体经济&#xff0c;绝对是当下互联网玩家们的首要选择。无论是头部的互联网企业来讲&#xff0c;还是新生的互联网玩家而言&#xff0c;它们都不约而同地将关注的焦点聚焦在了这样一个方向上。   透过这一点&#xff0c;我们可以非常明显地感受到&#xff0c;一个全新的…

蓝桥杯备赛Day4——多维数组

二维数组初始化 p[[0 for i in range(5)] for j in range(2)] #法一 p[[0]*5 for j in range(2)] #法二 s[[1,2,3],[4,5,6]] print(s) for i in range(2):for j in range(3):print(s[i][j],end ) 三维数组初始化 a[[[0 for _ in range(2)] for __ in…

CSDN每日一练最长递增的区间长度 C语言

题目名称&#xff1a;最长递增的区间长度 时间限制&#xff1a;1000ms 内存限制&#xff1a;256M 题目描述 给一个无序数组&#xff0c;求最长递增的区间长度。如&#xff1a;[5,2,3,8,1,9] 最长区间 2,3,8 长度为 3 &#xff08;注意&#xff1a;测试用例仅做参考&#xff0c;…

windows@网络防火墙@软件联网控制

文章目录ref打开防火墙控制面板常用部分限制某个软件联网文档参考具体操作取消控制/禁用第三方软件控制ref (Windows) 创建出站端口规则 | Microsoft LearnWindows Defender Firewall with Advanced Security (Windows) | Microsoft Learn组策略 Windows) 高级安全性的 Window…

二叉树经典算法题目

1.二叉树的前中后序遍历&#xff08;简单&#xff09; 省略 2.二叉树的深度(简单) 输入一棵二叉树的根节点&#xff0c;求该树的深度。从根节点到叶节点依次经过的节点&#xff08;含根、叶节点&#xff09;形成树的一条路径&#xff0c;最长路径的长度为树的深度。 例如&a…

VS coda C++、python运行与Dbug配置

首先新建终端 一次性使用C方法 检查C编译器是否存在 which g可见位置存在于&#xff1a;/usr/bin/g 一次性命令格式&#xff1a; 使用json配置文件 运行C方法&#xff08;推荐&#xff09;&#xff1a; 根据你查找的g的位置来决定 使用配置好的tasks.json&#xff08;C的…

Java window多环境配置

目录JDK版本下载配置内容描述创建JAVA_HOME在Path配置版本切换效果JDK版本下载 Java8 Download address 这个是Java8 的下载地址&#xff0c;下载是要登录的&#xff0c;自己花费一点时间去注册。如果想要下载其它版本的JDK&#xff0c;请看下面的图&#xff0c;然后你就可以看…

SSD_学习笔记记录

one-steage VGG16模型的修改 VGG16的模型输出&#xff0c;其中224.。。为特征图的大小。 SSD模型中对VGG网络的修改&#xff1a; SSD模型是对VGG中的第四个卷积块中的最后一个Conv2d进行第一个输出&#xff0c;在这里简称为Conv4-3。以及第五个卷积块中的最后一个Conv2d进行…

前端开发:Vue封装通过API调用的组件的方法

前言 在前端开发中&#xff0c;关于Vue的使用相比大家并不陌生&#xff0c;而且Vue框架的优势也是其他框架所不能比的&#xff0c;尤其是Vue的封装思想更是堪称一绝&#xff0c;还有就是组件化的运用实践过程也是亮点。所以关于Vue框架的使用想必看官都不陌生&#xff0c;而且常…

干货 | 关于PCB中的“平衡铜”,一文全部说明白

平衡铜是PCB设计的一个重要环节&#xff0c;对PCB上闲置的空间用铜箔进行填充&#xff0c;一般将其设置为地平面。 平衡铜的意义在于&#xff1a; 对信号来说&#xff0c;提供更好的返回路径&#xff0c;提高抗干扰能力&#xff1b;对电源来说&#xff0c;降低阻抗&#xff0c;…

8 NP完全性理论

8 NP完全性理论 p问题 NP问题 NP完全问题 NPC(complete ) NP难问题NP-hard p问题 是一类能够用**(确定的)算法**在多项式时间内求解的可判定问题 ●这种问题类型也称为多项式类型 NP问题 是一类能够用不确定算法在多项式时间内求解的可判定问题 在确定性计算模型下多项式时…

Web前端105天-day64-HTML5_CORE

HTML5CORE04 目录 前言 一、复习 二、WebSocket 三、服务器搭建 四、聊天室 五、defineProperty 5.1.初识defineProperty 5.2.配置多个属性 5.3.可配置 5.4.赋值监听 5.5.练习 5.6.计算属性 总结 前言 HTML5CORE04学习开始 一、复习 SVG: 利用HTML的 DOM 来绘制图…

juc-4-synchronized原理

目录 1、synchronized 作用于静态方法 总结 ​编辑 案例 静态成员变量 (synchronized锁非静态方法) 案例 静态成员变量 (synchronized锁静态方法 或 直接锁类) 2、监视器锁(monitor) 2.1 synchronized怎么实现的线程安全呢&#xff1f; 3、JDK6 synchronized 的优化 3.1 C…