應(yīng)用問(wèn)題
在實(shí)際應(yīng)用中我們經(jīng)常會(huì)遇到這樣的問(wèn)題:在我們構(gòu)建了一個(gè)實(shí)時(shí)監(jiān)控管理系統(tǒng)時(shí),我們可以直接獲得一些被監(jiān)測(cè)量的瞬時(shí)值;在進(jìn)行統(tǒng)計(jì)核算時(shí),這些瞬時(shí)值不能有效地反應(yīng)在一定時(shí)間段內(nèi)的生產(chǎn)產(chǎn)量、原料用量、能源消耗等生產(chǎn)情況。要反應(yīng)類(lèi)似這些信息就需要對(duì)相關(guān)的瞬時(shí)值進(jìn)行累計(jì)計(jì)算,得到即時(shí)累計(jì)值,然后通過(guò)即時(shí)累計(jì)再獲取某時(shí)間段內(nèi)的階段統(tǒng)計(jì)值。
下面我們就介紹一下通過(guò)紫金橋軟件如果實(shí)現(xiàn)這一應(yīng)用需求。
實(shí)現(xiàn)過(guò)程
- 瞬時(shí)值采集及累計(jì)
瞬時(shí)值的采集和累計(jì)過(guò)程是通過(guò)紫金橋的累計(jì)點(diǎn)來(lái)完成的。關(guān)于累計(jì)點(diǎn)各參數(shù)的意思可以查看在線幫助,但這里需要強(qiáng)調(diào)的是一定要注意“時(shí)間基”設(shè)置,否則可能得到錯(cuò)誤的累計(jì)結(jié)果。
再有累計(jì)點(diǎn)的過(guò)程值(PV)表示是被監(jiān)測(cè)量的瞬時(shí)值,需要通過(guò)數(shù)據(jù)連接與I/O數(shù)據(jù)關(guān)聯(lián)起來(lái),這樣才能利用累計(jì)點(diǎn)的計(jì)算功能通過(guò)TOTAL參數(shù)獲取累計(jì)值。如果我們需要系統(tǒng)重新啟動(dòng)后,累計(jì)量能從上次累計(jì)值繼續(xù)累計(jì),我們需要在歷史組態(tài)中將TOTAL參數(shù)的“退出時(shí)保存實(shí)時(shí)值作為下次啟動(dòng)初值”選項(xiàng)選中。
在這里我們建立“累計(jì)量1”和“累計(jì)量2”兩個(gè)累計(jì)點(diǎn),并以這兩個(gè)點(diǎn)為例介紹一下前述需求的實(shí)現(xiàn)過(guò)程。
- 階段累計(jì)量保存及清零
我們假設(shè)要統(tǒng)計(jì)時(shí)間段為每8小時(shí)統(tǒng)計(jì)一次。由于某一時(shí)段內(nèi)的統(tǒng)計(jì)結(jié)果一旦統(tǒng)計(jì)完成就應(yīng)在以后的查詢和使用過(guò)程保持不變,這樣我們可以通過(guò)另外一個(gè)點(diǎn)將這個(gè)統(tǒng)計(jì)結(jié)果保存下來(lái),下次使用時(shí)我們可以直接讀取,而不需要重復(fù)計(jì)算了。這樣也可以簡(jiǎn)化后續(xù)的查詢組態(tài)。
既然這里我們是8小時(shí)統(tǒng)計(jì)一次,我們就可以將系統(tǒng)小時(shí)變量($SYSTEM.Hour)的變化作為事務(wù)處理的觸發(fā)條件(實(shí)際應(yīng)用時(shí),我們可以統(tǒng)計(jì)周期選擇其它觸發(fā)條件)。每當(dāng)系統(tǒng)小時(shí)值發(fā)生變化時(shí),首先檢查是否到了8小時(shí)的時(shí)間間隔,如果到了就將“累計(jì)量1”和“累計(jì)量2”的當(dāng)前值累計(jì)值(參數(shù)TOTAL)通過(guò)歷史插值的方法保存到“累計(jì)統(tǒng)計(jì)1”和“累計(jì)統(tǒng)計(jì)2”過(guò)程值中(參數(shù)PV),然后再將“累計(jì)量1”和“累計(jì)量2”的當(dāng)前值累計(jì)值復(fù)位(清零)。通過(guò)這樣處理我們得到了一個(gè)每8小時(shí)統(tǒng)計(jì)一次的階段累計(jì)量值。
建立步驟如下:
在點(diǎn)組態(tài)中新建兩個(gè)模擬I/O點(diǎn)(累計(jì)統(tǒng)計(jì)1和累計(jì)統(tǒng)計(jì)2)用于形成累計(jì)量1和累計(jì)量2的歷史統(tǒng)計(jì)結(jié)果。
在“數(shù)據(jù)庫(kù)”導(dǎo)航樹(shù)中的“腳本/值改變”下建立值改變動(dòng)作腳本,變量名為“$SYSTEM.Hour”,
腳本如下:
int 開(kāi)始時(shí)刻=0;
int 時(shí)間間隔=8;
if( mod($SYSTEM.Hour + 24 - 開(kāi)始時(shí)刻, 0, 時(shí)間間隔) == 0) then
InsertHisData(累計(jì)統(tǒng)計(jì)1.PV,累計(jì)量1.Total,$system.Year,
$system.Month,$system.Day,$system.Hour,0,0,0);
InsertHisData(累計(jì)統(tǒng)計(jì)2.PV,累計(jì)量2.Total,$system.Year,
$system.Month,$system.Day,$system.Hour,0,0,0);
累計(jì)量1.RESET=1;
累計(jì)量2.RESET=1;
endif
- 統(tǒng)計(jì)結(jié)果查詢顯示
統(tǒng)計(jì)結(jié)果已經(jīng)有了,下面介紹如何查詢顯示:
假設(shè)我們要查詢的是一天內(nèi)每8小時(shí)的統(tǒng)計(jì)結(jié)果,那么我們首先需要指定查詢?nèi)掌?,這需要使用一個(gè)啟始時(shí)間組件;再有我們需要將查詢的結(jié)構(gòu)顯示出來(lái),這可以通過(guò)一個(gè)自由報(bào)表組件來(lái)完成。下面介紹一下實(shí)現(xiàn)步驟:
A.定義一個(gè)整型中間變量tm,用于要查詢記錄的開(kāi)始時(shí)間。
B.新建一個(gè)窗口,在窗口中建立一個(gè)開(kāi)始時(shí)間組件將其命名為:StartTime;在此開(kāi)始時(shí)間組件的事件腳本中對(duì)其進(jìn)行初始化:
time=$system.longtime;
time = time - GetHour()*3600- GetMinute()*60-GetSecond();//修正為一天啟始時(shí)間
tm = time;
C.再建立一個(gè)自由報(bào)表,進(jìn)入報(bào)表設(shè)置窗口,將報(bào)表第一列顯示屬性設(shè)置為“日期和時(shí)間”型;在這列的第二行、第三行和第四行分別公式:=tm+8*3600、=tm+16*3600、=tm+24*3600。
在第二列的第二行、第三行和第四行分別公式:
=GetHisData2(累計(jì)統(tǒng)計(jì)1.PV,VAL(1,$R),0)
注:GetHisData2為獲得指定數(shù)據(jù)庫(kù)變量,指定時(shí)刻的歷史記錄值;VAL(1,$R)表示獲得第一列,當(dāng)前行單元格內(nèi)的值,即為第一列指定的時(shí)間;這列主要是獲得“累計(jì)統(tǒng)計(jì)1.PV”每8小時(shí)的歷史記錄。
D.在第三列的第二行、第三行和第四行分別公式:
=GetHisData2(累計(jì)統(tǒng)計(jì)2.PV,VAL(1,$R),0)
注:這列主要是獲得“累計(jì)統(tǒng)計(jì)2.PV”每8小時(shí)的歷史記錄。
E.在窗中建立一個(gè)按鈕,在按鈕的鼠標(biāo)自定義動(dòng)作中輸入腳本:tm = #time.time,用來(lái)變換查詢啟始時(shí)間。
小結(jié)
上面例子只是介紹了一下在紫金橋軟件中實(shí)現(xiàn)累計(jì)統(tǒng)計(jì)的一種思路,在實(shí)際應(yīng)用中還會(huì)有許多要處理的事項(xiàng),實(shí)現(xiàn)過(guò)程也要比這復(fù)雜的多。希望這個(gè)小例子能達(dá)到拋磚引玉的作用,對(duì)您解決類(lèi)似問(wèn)題有所幫助。