跨平臺SCADA系統(組態軟件)開發4

四、數據採集

採集功能是整個系統最核心的功能,完成了這一功能,其他部分便水到渠成。數據採集的需求包括:

(1)儀器各種各樣,通信協議五花八門。

(2)軟件開發完成以後,能夠讓不懂代碼的人配置最終產品。

(3)使用多種鏈路,有些儀器共用一條鏈路。

(4)快速採集,有些鏈路或儀器出現問題不影響整個系統的採集。

(5)在採集的同時,反控能及時響應。

上述五個需求,我們在不同的模塊中完成,每個模塊只要做好自己的事情即可。

 

4.1 設備配置和通信協議

這一部分完成的是需求1和2。通信協議完成儀器數據格式的轉化,一般情況下,不同的儀器使用不同的通信協議。但實際上,大部分儀器使用的通信協議都是類似的。例如大部分儀器使用Modbus協議,所不同的是它們使用不同的地址存儲不同的數據。在這種情況下,我們不可能給每一種儀器做一次編碼,只能把Modbus協議編碼出來,而不同的地址對應什麼,就使用設備配置的方法來解決。

系統使用反射的機制開發通信協議,做到靈活增刪通信協議,不影響主程序的發佈。我所經歷過的場景是,每隔幾天就會新增一種儀器,或是其中一種儀器修改了通信協議。在這種情況下,不可能因爲儀器的變動,而推遲整個SCADA系統的發佈。

所有通信協議類都繼承一個基類,基類只有兩個接口函數:ReadValueState(讀取值和狀態)和WriteCommand(寫入命令)。爲每個通信協議創建獨立的項目(爲支持跨平臺,同時基於.NET Core和.NET Framework框架),生成之後,會得到一個dll。我們把這些dll放在某個指定的文件夾內,主程序經過掃描,即得到了通信協議類的列表。通過反射機制,得到每個類的實例,即可調用類的ReadValueState和WriteCommand兩個接口函數。

當有一種新的儀器出現時,我們不需要修改主程序,而只需要新建一個協議項目,把編譯好的dll扔到指定文件夾內,主程序就能支持這些新的儀器。

設備配置是按因子去配置的,以Modbus協議爲例,我們需要爲每個因子配置地址、連續數量、存儲類型(寄存器、線圈等)、讀寫模式、字節順序等。考慮到跨平臺的需求,設備配置的最終結果保存爲JSON文件,這樣在Web端也能輕鬆讀取。

 

4.2 鏈路

鏈路也有一個基類,其接口函數主要有兩個,Send和Receive(當然還有Open和Close這些),它們操作的數據類型都是字節流byte[]。爲了儘可能減少外部對鏈路的瞭解(黑盒化),我們需要在鏈路類裏完成兩個工作:

(1)異步轉同步。爲避免堵塞,鏈路內實際使用異步的方法接收數據。但這種異步回調的方式,不利於外部調用。我們需要把異步轉成同步的方式。外部都是先調用Send,然後等一段時間,再調用Receive。如果沒有數據,說明超時了。

(2)自動重連。在網絡環境中,斷線是很常見的,鏈路類需要做到自動發現網絡,自動重新連接。那麼,外部類只要不斷地Send和Receive就可以了。

在開發過程中,有一點需要注意的是,.NET Core本身已經不支持SerialPort(串口)了。我們需要使用第三方的類庫,本系統使用了SerialPortStream。

 

4.3 調度器

最後兩點需求,涉及到一個調度器的開發。我們可以想象,目前採集任務可以簡單用以下代碼表示:

//採集線程
Task.Run(() =>
{
    foreach(Device device in devices)
    {
        device.ReadValueState();
    }
});

//反控線程
Task.Run(() =>
{
    devices[i].WriteCommand("cmd");
});

採集線程不斷地調用協議類裏的ReadValueState,而這個接口函數內部,必定是調用了鏈路類的Send和Receive(有可能多次)。反控線程可以說是用戶觸發的,不定時地調用WriteCommand,其內部同樣也是調用了鏈路類的Send和Receive。

調度器的任務,就是在一大批Send和Receive下來時,確定什麼時候在哪條鏈路上發送什麼字節流,然後等待多長時間,從這條鏈路接收數據並跟原來的Send匹配。

調度器只使用一個線程,每個發送-接收任務都有一個等待時間(在設備配置時確定)。具體流程如下:

1、調度器先處理新的Send的任務,如果目前Send列表中沒有此任務,則加入到Send列表中。爲了讓反控能及時響應,反控命令的Send任何都是馬上加入,而採集的則稍微延遲加入。

2、根據當前時間,判斷哪些Send任務可以執行,向物理鏈路發送字節流。

3、已經發送的Send任務,改成Receive任務,加入到Receive列表中。

4、根據當前時間,判斷哪些Receive任務可以執行,向物理鏈路接收字節流。

5、把接收到的字節流,作爲回調函數的參數,給協議層使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章