本文通過結合上一篇博文《openOPC與監控頁面一》展現瞭如何通過通過一步一步實現UI端到OPC服務端數據刷新的技術驗證過程, ...
本章節,我們繼續完成監控頁面驗證的demo,實現實時從後臺刷新數據到UI端,筆者考慮採用B/S架構來構建這個簡單的監控頁面,下麵將演示這個頁面是如何一步一步來演進,這也是希望告訴讀者,當我們面向一個新的需求時,如何通過技術領域的探索驗證技術路線是否滿足需求。在通過迭代來確保功能滿足需求的同時,如何通過不斷的小步迭代改進技術架構的過程。
目標1:實現一個網頁,通過點擊一個按鈕,然後從後臺抓取某幾個位號的值回傳到UI端更新網頁里div的文本內容。
2.1.安裝集成開發環境
本小節為了提高開發效率,文中演示過程中才用的集成開發環境(IDE),是Visual Studio Community 2019社區版本,可供學習的教育版本和個人開發者使用,同時也授權5人一下的小團隊進行商業開發,另外VS Community 2019有Mac版本,對於鐘愛使用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 來確保滿足openOPC對python2環境的需求。如果環境不對就不能正常的訪問到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 位號值的原型驗證過程,下一篇,我們會進步優化這個頁面,實現頁面的動態自動刷新。