zoukankan      html  css  js  c++  java
  • WEB组态可视化软件(B/S)

    WEB组态可视化软件

    1 B/S组态软件

    它是一个独立的产品,包含编辑器(设计时)和运行环境(运行时)两大模块,我们将其命名为——WEB组态可视化软件(下称“组态软件”)。

    2 组态概念

    组态(Configure)的概念来自于20世纪70年代中期出现的第一代集散控制系统(Distributed Control System),可以理解为“配置”、“设定”、“设置”等,是指通过人机开发界面,用类似“搭积木”的简单方式来搭建软件功能,而不需要编写计算机程序。我们也可称之为“二次开发”,组态软件即为“二次开发平台”。

    3 组态产品呈现

    组态软件是个怎样的产品?
    先做一个概述:组态软件通过浏览器操作组态工具、浏览组态画面,实现工程管理、组态编辑以及组态运行三大功能。通过实现图元组态、可视化图表组态、数据库组态的配置与关联,完成基于Web服务的实时数据监控与服务端的多用户访问等。

    从用户操作与界面呈现的角度来说,组态软件采用标准HTML5技术,基于B/S架构进行开发,支持Web端呈现,在浏览器端即可完成便捷的人机交互,简单的拖拽即可完成可视化页面的编排设计。此外,由于组态软件功能较为复杂,为降低使用门槛,组态软件进行了模块集成化,旨在简化用户的操作步骤,提高用户的工作效率。

    从软件架构来说,组态软件具备高度的开放性。随着应用场景的逐渐增加,软件必然需要进行功能扩展,因此,组态软件不仅支持多种数据接口,也提供了二次开发接口,可以由用户自行完成二次开发。组态软件在功能上集成了大量通用模块和个性化模块,以实现不同行业用户的需求。针对具体的用户,软件支持定制化模块的开发与配置,实现“即插即用“。

    软件的运行逻辑并不复杂,除了基础的组态管理外,主要可分为组态编辑和组态运行两个部分。用户需要在组态编辑环境中使用组态软件提供的组态功能(图元、图表、数据库)进行组态设置、建立网络拓扑、绘制数据显示界面、配置各种系统参数(如数据采集频率)等;然后在组态运行环境中运行已经组态好的应用系统,包括数据实时监控、场景展示等。

    两者之间的关系如图所示:

    4 功能特点

    • 基于html5,B/S架构
    • 支持 2D、2.5D、3D多种呈现模式
    • 可视化拖拽编辑、简单易用
    • 支持云端/本地等部署方式,多终端使用
    • 提供丰富的行业标准元器件图元库
    • 提供行业模板和组件,支持自定义模板和图纸管理
    • 提供定制开发服务
    • 支持Http、WebSocket等主流协议,支持扩展更多协议
    • 支持嵌入第三方系统或者集成平台,也可作为独立平台
    • 具备延续性、可扩展性、封装性(易学易用)、通用性、开放性
    • 周密的系统安全防范

    软件主要功能模块有组态管理、组态编辑、组态运行三大模块:

    1. 组态管理

    管理模块的详细功能与其他软件大同小异,系统管理通过分级权限保障系统的安全;工程管理则是对组态文件的建立、提交、删除、恢复等基本操作提供入口。
    2. 组态编辑

    本模块是组态软件的核心模块,软件绝大部分操作都在这一个模块里面进行。

    主要操作对象有画布、图元、可视化图表以及数据库。针对画布与图元这类基础对象,软件提供诸如调整尺寸、属性、复制、粘贴、增删、合并、拆分、绑定跳转页面/事件等操作,搭建可视化页面的基础架构。

    可视化图表是页面展示的主要形式,因此,除了针对图元的基本操作之外,软件还提供了样式设计、文本属性以及运行参数设置,确保图表在可视化页面的展示效果。

    数据库作为系统的数据源,需要与组态形成关联,为组态提供数据。软件支持配置组态关联的数据库信息、绑定图元/可视化图表对应实时/历史数据源、设置图元/可视化图表数据源触发事件等功能。


    1. 组态运行

    本模块将为各类应用场景提供实际的运行功能,具体如下所示:

    • 解析组态画面编辑文件
    • 绘制动态实时监控页面
    • 关联图元及可视化图表数据源
    • 可视化图表数据导出
    • 网络通信检测
    • 设置可视化图表运行参数
    • 失效数据检测处理等

    5 组态软件应用场景

    组态软件的出现,为解决实际工程问题提供了一种崭新的方法,用户通过类似“搭积木”的简单方式来完成自己所需要的软件功能,不需要编辑计算机程序。组态软件能够很好地解决各类场景中存在的种种问题,使用户能根据自己的管理对象和管理目的的任意组态,完成最终的场景控制自动化、数据可视化。主要适应场景如下:

    • 配电
    • 工业(控制)
    • 智能楼宇
    • 变电站管理
    • 电厂电气
    • 配电室监控
    • 冶金工艺流程控制
    • 水力自动控制
    • 石油智能控制系统等

    6 经典的案例

    6.1 某通信基站的组态可视化

    本项目采用2.5D的形式进行可视化展示,2.5D技术使用三维建模方式,构建立体效果,同时增加了2D的光照和2D各种方法,系统的功能具有很好的延展性。系统在项目中可以进行数据结构更换、tips效果优化、选中效果、设备告警、油箱动态油量显示、油机开关机功能,支持自动布局多种布局方式,可进行接口对接,支持基站多设备的添加,设备基本信息的查看等功能。

    7 具体实现

    7.1 设计时

    7.1.1 表单输入

    基于HTML5进行表单输入,前端给ui打上id标签

    <li data-cIndex='16'><img src="./images/icons/door.png" class="CNicons" alt=""><a id="a_16"   class=" controlName" group="">门禁</a></li>
    
    
    <tr id="tr_i_DoorState" style=" display:none;">
    	<td></td>
    	<td class="txt i_attrName">门状态点</td>
    	<td class="txt">
    	   <input type="text" id="i_DoorState" name="DoorState" style="150px;">
    	</td>
    </tr>
    <tr id="tr_i_OpenStateValue" style=" display:none;">
    	<td></td>
    	<td class="txt i_attrName">门打开值</td>
    	<td class="txt">
    		<select id="i_OpenStateValue" name="openValue">
    			<option value="0">0</option>
    			<option value="1">1</option>
    		</select>
    	</td>
    </tr>
    <tr id="tr_i_OpenDoorState" style=" display:none;">
    	<td></td>
    	<td class="txt i_attrName">开门控制点</td>
    	<td class="txt">
    		<input type="text" id="i_OpenDoorState" name="OpenDoorState" style="150px;">
    	</td>
    </tr>
    <tr id="tr_i_linkdeviceid" style=" display:none;">
    	<td></td>
    	<td class="txt" id="td_i_linkdeviceid_tit">联动点</td>
    	<td class="txt i_attrName">
    		<input id="i_linkdeviceid" class="input0" value="" style="150px;">
    	</td>
    </tr>
    <tr id="tr_i_CardReader" style=" display:none;">
    	<td></td>
    	<td class="txt" id="td1">读头</td>
    	<td class="txt i_attrName">
    		<input id="i_CardReader" name="CardReader" class="input0" value="" style="150px;">
    	</td>
    </tr>
    
    
    

    7.1.2 js脚本

    根据id,通过js来面向dom元素编程,如果时vue,angular,react则直接可绑定数据,面向数据编程。通过js来对拖动,点击,修改,保存等事件进行编程;

    	//门状态点
    	$('#i_DoorState').focus(function(){
    		var stateName = $(this).attr('name');
    		selectDevState(stateName);
    	});
    	//门打开控制点
    	$('#i_OpenDoorState').focus(function(){
    		var stateName = $(this).attr('name');
    		selectDevState(stateName);
    	});
    	//读头
    	$('#i_CardReader').focus(function(){
    		var stateName = $(this).attr('name');
    		selectDevState(stateName);
    	});
    
    				else if(devIndex==16){//门禁
    					$('#tr_i_OpenStateValue').show();
    					$('#tr_i_DoorState').show();
    					$('#tr_i_OpenDoorState').show();
    					$('#tr_i_CardReader').show();
    

    如,如下保存点击事件可保存配置属性成json,生成json文件或者post给后台服务加载到数据库。

    $('#a_save').click(function(){
    	var row = $('#MonitoringSiteTable').datagri('getSelected');
    	if(row){
    		var devArr= $('.dev');
    		for(var i=0;i<devArr.length;i++){
    			if(devArr.eq(i).css('outline-style'!=='none'){
    				var upId = devArr.eq(i).attr('id');
    				switch(stateName){
    					case 'devname':
    						$('#i_deviceid').val(rowdevname);
    						deviced[upId].devname=rowdevname;
    						if(deviced[upId].devIndex==8){
    							
    							var txt = textShowMod(upId);	
    							var textID = 'p'+upI+'img';
    							$('#'+textID).text(txt)css({color:deviced[upId]fontColor});
    							textAlign(devId);
    						}else if(deviced[upId]devIndex==14){
    							devArr.eq(i).find('span')text(row.devname).css{color:'#555'display:'inline-block'position:'absolute'bottom:'10px'});
    						}else if(deviced[upId]devIndex==5){
    							moniShowMode(upId);
    							var textID = 'p'+upI+'img';
    							$('#'+textID).css{color:deviced[upId]fontColor});
    						}else if(deviced[upId]devIndex==15){
    							devArr.eq(i).find('span')text(row.devname).css{color:'#555'position:'absolute'bottom:'10px',left:'0px'};
    						}
    						break;
    					case 'OpenDoorState':
    						$('#i_OpenDoorState').val(rowdevname);
    						deviced[upId].OpenDoorState =row.devname;
    						break;
    					case 'DoorState':
    						$('#i_DoorState').val(rowdevname);
    						deviced[upId].DoorState = rowdevname;
    						break;
    					case 'CardReader':
    						$('#i_CardReader').val(rowdevname);
    						deviced[upId].CardReader =row.devname;
    						break;
    					case 'linkorgid':
    						$('#i_linkorgid').val(roworgname);
    						deviced[upId].linkorgid=roworgname;
    						break;
    

    7.2 运行时

    7.2.1 前端给ui打上id标签

    	<div id="centerTabs" class="easyui-tabs" style="100%;height:100%;">
    		<div title="组态图设计" id="contentBox" data-options="closable:false" style="padding:4px;position:relative;">
    			<div id="resizeBox" style="position:relative;100%;height:100%;z-index:2;border:1px solid #ccc;overflow:hidden;" data-Box="bgBox"></div>
    		</div>
    		<div title="预览" data-options="closable:false" style="padding:4px;position:relative;" id="previewBox">
    			
    		</div>
    	</div>
    

    7.2.2 js脚本

    需要先从数据库或者*.json加载控件的配置数据,来展现完成的控件属性,然后去对应的后台接口,或者devicedata.json(后台服务生成),来更新当前设备的实时数据。
    定时刷新设备实时数据,其余定时刷新实时数据的代码太长,这里不粘贴,自行补全。

    	//预览
    	$('#centerTabs').tabs({
    		onSelect:function(title,index){
    			if(title=="预览"){
    				preview();
    			}else if(title=="组态图设计"){
    				clearInterval(intervalId);
    				if($('.video').length>0){
    					var video = $('.video').eq(0);
    					$('#resizeBox').append(video);
    					var devId = video.attr('id');
    					video.css('outline-style',deviced[devId].outlineStyle);
    					if(video.css('outline-style')!=='none'){
    						$('#'+devId+'img').show();
    					}
    					$('#'+devId).resizable({
    						disabled:false
    					});
    					deviced[devId].ocx.DisConnectAllChannel();
    				}else if($('.chart').length>0){
    					var chart = $('.chart');
    					for(var j=0;j<chart.length;j++){
    						$('#resizeBox').append(chart.eq(j));
    						var devId = chart.eq(j).attr('id');
    						chart.eq(j).css('outline-style',deviced[devId].outlineStyle);
    						$('#'+devId).resizable({
    							disabled:false
    						});
    					}
    				}
    				$('#previewBox').empty();
    				for(var i in deviced){
    					if(deviced[i].devIndex==14){
    						deviced[i].option.series[0].data[0].value=50;
    						deviced[i].Chart = echarts.init(document.getElementById(i+'img')); 
    						deviced[i].Chart .setOption(deviced[i].option,true);
    					}else if(deviced[i].devIndex==15){
    						deviced[i].dial = new canvasPanel();
    						deviced[i].dial.bgColor = deviced[i].panelColor;
    						deviced[i].dial.splitNum = deviced[i].lineValue;
    						deviced[i].dial.MaxNum=parseInt(deviced[i].dmaxvalue);
    						deviced[i].dial.MinNum = parseInt(deviced[i].dminvalue);
    						deviced[i].dial.init(i+'img');
    					}else if(deviced[i].devIndex==24){
    						deviced[i].data = [];
    						clearInterval(deviced[i].chartInterval);
    					}
    				}
    			}
    		}
    	});
    
    

    8 小结

    • 设计时,根据配置属性,生成配置json文件,或者配置后台服务,通过webapi接口持久化配置到db;
    • 运行时,从数据库或者配置文件来生成定制的控件,根据配置参数来加载实时json或者去实时接口ajax或者websocket拿数据;

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://www.cnblogs.com/JerryMouseLi/p/14082036.html

  • 相关阅读:
    bzoj 1030 [JSOI2007]文本生成器
    Swift 学习笔记 (闭包)
    Swift 学习笔记 (函数)
    HTML 学习笔记 JQueryUI(Interactions,Widgets)
    HTML 学习笔记 JQuery(表单,表格 操作)
    HTML 学习笔记 JQuery(animation)
    HTML 学习笔记 JQuery(盒子操作)
    HTML 学习笔记 JQuery(事件)
    HTML 学习笔记 JQuery(DOM 操作3)
    HTML 学习笔记 JQuery(DOM 操作2)
  • 原文地址:https://www.cnblogs.com/JerryMouseLi/p/14082036.html
Copyright © 2011-2022 走看看