openOPC与监控页面二

openOPC与监控页面二

  本章节,我们继续完成监控页面验证的demo,实现实时从后台刷新数据到UI端,笔者考虑采用B/S架构来构建这个简单的监控页面,下面将演示这个页面是如何一步一步来演进,这也是希望告诉读者,当我们面向一个新的需求时,如何通过技术领域的探索验证技术路线是否满足需求。在通过迭代来确保功能满足需求的同时,如何通过不断的小步迭代改进技术架构的过程。

目标1:实现一个网页,通过点击一个按钮,然后从后台抓取某几个位号的值回传到UI端更新网页里div的文本内容。

2.1.安装集成开发环境

  本小节为了提高开发效率,文中演示过程中才用的集成开发环境(IDE),是Visual Studio Community 2019社区版本,可供学习的教育版本和个人开发者使用,同时也授权5人一下的小团队进行商业开发,另外VS Community 2019Mac版本,对于钟爱使用Mac同学来说也是一个非常好的IDE选择。 

VS Community 2019下载网址: 

https://visualstudio.microsoft.com/zh-hans/free-developer-offers/

 笔者所用的开发环境:Windows 10操作系统笔记本电脑,进入安装界面如下:

 

   注意如上图一定要选择左边ASP.NET Web 开发 和 Python 开发,同时,我们选择python 2 32-bit 2.7 来确保满足openOPCpython2环境的需求。如果环境不对就不能正常的访问到OPC服务读取tag位号值。

2.2.创建一个web project项目

 安装完毕后我们启动VS Community 2019集成开发环境,来到启动界面,如下图:

 选择Create a new project选项创建一个Python web项目,这里选择创建Flask Web Project,如下图:

笔者选择默认路径,可自己选择项目的存放位置。

 

2.3.添加一个项目运行的虚拟环境

 项目运行的虚拟环境很重要,一定要选择前面openOPC运行支持的python2环境否则后面就会很坑的,如下图:

 虚拟环境添加过程中IDE环境会自动安装目标环境需要的相应的一些基本的python,比如Flask和其依赖的第三方组件,如下图:

   安装虚拟环境完毕后我们就可以通过IDE环境运行这个项目了,点击Debug下的F5运行我们刚刚创建的Flask Web项目,一个轻量级的网站就跑起来了,Flask 在轻量级上确实方便又好用的一个web开发利器。

2.4.新增一个自己的测试页面

 我们新增一个页面来模拟点击按钮刷新界面div文本效果,首先在项目的templates目录下增加一个新的testPage.html的文件,如下图:

 

2.4.1.testPage.html代码

 

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
        <script src="https://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
</head>
<body>
    <div>
        tag value:
    </div>
    <div id="divTag">0.0 </div>
    <button onclick="testClick()">test</button>
<script>
    //按钮绑定事件,首先模拟把0.0值修改为2020
        function testClick() {
            $("#divTag").html("2020");          

        }
    </script>
</body>
</html >

   

2.4.2.修改项目的views.py文件代码

# coding=utf8  #非常重要文件了加了中文一定要加这个标记,否则运行程序会报错
"""
Routes and views for the flask application.
"""

from datetime import datetime
from flask import render_template
from FlaskWebProject1 import app

#@app.route("/") 注释这一行默认显示我们新增的页面
@app.route("/home")
def home():
    """Renders the home page."""
    return render_template(
        "index.html",
        title="Home Page",
        year=datetime.now().year,
    )

@app.route("/contact")
def contact():
    """Renders the contact page."""
    return render_template(
        "contact.html",
        title="Contact",
        year=datetime.now().year,
        message="Your contact page."
    )

@app.route("/about")
def about():
    """Renders the about page."""
    return render_template(
        "about.html",
        title="About",
        year=datetime.now().year,
        message="Your application description page."
    )

@app.route("/") #把网站默认显示页面修改为我们新增的页面便于调试
@app.route("/testPage")
def testPage():
    """Renders the home page."""
    return render_template(
        "testPage.html",
        title="Test Page",
    )

  2.4.3.按F5运行我们的网站项目

 点击test”按钮div 文字变成2020,模拟了点击更新当前文字内容。

  

  到目前为止,这个页面简单的体现了主动刷新数据的一个基本机制,那么接下来尝试如何从后台来获取到数据,后台获取数据这里我们采用JQuery的异步请求 ajax() 技术来实现,因此我们发现页面的head里加载了jquery-2.0.2.min.js文件,本文采用百度的CDN就不用再自己的项目里增加这个js文件了。

 

<script src="https://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js">
</script>

 

  2.4.4.ajax异步调用

    现在我们把testClick()函数代码修改为如下:

 

        function testClick() {
            //模拟改变值
            //$("#divTag").html("2020");

            //模拟异步从后台获得值
            $.ajax({url:"/getTagCurValue/",success:function(result){
                $("#divTag").html(result);
            }});

        }

  

这次运行网站点击test按钮我们会在浏览器调试工具页的控制台上看到错误,服务器没有发现url资源,如下图:

 

于是我们得在web服务里增加这个/getTagCurValue/,通过它从服务端返回我们想读取的tag位号的当前值。 

2.4.5.views文件里增加getTagCurValue url 函数 

@app.route("/getTagCurValue")
def getTagCurValue():
    """Renders the home page."""
    #先返回一个静态值测试页面的刷新效果
    return "2021" 

  

Flask笔者用起来可以说真是很爽,你看这么一段简单的代码我们就增加了一个后台服务接口,F5 点击“test”按钮你会发现div文本刷新为“2021”了。是不是得呵呵了。

 

 2.5.读取opc服务的tag位号值

  现在我们就差一步了getTagCurValue"真正读取opc服务某一个tag位号的值。这样就完成了从UI端到服务端主动获取opc服务tag位号值,并更新UI界面的技术原型。views文件函数getTagCurValue代码修改如下:

@app.route("/getTagCurValue")
def getTagCurValue():
    #先返回一个静态值测试页面的刷新效果
    #return "2021"  
    import OpenOPC
    opc = OpenOPC.client()
    opc.connect("Matrikon.OPC.Simulation")
    result= opc["Random.Int1"]
    opc.close()
    return unicode( result)

  

这次我们F5执行测试,点击“test”按钮UI界面数据不会刷新,服务端控制台出现错误提示:

import OpenOPC

ImportError: No module named OpenOPC

这是因为我们添加的虚拟环境没法有安装这个openOPC组件,这里我们移除这个虚拟环境使用电脑安装好的python27环境即可,如下图:

 

  移除虚拟环境后,我的系统会默认使用python3.6,需要把python2.7设置这个工程的默认执行环境,如下图:

 

 python环境切换成全局的python2.7后我们在F5运行测试,每次点击“test”按钮UI都会刷新从服务端获取到的tag Random.Int1 的当前值。

 

2.6.小结

  本小节,通过设立一个小目标(1亿元)我们完成了页面UI通过主动刷新(通过按钮Click事件) 采用ajax异步请求方式从后台读取静态数据,到读取OPC tag位号值的演进过程,结合上一篇的代码我们就实现了UI端展现OPC tag 位号值的原型验证过程,下一篇,我们会进步优化这个页面,实现页面的动态自动刷新。