当前位置:   article > 正文

基于Web SCADA平台构建数字化车间的MES系统_webscada

webscada

       数字化车间的MES系统与偏管理的信息化系统(如ERP、CRM、SRM等)最大的区别在于数据的“实时性”,以传统的管理为主线的信息化系统因无法及时的将数据录入进系统,使得管理信息化中的数据有严重的滞后性,其管理也属于事后管理,为的是同样的问题下一次不要再次发生。

      伴随着自动化设备的普及,原本无交集的信息化与工业自动化顺其自然的融合在了一起,即是我们工业口都在普及的”两化融合“,生产企业90%的成本来源于车间,管控好车间相当于掌控了90%的成本源头,如何拿到数据,通过数据分析找出工艺、质量、人员、材料等影响成本的因素便成了各企业努力的方向,借用互联网时代大佬的一句话,“上世纪做好企业需要用好IT技术,这个时代做好企业需要用好DATA技术”,从中可以看出数据对于未来的企业的重要性,你用或者不用或许短时间你可以通过丰富的经验弥补这个短板,但将来你一定离不开她,说白了就是数据对于企业的重要性,传统的管理信息化企业管理的是人,管的是人的行为,未来的企业你管理的主体将慢慢变为机器人,实时性的数据对于一个企业来说是我们能最大限度的降低企业成本、提高产品质量最有效的办法,最佳的情况是基于实时性的数据与管理信息化的结合进行事前的预测管理,将产品问题、质量、工艺等纠正于事前。

      数据的来源在车间层,距离设备最近的系统目前来说是SCADA系统,除非有一天自动化与信息化进一步的融合,我不确定是不是当前在说的数字孪生,孪生意味着还不是整体,因为只有是一个整体的系统对于企业来说才是最佳的状态。

      MES系统说到其根本就是要基于实时性的数据,做实时性的决策,这是我的理解,传统的CS架构的SCADA,更多的是侧重于设备及车间层,与后勤部门是脱节的,其最初的定义就是管控工艺而存在,与管理信息化不能很好的融合,伴随着企业对两化的融合,大家发现,只管车间,不管后勤,企业整体的效率仍然得不到提升,后勤与车间等多部门间做不到实时的上传下达,导致了一系列问题的产生,成本损失都发生了,能做的只有事后分析,基于管理的需要车间层的数据需要实时的与后勤管理部门及管理系统进行实时的交互,以达到后勤各部门与车间各角色间的高效率协作,基于当下设备的自动化及各种电子仪器仪表的普及率,要实现上述所说已经不存在难度,剩余的可能就是管理观念的转变了(流程管理)。

    如上说了这么多,下面通过一个实际的案例说明实时性的数据是如何与管理结合的。

  • 建设的背景:

      烘箱广泛应用于各个行业;如:制药卫生,电子元器件干燥,工农业,橡胶机械,大专院校和科研部门的生产车间或实验室等,烘箱的国内市场占有率逐步提升。据了解,国内市场常规的烘箱设备,以及主要国际市场烘箱设备,基本都在中国制造,这表明在中国烘箱设备进口为导向的历史已经结束。但是,仍存在一些问题和困难,据中国通用机械烘箱设备行业协会预测未来几年中国的需求,化工行业将烘箱设备的年需求量达到30000(套)左右;制药干燥烘箱设备的年需求量达到30000(套)左右;农业,林业,粮食。轻工等行业,烘箱设备的年需求量达到50000(套)左右。目前,烘箱设备在国内市场的占有率已达到80%以上。随着技术的发展和自动化程度的进一步革新,各行业使用烘箱设备也在不断的发展,烘箱在我国的相关行业得到广泛应用,也有了很大的发展和提高。但在与烘箱数据,控制管理方面仍存在一些问题:

  (1)数据实时传输,控制与现场烘箱设备联动性不高;

  (2)数据传输,交互存在通讯壁垒;

  (3)管理监控系统过于陈旧;

  • 建设的意义:

       目前,我国大多数行业的烘箱生产应用基本实现了人机互通的管理模式,但缺乏系统的技术指导,导致在实际的应用中障碍重重,IGX烘箱管理系统的建设,对于工业现代化进程具有深远的影响。IGX 烘箱管理系统为提高更好的人机互通,信息传输,智能化任务管理,为推进工业结构调整发挥了重要的作用,智能化管理在工业生产中占有重要地位。要实现高水平,高效率的工业生产和产品人员管理,信息获取手段是最重要的关键技术之一。物联网信息技术在工业领域中有着广泛的应用。我们从工业产品生产不同的阶段来看,无论从原材料的获取和制造及完成阶段,都可以用物联网的技术来提高它工作的效率和精细化管理。IGX 烘箱监控控制系统能大大的提高生产管理效率,节省人工(例如:对于大型工厂来说,上千台的烘箱如果用人力来进行巡检,手动升温/降温,记录数据等工作,其工作量相当庞大且难以管理,如果应用了IGX 烘箱监控控制系统系统,手动控制也只需点击鼠标的微小的动作,前后不过几秒,完全替代了人工操作的繁琐),而且能非常便捷的为工业各个领域研究等方面提供强大的科学数据理论支持,其作用在当今的高度自动化、智能化的社会中是不言而谕的。工业示范园区作为最新的行业技术的应用与推广载体,是现代工业技术的集中体现,是现代信息技术的在工业中最先应用的场合。

  • 提高企业产能

       准确、实时抓取烘箱数据信息,完成数据分配和管理,打通信息传输壁垒,实现任何场合,任何时间,无障碍的与设备的沟通。目前老一代的烘箱监控管理系统,数据信息采集不完全,实时控制不完整,无法完成任何场合,任何时间的访问。系统完整性利用率不足50%,IGX 烘箱监控管理系统的数据采集,控制准确且实时,降低烘箱任务错误率的发生,使生产成品率增加到最高程度,便可获得较高的产能。

  • 提高任务准确性

       烘箱中的每一项产品便是每一个任务,对于任务截取准确的入箱时间,计算正确的出箱时间,设置出箱预警提示,及时出箱,及时部署新任务,减少中间人为的错误。 烘箱数据实时准确显示,提供可靠的曲线数据,报表数据,以及报警数据,数据信息因其高度的准确性,使得具有极高的学术研究价值,为现代化工业进程起到推动性作用。

  • 系统整体架构
烘箱管理系统整体架构

       IGX 烘箱监控管理系统整体解决方案,主要包括三个部分:SCADA信息采集与自动控制、设备及人员管理和MES 智能任务处理组成。信息采集与控制包括烘箱实时温度监测、烘箱目标温度监测、烘箱温度上限余量监测、烘箱下限余量监测等。设备控制包括烘箱目标温度控制、烘箱温度上限余量控制和烘箱启停控制等。信息的发布与数据处理包括信息中心的管理平台和报警信息的手机报警处理等功能。

  •  实时监测模块

       该模块主要由烘箱自带的各类温度控制器、温度传感器组成,实时监测温度,并PID 控制到设定温度值。 

  • 采集传输模块

      采集传输模块为(WEB SCADA)公司DIOT 8500 系统MQTT 网关完成,该网关支持MQTT 物联网协议,支持GPRS 传输、WIFI 无线传输、3G /4G传输及有线宽带;可在局域网通过交换机传输,也可在INTERNET 公网传输;该网关支持各类仪表协议、实时、安全、很少带宽的情况下完成数据高效传输。 

  • 上位平台系统

      上位平台系统为ECAVA 公司的IntegraXorTM SCADA  ( WEB SCADA)专业版B/S 架构组态软件,在全世界超过60 多个国家几万个安装点布置。该软件为最轻、最快、最稳、最安全的信息化物联网系统,支持安卓、苹果、LIUNX、Windows 等系统的手机、平板、PC 以及智能电视和大屏访问。系统可布置在本地、远程或云服务器,同时因其扩展性、灵活性且支持二次开发,使得IGX的存在,一、可在其平台上进行二次开发实现更加强大的功能,二、通过标准的数据接口,可将数据与其他的第三方管理系统,如ERP、MES等各种管理系统进行实时数据对接,这是企业信息化的核心,系统可以有多个,但一定要基于完整的业务流程实时的打通,让期成为一个整体。

  • 烘箱实时监控系统

     烘箱实时监控系统分为“实时监控”、“通信监控”、“曲线管理”、“报表管理”、“报警管理”等功能模块。 

  • 烘箱区域总览
标烘箱区域总览

老化实验室

 每个方格代表一个烘箱位,根据现场实际位置组态,共计62 台烘箱;
点击 “任务管理” 按钮,可进入MES 任务管理界面;
点击 “报表” 按钮,可跳转实时烘箱温度报表界面;
点击 “曲线” 按钮,可跳转实时烘箱温度曲线界面;
点击 “报警” 按钮,可跳转实时烘箱温度报警界面;
点击 “换气老化箱” 按钮,可跳转至6 台换气老化箱监控界面;
点击 “说明书” 按钮,打开烘箱监控管理系统操作说明书;
此界面有 “超温报警” “欠温报警” 的闪烁提示:

  红色闪烁 “超温报警”,黄色闪烁 “欠温报警”

  •  独立烘箱操作界面

      可显示当前系统:是何时发生 “超温报警”、“欠温报警”、“通讯报警” 系统报警:每个页面显示最新两条报警记录;
     实时报警:报警产生,满足设定触发条件,红色警报显示于屏幕下方。

确认报警:用户登录后,点击确认报警,报警信息显示橘色,并显示确认人员、确认时间。

     历史报警:首先,确认后的报警信息可以在历史报警中显示,并且显示确认人员信息及确认时间;其次,当报警触发条件不满足时,此条报警信息自动计入历史报警。
     取消报警:在相对应的报警界面,点击“配置”对需要的报警信息进行勾选,不需要的则不用勾选。 

  •  烘箱温度曲线监控
标题烘箱温度曲线监控
  • 烘箱曲线勾选方法 

 烘箱实时(历史)温度曲线可以通过勾选,进而显示实验员所需的多组烘箱数据曲线。

烘箱曲线勾选方法

  • 烘箱曲线界面具体操作  
烘箱曲线界面具体操作

输出(.csv 数据表形式)

  烘箱温度报表管理

烘箱温度报表管理

烘箱温度报表显示

温度数据历史查询,单击“打开”,选择时间段。 

烘箱温度报表历史查询

  • 烘箱温度报表历史数据导出

温度报表的导出,以“.csv”格式导出,单击“导出”,下载即可。

  •   烘箱报警管理

       根据现场数据实时采集判断输出“超温报警”“欠温报警”“通讯报警”三种报警形式;IGX Web 页面报警显示,将此划分为四个界面进行显示:“所有报警”、“超温报警”、“欠温报警”、“通讯报警”,登陆用户后可确认报警(绿色)、报警(红色)、用户确认(橘色)。报警信息可打印、可导出、可刷选(即过滤)点击左上方对应字样即可。

所有报警

通信报警
  • 烘箱任务管理 
MES系统框架

 烘箱任务管理系统包括“获取实验计划”、“创建实验任务”、“实时任务列表”、“历史任务列表”以及“历史报表”功能。

  •  获取实验计划

    IGX 从《产品全生命周期管理 PLM》系统获取信息中心工艺要求的各项数据。打开当前页面后,默认显示当天任务计划,点击“获取申请单”任务计划获取到IGX 服务器。

 查询功能:可通过“样品编号”、“胶料名称”、“日期间隔”查询当天或历史实验计划。
 防错功能:当前登录用户仅能获取自己的实验计划,若申请其他操作员任务,系统提示无效。
 快速查询功能:可通过选择“实验员”下拉菜单的实验员,快速查询出操作员的所有实验计划。
 

  •  创建实验任务

           此功能模块通过获取的实验计划生成实验任务。选择或填写 “样品编号(委托号)”、“胶料名称”、“实验项目”、“烘箱”、“温度”、“实验时长”以及“备注”后点击“创建实验任务”按钮,生成实验任务。逐个点击“入箱”或一次性点击“全部入箱”完成实验任务入箱,可在“实时任务”页面进行监控。

 自动填写功能:当操作员选择“样品编号(委托号)”后,会自动填写“样品编号(委托号)”、“胶料名称”、“实验项目”,只需操作员确认即可,或可进行少量修改。

 智能搜索功能:在选择烘箱时,输入温度值或烘箱编号均可快速查询到对应烘箱。如图:

 防错功能:当前登录操作员只能对自己的实验计划生成实验任务;也只能对自己的实验任务进行入箱操作。

 快速筛选功能:点击页面的“仅显示自己的实验任务”按钮,可快速查询出自己的实验任务,提高操作效率。如下图:

 自动记录入箱时间功能:不需要操作员输入或选择比较繁琐的入箱时间,当点击“入箱”“全部入箱”按钮后,系统会自动记记录箱时间,防止出错、提高精度和工作效率。此处是体现信息化与自动化的一个融合点,如果当前不采集时间,传统的做法即是,当入箱后作业人员需记录当前的时间,这个过程耗时且会存在数据记录不准确性的情况,关键问题是基于业务流程的需要,这个入箱的动作并不能满足实时更新生产计划、生产进度、生产日报、实时计件工资等一系列管理的要求。

  •  实时任务列表

        如上界面显示所有正在实验中的项目,实验项目按烘箱编号大小顺次排列(即可观察箱内实验项目数量),当实验完成时点击“出箱”按钮完成实验任务,可到“历史任务列表”查询历史数据。


 出箱提示功能:当距出箱20 分钟时,实验单条记录显示“红色”背景提示;当实验时间完成时,实验单条记录显示“黄色”背景提示。
 防错功能1:当前登录用户仅对自己实验任务进行修改或出箱操作,当对其他操作员任务进行操作时会有权限不足提示。
 防错功能2:当出箱时间未到时,如果误点“出箱”按钮,系统会自动提示“出箱时间未到”,并不予操作通过 。
 快速选择功能:通过选择“入箱人员”下拉菜单,可快速显示相关实验任务,提高效率。
 三次修改功能:即使是正在实验的任务,也可以进行第三次修改功能,如图:

并且系统自根据修改内容计算“出箱时间”“剩余分钟”数。 

 自动记录出箱时间功能:同入箱时间一样,当点击“出箱”按钮后,系统会优先判断是否满足工艺的要求,如果在工艺要求的工艺范围之内,系统将自动记记录箱时间,防止出错,且提高精度和工作效率。

  •  历史任务列表 

       如上页面显示所有历史任务,默认显示当天的历史实验任务。点击任务对应的“打开报表”按钮,可打开此实验任务的具体数据及历史温度报表。

  • 历史任务报表

       上述历史任务报表详细查询到了此项任务的相关数据,并可导出或打印,以供数据追朔,这种追溯将有能力将从任务下发、入箱、出箱及过程中所有采集到的实时工艺数据进行有效的关联,将某批次的产品与影响产品质量的实时数据绑定将有效的实现质量及工艺的全流程追溯,以辅助企业找出影响产品质量的具体原因,以进一步提升并优化生产工艺,实现企业的降本增效目标。

  •  移动访问和权限管理系统

       系统支持安卓、苹果、Linux、Windows 等系统的手机、平板、PC以及智能电视和大屏访问,可进行矢量放大或缩小。操作员或相关人员可在局域网或INTERNET 网访问,随时随地掌握
实验情况,提高工作效率。如图手机访问: 

手机端监控效果

手机端监控效果

        上述是整个烘箱数字化车间MES系统的核心业务功能,其中涉及到从计划任务的管理、实时任务的工艺监控、出箱及入箱的管理、实时生成管理需要的日报分析性报表,其功能实现了ERP与MES系统相结合的大部分功能,从生产计划的生成、生产工单的下达、基于生产工单的领工、领发料管理、生产过程监控、工艺过程实时数据采集、完工报工、质量检测(通过接口读取当前产品PLM中的工艺要求与SCADA实时采集的数据进行实时对比分析,不满足工艺则给予报警提醒,同时车间的三色灯也会声光报警) 、成品入库等,配合以生产看板、仓库备料及领发料看板,实现以SCADA实时的数据采集监控为主的车间数字化,整个过程对关键数据实现了自动采集、基于数据自动触发下一步的流程、实时更新对应的业务节点、生产计划、生产工单、质量数据及看板数据,实现了后勤管理部门与生产车间、仓库、质量等多部门间基于业务流程的实时协作场景。

        如下将说明基于IGX Web SCADA平台(Ecava_IGX / Ecava WEB SCADA ),如何将底层采集的设备数据与前后端实现逻辑对接的,以给有类似需求的个人或企业提供一些思路。

       首先IGX Web 组态平台 (Ecava_IGX / Ecava WEB SCADA ),分为设计时与运行时,IGX在设计时为C/S架构(C/S架构在某些应用场景中仍然有着绝对的优势),通过IGX项目编辑器编辑后的项目,项目结构更像是一个管理系统的前端工程(详见下方表格)一样,其生成的工程文件在编辑后发布时则是以B/S架构进行运行,相当于是这个发布后的WEB组态平台是通过C/S架构的平台设计、配置出来的,当然各位伙伴们也可以通过自己的前后端开发能力,基于业务逻辑进行深度的定制开发,以满足个性化的需求。

IGX项目文件结构
序号结构内容说明
1cacheIGX运行过程中数据缓存
2Images同前端工程一致,用于图片等文件的存放
3lang语言配置文件;
4media媒体文件
5plugins各种第三方的JS插件包,如Bootstrap、ThreeJS、JQuery等
6scripts脚本文件
7styles样式文件
8*.igxIGX的工程运行文件
9*.html展示页面
10*.svg同上方的展示页面,用于数据与图形的绑定
11*.* 其他文件其他配置性文件等

       IGX自带Web Server,且内置GoogleV8 脚本引擎,在项目工程文件发布时,可以直接在项目编辑器中直接运行并发布,Web SCADA ( WEB SCADA )运行引擎集成了各种服务,如兼容市面80%以上的通用数据协议、IO点采集服务、IO驱动服务、Script 脚本服务、网关服务、Web Server、集群服务、冗余服务、报警服务、报表服务、SNMP agent 服务、日志、数据库等服务,所以IGX即支持通过简单的拖拉拽模式的开发、也支持复杂脚本逻辑的开发、同时可以一键发布并运行,不需要额外配置。

  • 前端开发与支持:

       IGX Web SCADA ( WEB SCADA )严格来说也分为前后端,前端即是通过最新的WEB技术,如JavaScript 脚本、DOM、CSS、AJAX、JSON、WebServices等进行扩展开发,相对于管理系统复杂的后端,对于SCADA来说,其后端一是数据采集与实时计算、二是提取历史数据分析与展示等。IGX已将底层采集的数据通过封装技术,将数据封闭为一个JS包:igrX2.js,伙伴们可以直接引用当前文件至页面中,如下:

<script type='text/javascript'src='system/scripts/igrX2.js'></script>

 JS包引用后,除标准JavaScript函数之外,伙伴们则可以基于通过GetTag('TagName')、SetTag('TagName',val,option)来获取实时的设备数据,设置某个可读写IO的值等操作,其中SetTag接受可选参数,从而可以更改虚拟标记的时间戳以用于数据库日志记录。setTag('tag',data,option);其中选项是具有接受JavaScript Date()的时间项的JSON对象。完整的示例可以在以下代码片段中看到。

如下 getTag:

  1. // SetTag 获取标签数据
  2. var S1 = getTag('SIM1_Lek');
  3. var S2 = getTag('SIM1_Breuk');
  4. var S3 = getTag('SIM1_Service');
  5. var S4 = getTag('SIM1_Loopim');

如下  setTag:

  1. // 给数据标签设置数据 SetTag
  2. var opt = {
  3. "time" : new Date(
  4. 2020, //yyyy
  5. 0, //M; 0: Jan, 1: Feb...
  6. 1, //D
  7. 1, //h
  8. 2, //m
  9. 3, //s
  10. 456//msec
  11. )
  12. };
  13. setTag( "myTag", 123.45, opt);
  • 调试功能

      更多功能仅适用于服务器端,它们主要用于调试目的。这些功能需要通过单击调试按钮打开调试模式,当在任务窗口上选择脚本时,调试信息将显示在状态窗口里。

  1. debugString(String//用于将调试字符串发送到状态窗口。
  2. debugTag(标记名)//只需打印标记名及其值到状态窗口。 

       调试信息在状态窗口的粉红色文本中滚动显示。下面是一个演示使用调试功能进行故障排除的示例代码。它可以被复制并粘贴到脚本条目中以查看程序流。 

高度参考界面

  

  1. //代码调试
  2. var a = getTag( "tagA") || 1; //默认 value 1
  3. var b = getTag( "tagB") || 2; //默认 value 2
  4. var c = getTag( "tagC"); //没有默认值
  5. if (c > 1000) {
  6. a = 1;
  7. b = 2;
  8. }
  9. a = a + 1;
  10. setTag( "tagA", a);
  11. b = b + 2;
  12. setTag( "tagB", b);
  13. c = a + b;
  14. setTag( "tagC", c);
  15. debugTag( "tagC"); //使用debugTag()调试.
  16. debugString( "Script is successfully executed."); //debugString 只能在调试模式下使用

 通过getTag拿到数据后,伙伴们可以在前端加入相应的处理逻辑进行开发。

  • 后端开发与支持 - runSql()函数

在IGX Web SCADA ( WEB SCADA )中存储的SQL语句的详细说明可以在存储SQL 配置的配置章节中阅读。在项目编辑器中定义存储语句的名称,要执行的SQL 语句和SQL 参数(如果有)之后,我们可以立即从前端访问它。我们使用以下表达式访问存储的SQL 语句:

runSql(name, parameters, option, callback-function);

基于上述表达式传递4个参数。
下面的表解释了runSql()函数中的每个参数的作用。

名称:
         Name 是与项目编辑器中指定的存储SQL 语句的名称相对应的字符串值
        [重要]
         你可能猜到,name 是一个强制参数,不能留空!
参数:
        参数是指定在项目编辑器中为特定语句定义的参数的值参数是一个Javascript 对象,应该遵循JSON语法。

      [注意]
        不应包括用于在项目编辑器中指定参数的“@”符号,假设定义语句有2个参数@table 和val,param对象应该构造如下:

  1. var param = {
  2. "table": "table value",
  3. "val": "val value"
  4. };

选项:
      Option也是一个Javascript 对象,应该遵循JSON语法,暂时选项有两个条目,outfmt(表示输出格式)和dbgroup(数据库名称)
     outfmt 是用户希望服务器返回任何SQL 语句的结果数据的传输格式,outfmt 可以采用json,csv,csvh或xml的4个值中的任何一个,如果未指定,outfmt值将默认为csv,dbgroup允许您指定应执行SQL 语句的数据库名称,该名称应与您在项目编辑器的“数据库”部分中定义的数据库的名称匹配,如果在选项中未指定bgroup,则将应用默认值-1,它指示服务器在项目编辑器中定义的所有数据库上运行SQL语句,要定义选项,您可以将其定义如下:

  1. var opt = {
  2. "outfmt": "json",
  3. "dbgroup": "dbname"
  4. };
  5. // 或者你也可以像下面这样做:
  6. var opt = {};
  7. opt["outfmt"] = "json";
  8. opt["dbgroup"] = "dbname";

回调函数:
        回调函数将是负责处理服务器在执行SQL语句时返回的结果的函数,如果服务器没有返回任何结果,回调函数也负责用户通知,您可以预先声明一个函数,并将函数名称作为参数传递:

  1. var cbfn = function(result){
  2. //这是回调函数
  3. // result 是来自服务器的响应
  4. };
runSql(name,parameters,options,cbfn);

或者,您可以在指定回调函数的参数时声明一个匿名函数,如下:

  1. runSql(name,parameters,options,function(result){
  2. //这是回调函数
  3. // result 是来自服务器的响应
  4. });

烘箱案例代码分析 - 获取烘箱计划任务:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>列表</title>
  5. <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
  6. <script type="text/javascript" src="system/scripts/igrX.js"></script>
  7. <script type="text/javascript" src="system/scripts/igrX2.js"></script>
  8. <style type="text/css">
  9. fieldset {width:80%; margin:auto; float: none;background-color: #F5F5F5; }
  10. #content-table-th{
  11. width:1328px;
  12. margin:auto;
  13. border:1px solid #aaa!important;
  14. background-color: #B1D2EC;
  15. }
  16. #content-table{
  17. width:1328px;
  18. text-align: center;
  19. margin:auto;
  20. border-spacing:0;
  21. border-collapse:collapse;
  22. }
  23. #content-table tr:nth-child(even){
  24. background-color: #ddd;
  25. }
  26. #content-table tr:nth-child(odd){
  27. background-color: #eee;
  28. }
  29. #content-table td{
  30. border:1px solid #aaa!important;
  31. }
  32. body{padding: 20px;}
  33. .demo-input{padding-left: 10px; height: 28px; min-width: 110px; line-height: 28px; border: 2px solid #e6e6e6; background: url(laydate/riqi.png) no-repeat;background-position:right; border-radius: 2px;}
  34. .demo-footer{padding: 50px 0; color: #999; font-size: 14px;}
  35. .demo-footer a{padding: 0 5px; color: #01AAED;}
  36. </style>
  37. </head>
  38. <body bgcolor="#FFFFFF">
  39. <div id="container">
  40. <center><fieldset style="width:1320px;" class="ui-widget-content">
  41. <div>
  42. &nbsp;样品编号:&nbsp;
  43. <input type="text" style="width:145px; height:20px; font-size:16px" id="wt_num" placeholder="请输入样品编号" autofocus="autofocus"></input>
  44. &nbsp;胶料名称:&nbsp;
  45. <input type="text" style="width:125px; height:20px; font-size:16px" id="sj_code" placeholder="请输入胶料名称" autofocus="autofocus"></input>
  46. &nbsp;&nbsp;实验员:&nbsp;
  47. <select style="width:70px; height:25px;" id="selStId" onchange="dotakeSt()">
  48. <option value="0">---全部---</option>
  49. <option value="wangb">王博</option>
  50. <option value="chenk">陈开</option>
  51. </select>
  52. <input style="display:none" style="width:120px; height:25px;" type="text" readonly="readonly" id="takeSt_v"></input>
  53. <input style="display:none" type="text" id="takeSt"></input>
  54. &nbsp;日期开始:&nbsp;
  55. <input type="text" class="demo-input" name="datep31" id="datep31" style="width:110px;font-size:95%;border-radius:5px;" autocomplete="off"/>
  56. &nbsp;截止(当天)&nbsp;
  57. <input type="text" class="demo-input" name="datep32" id="datep32" style="width:110px;font-size:95%;border-radius:5px;" autocomplete="off"/>
  58. &nbsp;
  59. <input style="width:120px; height:30px;font-size:13px; border-radius:5px;" type="button" value="⇪&nbsp;查询最新申请单" onclick="searchTaskData()"/>&nbsp;
  60. </div>
  61. </fieldset></center>
  62. </div>
  63. <table id="content-table-th">
  64. <tr><th width="20px">序号</th><th width="120px">样品编号</th><th width="120px">胶料名称</th><th width="160px">实验项目</th><th width="100px">申请日期</th><th width="40px">周期</th><th width="60px">实验员</th><th width="90px">操作</th></tr>
  65. </table>
  66. <table id="content-table"> </table>
  67. </body>
  68. <script type="text/javascript">
  69. var myTimer;
  70. var param = {};
  71. function dotakeSt(){
  72. var myselect=document.getElementById("selStId");
  73. var index=myselect.selectedIndex ;
  74. document.getElementById('takeSt').value=myselect.options[index].value;
  75. document.getElementById('takeSt_v').value=myselect.options[index].text;
  76. }
  77. function searchTaskData(){
  78. var txt="",i;
  79. var wt_num ="";
  80. wt_num = document.getElementById('wt_num').value;
  81. var sj_code ="";
  82. sj_code = document.getElementById('sj_code').value;
  83. var expCode ="";
  84. expCode = document.getElementById('takeSt').value;
  85. if (expCode==0) expCode="";
  86. var sttime=document.getElementById ("datep31");
  87. var edtime=document.getElementById ("datep32");
  88. param["ts"] = sttime.value;
  89. param["ts2"] = edtime.value;
  90. param["wt_num"] = wt_num;
  91. param["sj_code"] = sj_code;
  92. param["expCode"] = expCode;
  93. var todo ="<a href='#' onclick='insertData(this)'>⇩获取申请单&nbsp;</a>&nbsp;"
  94. txt=txt + "";
  95. runSql("getjc_task", param, {outfmt:"json"}, function(result) {
  96. if (result.statusCode == 200) {
  97. var data = JSON.parse(result.response);
  98. for (var i in data){
  99. var j =i*1 + 1;
  100. txt=txt + "<tr>";
  101. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["wt_num"] + "</td>";
  102. txt=txt + "<td width='20px'>" + j + "</td>";
  103. txt=txt + "<td width='120px'>" + data[i]["wt_num"] + "</td>";
  104. txt=txt + "<td width='120px'>" + data[i]["sj_code"] + "</td>";
  105. txt=txt + "<td width='160px'>" + data[i]["sy_item"] + "</td>";
  106. txt=txt + "<td width='100px'>" + data[i]["sysdate"] + "</td>";
  107. txt=txt + "<td width='40px'>" + data[i]["days1"] + "</td>";
  108. txt=txt + "<td width='60px'>" + data[i]["expname"] + "</td>";
  109. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["sy_name"] + "</td>";
  110. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["draw_no"] + "</td>";
  111. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["sy_lot"] + "</td>";
  112. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["sy_qty"] + "</td>";
  113. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["sy_dept"] + "</td>";
  114. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["applicantcode"] + "</td>";
  115. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["applicantname"] + "</td>";
  116. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["days2"] + "</td>";
  117. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["comdate"] + "</td>";
  118. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["findate"] + "</td>";
  119. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["appfindate"] + "</td>";
  120. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["fee"] + "</td>";
  121. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["expcode"] + "</td>";
  122. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["keep"] + "</td>";
  123. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["memo"] + "</td>";
  124. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["stage"] + "</td>";
  125. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["flag"] + "</td>";
  126. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["pcode"] + "</td>";
  127. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["ypcfdate"] + "</td>";
  128. txt=txt + "<td style=" + '"display:none"'+">" + data[i]["ypcldate"] + "</td>";
  129. txt=txt + "<td width='90px'>" + todo + "</td>";
  130.       txt=txt + "</tr>";
  131. }
  132. }
  133.   document.getElementById('content-table').innerHTML=txt;
  134. });
  135. }
  136. // 按照样品编号 获取到实验计划后,并插入到 MES任务执行系统中
  137. function insertData(element) {
  138. var updateTr = element.parentNode.parentNode;
  139. var expcode ="";
  140. expcode = updateTr.childNodes[20].innerHTML;
  141. expname = updateTr.childNodes[7].innerHTML;
  142. window.user_name = window.parent.sec_module.current_user();
  143. if (expcode.search(user_name) == -1 )
  144. {
  145. if(user_name == "Admin")
  146. {
  147. if (!confirm(user_name+ " :您是管理员,可获取此[申请单],确定获取?!")) {
  148. return;
  149. };
  150. var wt_num ="";
  151. wt_num = updateTr.childNodes[2].innerHTML;
  152. param["wt_num"] = wt_num;
  153. runSql("check_task", param, {outfmt:"json"}, function(result) {
  154. if (result.statusCode == 200) {
  155. var data = JSON.parse(result.response);
  156. var num = data.length;
  157. alert(" ✔ ✔ 已有该任务申请单,样品编号: "+wt_num +" , 在下一流程界面上,请对该任务新建✍[执行计划]" );
  158. }
  159. else{
  160. {
  161. var sj_code="";
  162. sj_code = updateTr.childNodes[3].innerHTML;
  163. var sy_item ="";
  164. sy_item = updateTr.childNodes[4].innerHTML;
  165. var sysdate ="";
  166. sysdate = updateTr.childNodes[5].innerHTML;
  167. var days1 ="";
  168. days1 = updateTr.childNodes[6].innerHTML;
  169. var expname ="";
  170. expname = updateTr.childNodes[7].innerHTML;
  171. var sy_name ="";
  172. sy_name = updateTr.childNodes[8].innerHTML;
  173. param["sj_code"] = sj_code;
  174. param["sy_item"] = sy_item;
  175. param["sysdate"] = sysdate;
  176. param["days1"] = days1;
  177. param["expname"] = expname;
  178. param["sy_name"] = sy_name;
  179. var draw_no ="";
  180. draw_no = updateTr.childNodes[9].innerHTML;
  181. var sy_lot ="";
  182. sy_lot = updateTr.childNodes[10].innerHTML;
  183. var sy_qty ="";
  184. sy_qty = updateTr.childNodes[11].innerHTML;
  185. var sy_dept ="";
  186. sy_dept = updateTr.childNodes[12].innerHTML;
  187. var applicantcode ="";
  188. applicantcode = updateTr.childNodes[13].innerHTML;
  189. var applicantname ="";
  190. applicantname = updateTr.childNodes[14].innerHTML;
  191. param["draw_no"] = draw_no;
  192. param["sy_lot"] = sy_lot;
  193. param["sy_qty"] = sy_qty;
  194. param["sy_dept"] = sy_dept;
  195. param["applicantcode"] = applicantcode;
  196. param["applicantname"] = applicantname;
  197. var days2 ="";
  198. days2 = updateTr.childNodes[15].innerHTML;
  199. var comdate ="";
  200. comdate = updateTr.childNodes[16].innerHTML;
  201. var findate ="";
  202. findate = updateTr.childNodes[17].innerHTML;
  203. var appfindate ="";
  204. appfindate = updateTr.childNodes[18].innerHTML;
  205. var fee ="";
  206. fee = updateTr.childNodes[19].innerHTML;
  207. var expcode ="";
  208. expcode = updateTr.childNodes[20].innerHTML;
  209. var keep ="";
  210. keep = updateTr.childNodes[21].innerHTML;
  211. //alert("expcode 19: " +expcode);
  212. param["days2"] = days2;
  213. param["comdate"] = comdate;
  214. param["findate"] = findate;
  215. param["appfindate"] = appfindate;
  216. param["fee"] = fee;
  217. param["expcode"] = expcode;
  218. param["keep"] = keep;
  219. var memo ="";
  220. memo = updateTr.childNodes[22].innerHTML;
  221. var stage ="";
  222. stage = updateTr.childNodes[23].innerHTML;
  223. var flag ="";
  224. flag = updateTr.childNodes[24].innerHTML;
  225. var pcode ="";
  226. pcode = updateTr.childNodes[25].innerHTML;
  227. var ypcfdate ="";
  228. ypcfdate = updateTr.childNodes[26].innerHTML;
  229. var ypcldate ="";
  230. ypcldate = updateTr.childNodes[27].innerHTML;
  231. param["memo"] = memo;
  232. param["stage"] = stage;
  233. param["flag"] = flag;
  234. param["pcode"] = pcode;
  235. param["ypcfdate"] = ypcfdate;
  236. param["ypcldate"] = ypcldate;
  237. param["getuser"] = user_name;
  238. param["gettime"] = getTag("app.currentTime");
  239. var opt = {
  240. "outfmt": "json"
  241. };
  242. var cbfn = function(result){
  243. alert(" ✔ 成功获取了任务申请单,其对应【样品编号】: " + wt_num +" ,在下一流程界面上,请对该任务新建✍[执行计划]" );
  244. };
  245. runSql("insert_task", param,opt,cbfn);
  246. }
  247. } // end ---保证数据库里记录唯一性,插入该条任务
  248. });
  249. }
  250. else{
  251. alert(user_name+" :权限不够!不可以获取此申请单!请使用IGX产品自带的账户Admin登录本系统。");
  252. return false;
  253. }
  254. }
  255. else
  256. {
  257. alert(user_name+" :登录人员,属于此申请单的实验员,可以获取!");
  258. var wt_num ="";
  259. wt_num = updateTr.childNodes[2].innerHTML;
  260. param["wt_num"] = wt_num;
  261. runSql("check_task", param, {outfmt:"json"}, function(result) {
  262. if (result.statusCode == 200) {
  263. var data = JSON.parse(result.response);
  264. var num = data.length;
  265. alert(" ✔ ✔ 已有该检测任务申请单,样品编号: "+wt_num +" , 在下一流程界面上,请对该任务新建✍[执行计划]" );
  266. }else{
  267. {
  268. var sj_code="";
  269. sj_code = updateTr.childNodes[3].innerHTML;
  270. var sy_item ="";
  271. sy_item = updateTr.childNodes[4].innerHTML;
  272. var sysdate ="";
  273. sysdate = updateTr.childNodes[5].innerHTML;
  274. var days1 ="";
  275. days1 = updateTr.childNodes[6].innerHTML;
  276. var expname ="";
  277. expname = updateTr.childNodes[7].innerHTML;
  278. var sy_name ="";
  279. sy_name = updateTr.childNodes[8].innerHTML;
  280. param["sj_code"] = sj_code;
  281. param["sy_item"] = sy_item;
  282. param["sysdate"] = sysdate;
  283. param["days1"] = days1;
  284. param["expname"] = expname;
  285. param["sy_name"] = sy_name;
  286. var draw_no ="";
  287. draw_no = updateTr.childNodes[9].innerHTML;
  288. var sy_lot ="";
  289. sy_lot = updateTr.childNodes[10].innerHTML;
  290. var sy_qty ="";
  291. sy_qty = updateTr.childNodes[11].innerHTML;
  292. var sy_dept ="";
  293. sy_dept = updateTr.childNodes[12].innerHTML;
  294. var applicantcode ="";
  295. applicantcode = updateTr.childNodes[13].innerHTML;
  296. var applicantname ="";
  297. applicantname = updateTr.childNodes[14].innerHTML;
  298. param["draw_no"] = draw_no;
  299. param["sy_lot"] = sy_lot;
  300. param["sy_qty"] = sy_qty;
  301. param["sy_dept"] = sy_dept;
  302. param["applicantcode"] = applicantcode;
  303. param["applicantname"] = applicantname;
  304. var days2 ="";
  305. days2 = updateTr.childNodes[15].innerHTML;
  306. var comdate ="";
  307. comdate = updateTr.childNodes[16].innerHTML;
  308. var findate ="";
  309. findate = updateTr.childNodes[17].innerHTML;
  310. var appfindate ="";
  311. appfindate = updateTr.childNodes[18].innerHTML;
  312. var fee ="";
  313. fee = updateTr.childNodes[19].innerHTML;
  314. var expcode ="";
  315. expcode = updateTr.childNodes[20].innerHTML;
  316. var keep ="";
  317. keep = updateTr.childNodes[21].innerHTML;
  318. param["days2"] = days2;
  319. param["comdate"] = comdate;
  320. param["findate"] = findate;
  321. param["appfindate"] = appfindate;
  322. param["fee"] = fee;
  323. param["expcode"] = expcode;
  324. param["keep"] = keep;
  325. var memo ="";
  326. memo = updateTr.childNodes[22].innerHTML;
  327. var stage ="";
  328. stage = updateTr.childNodes[23].innerHTML;
  329. var flag ="";
  330. flag = updateTr.childNodes[24].innerHTML;
  331. var pcode ="";
  332. pcode = updateTr.childNodes[25].innerHTML;
  333. var ypcfdate ="";
  334. ypcfdate = updateTr.childNodes[26].innerHTML;
  335. var ypcldate ="";
  336. ypcldate = updateTr.childNodes[27].innerHTML;
  337. param["memo"] = memo;
  338. param["stage"] = stage;
  339. param["flag"] = flag;
  340. param["pcode"] = pcode;
  341. param["ypcfdate"] = ypcfdate;
  342. param["ypcldate"] = ypcldate;
  343. param["getuser"] = user_name;
  344. param["gettime"] = getTag("app.currentTime");
  345. var opt = {
  346. "outfmt": "json"
  347. };
  348. var cbfn = function(result){
  349. alert(" ✔ 成功获取任务申请单,其对应【样品编号】: " + wt_num +" ,在下一流程界面上,请对该任务新建✍[执行计划]" );
  350. };
  351. runSql("insert_task", param,opt,cbfn);
  352. }
  353. } // end ---保证数据库里记录唯一性,
  354. });
  355. }
  356. }
  357. </script>
  358. </html>
  359. <script src="laydate/laydate.js"></script>
  360. <script>
  361. laydate.render({
  362. elem: '#datep31'
  363. ,type: 'date'
  364. ,value: '2020-01-01'
  365. });
  366. laydate.render({
  367. elem: '#datep32'
  368. ,type: 'date'
  369. ,value: new Date()
  370. });
  371. </script>

     在上述获取洪箱计划任务的代码段中,通过在JS中直接引用RunSql函数,获取到计划任务数据,如下:

  1. runSql("getjc_task", param, {outfmt:"json"}, function(result){
  2. if (result.statusCode == 200) {
  3. #函数体处理逻辑
  4. }
  5. }

其中的getjc_task,是通过IGX在设计端事前定义好的,如下图:

 getjc_task SQL语句如下:

  1. select num as wt_num,
  2. code as sj_code,
  3. name as sy_name,
  4. draw_no,
  5. lot as sy_lot,
  6. qty as sy_qty,
  7. item as sy_item,
  8. dept as sy_dept,
  9. applicantCode,
  10. applicantName,
  11. sysDate,
  12. days1,
  13. days2,
  14. comDate,
  15. finDate,
  16. appfinDate,
  17. fee,
  18. expCode,
  19. expName,
  20. keep,
  21. Memo,
  22. stage,
  23. flag,
  24. pcode,
  25. ypcfdate,
  26. ypcldate
  27. from M_Experiment
  28. where sysDate>='@ts' and sysDate<='@ts2' and num like '%@wt_num%' and code like '%@sj_code%' and expCode like '%@expCode%'
  29. ORDER BY num DESC;

如感兴趣,请各位伙伴自行阅读上述代码。

       基于上述步骤一个基于IGX WEB SCADA ( WEB SCADA )所构建的数字化车间MES系统即可上线,通过系统的上线及使用,系统整体达到了客户的预期效果,通过系统将客户方传统的人管人的模式,经过业务流程的梳理、系统固化,实现了多部门间基于流程相互驱动,通过业务流程驱动人员及部门间的沟通与协调,实现了企业线上与线下、信息化与自动化的融合。 

     如各位伙伴对此文章或IGX WEB SCADA ( WEB SCADA )平台感兴趣,欢迎伙伴们转发、评论、私信,大家相互帮忙、共同成长、共赢。

     IGX WEB SCADA适用的企业:

一、从事自动化工程、电气、自动化类的企业,替代传统的组态平台。

二、拥有独立开发能力的软件工程类企业、基于此平台帮助客户构建数字化产线、MES系统 ,实现车间设备、仪器仪表的数据采集、监视及控制,与现企业信息化系统高度融合。

三、拥有电气自动化、物联网、工业控制等专业的高校,将IGX WEB SCADA平台、IGX应用、实践与二次开发教材及物联网教仪进行推广。

四、当前从事或计划从事物联网行业的伙伴们。

    本次的分享到此结束,感谢各位伙伴。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/627110
推荐阅读
相关标签
  

闽ICP备14008679号