背景:隨着國家工業2025戰略的推進,工業互聯網發展將會提速,將迎來一個新的發展時期,設備的在線監控IOT應用將越來越廣,這個系列文章嘗試用主流的互聯網開發技術,在工業互聯網的監控領用做一個基於B/S架構的探索。筆者對於工業互聯網監控也有幾點感受就是現在好多企業項目越來越多的采用WebGL做三維動畫交互式監控內容越走越復雜、越做越炫,首頁就是工廠的3D鳥瞰圖,模擬工廠三維布局,演示虛擬工廠效果,對於參觀訪問者看起來的確高大上,但是對於熟悉現在工藝設備的操作人員來說,反而不是很實用,直觀2D線條圖很容易方便查看產線設備的整體運行情況,交互式3D畫面更適合培訓和參觀。所以估計縮略的2D線條圖的監控畫面還會長期與3D監控圖並存,用來監控簡化的產線全局運行工況。
前面章節我們演示了如何從一個需求(問題)開始,然后,拆解需求(問題);其次,解決拆解需求(問題)的點;再次,通過的不斷技術摸索和迭代找到一個個合理的解決需求的方法和手段,最終,完成了這個需求(問題)的技術驗證原型。接下來的章節我們將演示原型是如何通過演化,逐步的變成一個真正的項目的實戰過程。
解題思路:如驗證原型一樣,先實現靜態界面的展示效果,然后動態刷新變化的3個監控tag點的數字就基本上解決了上述需求(問題)。
1.工業監控項目實戰1—UI
現在回到一開始的需求(問題)點,下面這張監控圖。如很多開發者的思路一樣,第一步也是先從UI界面的繪制開始,用html描述語言完成畫面的靜態繪制,效果如下圖:
1.1. 新建項目和環境准備
本小節起開始為了方便以及與筆者后面的django內容關聯,文中的所有案例將采用python3.6和django 2.1作為基本運行環境來演示相關程序代碼。
前面的章節我們以簡單圖文的形式知識介紹了如何在IDE環境里創建一個新的項目,現在我們通過VS Communit 2019 File->new->project 菜單創新的Blank Django Web Project項目名為CollectorSvr,如下步驟:
- 新建項目
2. 選擇選擇 Blank Django Web Project 項目類型
3. IDE python環境安裝pip install django==2.1 (不熟悉的參考前面文章 websocket實時的監控畫面)
4. 最后把解決方案重命名為demo,后面系列文章中涉及到的其它項目我們將在添加到demo解決方案下面。
1.1.1. 項目添加Django APP
現在django項目還需要一個實現具體業務的app,來編寫我的業務邏輯和UI,為了簡化案例的復雜度,UI和后台url將都編寫在CollectorSvr上。
讓我們通過IDE環境在項目中添加一個名為Collector Django APP,如下圖:
到這步驟我們就換成了基於 python3.6和django 2.1項目的准備工作,接下來我們來演示如何一步一步的實現本文開頭的監控界面效果。項目結構如下圖:
1.2. Bootstrap前端組件庫
本文采用Bootstrap作為前端展現的組件庫, Bootstrap是全球最受歡迎的前端組件庫,用於開發響應式布局、移動設備優先的 WEB 項目。Bootstrap 是一個用於 HTML、CSS 和 JS 開發的開源工具包。利用 Bootstrap 提供的 Sass 變量和混合(mixins)、響應式柵格系統、可擴展的預制組件以及強大的 jQuery 插件,能夠讓你快速地開發出產品原型或構建整個 app。
版本:v4.4.1
首先,在上面創建的Collector app templates目錄下中添加一個新的html頁面文件,命名為tank4C9.html,並采用國內cdn的方式引用Bootstrap 組件css和js文件。
<link href="https://cdn.bootcss.com/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/4.4.1/js/bootstrap.min.js"></script>
然后,本小節我們直接背景圖和bootstrap行列布局來實現數據在背景圖上的布局效果,我們把原圖修改成下圖:
圖片拖放到Collector app的靜態文件架中\static\img,這個兩個目錄需要通過IDE環境在Collector app創建,如圖:
其次,tank4C9.html監控界面UI中,主要采用class="row"和class="col-sm 行列方式來實現顯示文本的布局工作,col-sm-5 數字5 是列的寬度,也采用了 作為占位符。
頁面完整實現代碼:
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8" /> <title>Tank 4C9</title> <link href="https://cdn.bootcss.com/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/4.4.1/js/bootstrap.min.js"></script> <style type="text/css"> .bg { background:url(../../static/img/tank4C9-1.png) no-repeat left; background-size:contain; } </style> </head> <body> <div class="container-fluid bg" style="height:455px;background:url(../../static/img/tank4C9-1.png) no-repeat left;background-size:contain;"> <div class="row"> </div> <div class="row"> </div> <div class="row"> <div class="col-sm"></div> <div class="col-sm"><strong class="text-warning">100</strong><strong> mm/sΛ2</strong></div> <div class="col-sm"></div> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> <div class="col-sm"></div> <div class="col-sm-2"> <strong class="text-success" >200</strong><strong> kWh</strong></div> <div class="col-sm-9"></div> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> <div class="col-sm-5"></div> <div class="col-sm-2"><strong class="text-danger" >300</strong><strong> mm/sΛ2</strong></div> <div class="col-sm-5"></div> </div> </div> </body> </html>
1.3. 發布django項目urls
頁面tank4C9.html代碼完成后,需要通過django項目把app頁面發布urls上,這樣調試運行項目后,我們wo才能通過url訪問頁面查看頁面訪問效果。
1. 修改Collector app views文件添加tank4C9函數
def tank4C9(request): assert isinstance(request, HttpRequest) return render( request,'Collector/tank4C9.html',)
2. 修改項目settings文件INSTALLED_APPS,添加Collector app
INSTALLED_APPS = [ # Add your apps here to enable them 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'Collector', ]
3. 修改項目urls文件urlpatterns ,發布tank4C9 path
from django.urls import path from Collector import views urlpatterns = [ # Uncomment the next line to enable the admin: #path('admin/', admin.site.urls) path('tank4C9/', views.tank4C9), ]
1.4. 調試瀏覽靜態頁面
現在調試運行項目我們就可以本地瀏覽完成的頁面效果了,為了調試方便筆者同樣設置了項目的調試端口:8090。
現在按F5運行IDE調試環境,就可以在彈出的默認瀏覽器地址欄輸入頁面訪問地址:http://127.0.0.1:8090/tank4C9/ 查看頁面效果了。
頁面還是一個數字不會刷新的靜態頁面,但是監控效果圖已經到達了初步的顯示效果,接下來我們采用前面原型的ajax輪詢實現3個監控tag位號的數字動態刷新。
1.5. 輪詢的動態頁面
我們Collector APP提供一個webAPI 來返回動態的模擬數據函數,通過引入random來模擬變化的設備tag位號值,並返回json格式數據到請求端。
1. Collector APviews 增加函數getTank4C9Data 代碼如下:
import random def getTank4C9Data(request): tank4C9={ 'Status': random.randint(0,1), #設備運行狀態 'OverheadFlow':random.randint(1,10) ,#'頂流量', 'ButtomsFlow': random.randint(1,10), #'低流量' 'Power': random.randint(10000,100000), #功率 } return HttpResponse( json.dumps(tank4C9));
2. 修改項目urls文件urlpatterns ,發布getTank4C9Data path
from django.urls import path from Collector import views urlpatterns = [ # Uncomment the next line to enable the admin: #path('admin/', admin.site.urls) path('tank4C9/', views.tank4C9), path('getTank4C9Data/', views.getTank4C9Data), ]
項目調試狀態我們可以通過瀏覽器直接訪問url查看webAPI結果
http://127.0.0.1:8090/getTank4C9Data/
1.5.1. 參考原型的ajax輪詢修改tank4C9.html代碼實現ajax輪詢
頁面代碼
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8" /> <title>Tank 4C9</title> <link href="https://cdn.bootcss.com/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <!--<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.slim.min.js"></script>--> <script src="https://cdn.bootcss.com/twitter-bootstrap/4.4.1/js/bootstrap.min.js"></script> <style type="text/css"> .bg { background:url(../../static/img/tank4C9-1.png) no-repeat left; background-size:contain; } </style> </head> <body> <div class="container-fluid bg" style="height:455px;background:url(../../static/img/tank4C9-1.png) no-repeat left;background-size:contain;"> <div class="row"> </div> <div class="row"> </div> <div class="row"> <div class="col-sm"></div> <div class="col-sm"><strong class="text-warning" id="OverheadFlow">100</strong><strong> mm/sΛ2</strong></div> <div class="col-sm"></div> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> <div class="col-sm"></div> <div class="col-sm-2"> <strong class="text-success" id="Power">200</strong><strong> kWh</strong></div> <div class="col-sm-9"></div> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> </div> <div class="row"> <div class="col-sm-5"></div> <div class="col-sm-2"><strong class="text-danger" id="ButtomsFlow">300</strong><strong> mm/sΛ2</strong></div> <div class="col-sm-5"></div> </div> </div> <script> //JQuery 代碼入口 $(document).ready(function(){ setInterval("getData()",1000); }); function getData() { //模擬異步從后台獲得值 $.ajax({ url: "/getTank4C9Data/", success: function (result) { data = JSON.parse(result); $("#OverheadFlow").html(data.OverheadFlow); $("#ButtomsFlow").html(data.ButtomsFlow); $("#Power").html(data.Power); }}); } </script> </body> </html>
調試運行
1.6.總結
本小節我們演示了監控項目實戰的UI界面效果和如何實現數據從后台到UI端傳輸,同時,實現了基於ajax輪詢的動態頁面效果,文末的gif也顯示了動態刷新的頁面監控情況。傳輸數據我們用了主流的Json格式,便於在UI同通過JSON對數據進行解析和使用。當然本文的案例界面簡潔明快。
下一篇我們將進一步對數據格式進行封裝,並進一步通過模擬讀取OPC服務的tag位號值來模擬通過OPC DA完成讀取設備工藝數據的實時監控tag值。