IEC-104協(xié)議
一 IEC104協(xié)議介紹
1 IEC104簡要說明
IEC104是一種基于TCP/IP的電力行業(yè)通信協(xié)議,主要用于數(shù)據(jù)遠程監(jiān)控等功能。通信有一般有主要發(fā)送數(shù)據(jù)、接收命令的從站服務端和接收數(shù)據(jù)、發(fā)送命令的主站客戶端構(gòu)成。采用應答式數(shù)據(jù)傳輸,一般上行數(shù)據(jù)為遙信、遙測,下行信息為遙控、遙調(diào)。
2 IEC104幀格式
IEC104的通用幀格式如圖

其中APCI為控制信息部分,ASDU為存儲數(shù)據(jù)單元,APDU為長度等于APCI+ASDU-2,即減去起始字節(jié)和APDU長度字節(jié)。 IEC104有3種幀格式,分別為U幀即控制報文幀、S幀即監(jiān)視幀和I幀即信息傳輸幀。
- U幀:只包括APCI部分,主要有啟動幀、停止幀、測試幀。U幀具體格式如圖

- S幀:只包含APCI部分。S幀格式如圖

- I幀:包含APCI+APDU部分。I幀格式如圖

發(fā)送序號和接收序列號是保證數(shù)據(jù)完整性的條件。 類型標識定義發(fā)送數(shù)據(jù)的格式。 可變結(jié)構(gòu)體定義發(fā)送數(shù)據(jù)信息是有序還是無序,有序即一個信息體地址,元素的對應地址會在此信息地址基礎(chǔ)上依次加1。無序即1個地址對應一個元素。 傳輸原因定義記錄傳送的原因,用以對傳輸數(shù)據(jù)進行歸類。
3 IEC104規(guī)約流程
- 由客戶端向服務器建立連接,同時,發(fā)送鏈路啟動幀。
- 服務端在收到鏈路啟動幀后,向客戶端發(fā)送啟動確認幀。
- 客戶端收到啟動確認幀后,發(fā)送總召喚命令數(shù)據(jù)請求幀。
- 服務端收到總召喚命令數(shù)據(jù)請求后,發(fā)送總召喚命令數(shù)據(jù)響應幀,然后繼續(xù)發(fā)送總召喚命令數(shù)據(jù)??傉賳久顢?shù)據(jù)發(fā)送完成后,發(fā)送總召喚命令數(shù)據(jù)結(jié)束幀。
- 客戶端在收到總召喚命令數(shù)據(jù)結(jié)束幀后,發(fā)送對時請求幀。
- 服務器收到對時請求幀后,發(fā)送對時響應幀。
- 由服務器主動向客戶端發(fā)送變化數(shù)據(jù)幀。同時,收到客戶端發(fā)送的控制類命令,回復相應的操作結(jié)果。
- 客戶端等到下一個數(shù)據(jù)總召喚命令數(shù)據(jù)周期,重復第4步之后的流程。
二 IEC104通信主站程序總體設(shè)計實現(xiàn)
根據(jù)項目需求和IEC104通信規(guī)約設(shè)計,主要包括遙信、遙測的解析程序功能,遙控、遙調(diào)的組合程序功能,數(shù)據(jù)庫并發(fā)操作。涉及技術(shù)Java面對對象編程,多線程,socket編程,JDBC數(shù)據(jù)庫操作映射API,C3P0高并發(fā)數(shù)據(jù)庫連接池。 首先設(shè)計如圖的目錄結(jié)構(gòu): 其中jdbc 庫文件存儲數(shù)據(jù)庫連接相關(guān)配置的類文件,model庫文件存儲著數(shù)據(jù)庫的對應模型的類結(jié)構(gòu)文件,dao庫文件存儲著數(shù)據(jù)庫操作的類函數(shù)文件,iec104.util存儲著程序處理中所用到的工具類,iec104為程序邏輯主體,存儲著程序的主要處理類函數(shù)文件。 設(shè)計如圖的配置文件目錄
其中typeId.properties存儲著功能類型的數(shù)字對應信息漢字關(guān)系,cause.properties存儲著原因類型數(shù)字對應信息漢字關(guān)系,用于幀格式解析。remote_signal、remote_measure、remote_control、remote_adjust是存儲信息體地址和對應存儲數(shù)據(jù)庫字段關(guān)系文件,用于將設(shè)備狀態(tài)信息存儲到數(shù)據(jù)庫對應數(shù)據(jù)模型或從對應數(shù)據(jù)進行數(shù)據(jù)提取。 設(shè)計主體程序有3部分構(gòu)成,主程序包括配置信息初始化,Socket端口連接初始化,數(shù)據(jù)庫連接配置初始化,線程定時器初始化,啟動鏈路,接收遙信、遙測幀信息解析緩存到對應對象結(jié)構(gòu)體;定時將緩存在遙信、遙測對象結(jié)構(gòu)體的數(shù)據(jù)寫入數(shù)據(jù)庫;遙控、遙調(diào)定時器程序包括根據(jù)讀取數(shù)據(jù)庫對應數(shù)據(jù)信息與緩存字典比較,發(fā)現(xiàn)變化信息組合幀信息并發(fā)送。設(shè)計總體流程圖如圖

三 IEC104主站數(shù)據(jù)庫相關(guān)程序設(shè)計
1 設(shè)備數(shù)據(jù)庫模型類實現(xiàn)
IEC104數(shù)據(jù)庫與Web管理系統(tǒng)共用一個數(shù)據(jù)庫,IEC104需建立的數(shù)據(jù)庫模型與web模型的屬性、字段都相同,在此基礎(chǔ)建立數(shù)據(jù)庫映射操作庫model中的映射實現(xiàn)類如圖

其中DevControl為存儲所有設(shè)備信息及其控制部分的映射實現(xiàn)類,PVAnalogQuantotyData1, PVAnalogQuantotyData1,PVDigtialQuantityData為具體設(shè)備(光伏逆變器)類的數(shù)字信息和模擬量信息映射實現(xiàn)類。
2 IEC104設(shè)備數(shù)據(jù)庫操作類實現(xiàn)
model每個類文件會對應數(shù)據(jù)庫操作dao庫中一個類文件,dao的類中會記錄數(shù)據(jù)庫操作所需要執(zhí)行的增刪改查操作。目錄結(jié)構(gòu)如圖:
以DevControlDao實現(xiàn)類為例簡要說明: 添加設(shè)備實現(xiàn)函數(shù)核心sql操作語句
Strning sql = "insert into microgrids_devcontrol (num, dev_type) values(?,?)";
更新設(shè)備類型號碼實現(xiàn)函數(shù)核心sql操作語句
Strning sql = "update microgrids_devcontrol set dev_type=? where num=?";
刪除設(shè)備類實現(xiàn)函數(shù)核心sql操作語句
String sql="delete from microgrid_devcontrol where num=?"
查詢設(shè)備是否存在函數(shù)的核心sql操作語句
String sql="select num from microgrid_devcontrol where num=?"
3 IEC104數(shù)據(jù)庫連接初始化
數(shù)據(jù)庫為考慮大量數(shù)據(jù)寫入時的性能要求,使用了C3P0數(shù)據(jù)庫連接池的方法來增強數(shù)據(jù)庫操作的性能。其中C3P0連接池初始化獲得mysql操作對象的類為jdbc包的C3P0Utils類
public class C3P0Utils {
private static ComboPooledDataSource dataSource = new ComboPooledDataSource("mysql");
public static DataSource getDataSource() {
return dataSource;
}
public static Connection getConnection() {
try {
return dataSource.getConnection();
}catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
其中,系統(tǒng)會調(diào)用主目錄下的c3p0-config.xml文件進行數(shù)據(jù)庫初始化配置,包括連接數(shù)據(jù)庫地址,數(shù)據(jù)庫用戶和密碼。
四 主站核心程序設(shè)計
1 主站設(shè)備信息初始化
首先,程序會在初始化完成時加載配置文件dev.json,dev.json數(shù)據(jù)格式為設(shè)備編號,設(shè)備名,設(shè)備類型編號。(設(shè)備類型對應編號在Django model中進行定義,這里寫入是為便于Web管理操作)
{
"PVI0101":{"name":"光伏1區(qū)光伏逆變器1號", "DEV_TYPE":1},
}
根據(jù)配置文件的設(shè)備信息會去更新數(shù)據(jù)庫DevControl中的設(shè)備信息,對配置信息存在數(shù)據(jù)庫卻不存在的設(shè)備使用dao庫DevControl類下的addDev方法進行添加,對配置信息中不存在設(shè)備數(shù)據(jù)庫卻存在的設(shè)備使用delDev方法進行刪除。根據(jù)設(shè)備類型編號去創(chuàng)建對應設(shè)備遙信,遙測需要的設(shè)備信息結(jié)構(gòu)體,以便在后面獲取數(shù)據(jù)存入對應結(jié)構(gòu)體存儲。
2 主站遙信、遙測程序設(shè)計實現(xiàn)
首先,程序會在初始化加載remote_signal.json、remote_measure.json、遙信、遙測配置文件,配置信息格式主要為信息體地址,對應數(shù)據(jù)庫字段名,對應數(shù)據(jù)庫表單名,對應數(shù)據(jù)庫設(shè)備編號。
{
"14":{"field":"status_down","num":"PVI0101","table_name":"pvdigitalquantitydata","descript":"西科逆變器1_停機","注釋":""},
}
然后,使用多線程Runable類定義遙信、遙測數(shù)據(jù)寫入數(shù)據(jù)庫的方法即將設(shè)備對應數(shù)據(jù)信息結(jié)構(gòu)體(在設(shè)備信息初始化中產(chǎn)生)使用對應sql方法寫入數(shù)據(jù)庫。使用ScheduledExecutorService類初始化遙信、遙測的多線程定時器得到對象service,再使用service下的scheduleAtFixedRate方法定時執(zhí)行信息結(jié)構(gòu)體數(shù)據(jù)寫入數(shù)據(jù)庫方法。
程序在發(fā)送完總召喚命令后會一直使用socket的方法去讀取從站發(fā)送過來的幀數(shù)據(jù)并進行解析,首先會使用Apdu類下的Apdu方法進行解析,獲得幀的啟動幀,APDU長度,發(fā)送序號,接收序列號,控制域信息,根據(jù)控制域信息會進行判斷幀類型,即為I幀,S幀,還是U幀。如果是S幀,或U幀獲取后基本不做處理,主要會進行I幀解析。再判斷是I幀后,會使用Asdu類下的Asdu進行解析,獲取幀的類型標識,傳輸原因,公共地址,可變結(jié)構(gòu)體等信息,然后使用InformationObject類的InformationObject方法去根據(jù)幀的類型標識去把數(shù)據(jù)信息存入到InformationElement,再獲取存在信息體地址和數(shù)據(jù)的InformationObject對象。最后,再使用Client類中handleData方法,根據(jù)信息體地址從遙信、遙測配置文件獲取其在數(shù)據(jù)庫的表單名,對應字段,對應設(shè)備,把信息體對應的數(shù)據(jù)寫入到對應的設(shè)備信息結(jié)構(gòu)體中。 使用PMA軟件模擬從站進行遙信測試如下: 首先啟動程序建立鏈接,并發(fā)送總召喚命令,如圖

從站PMA地址發(fā)送地址為14,值為0的遙信數(shù)據(jù)(逆變器PV0101停機信號),如圖


主站接收遙信幀并進行解析,打印解析信息如圖

數(shù)據(jù)庫對應更新遙調(diào)信息所需要修改數(shù)據(jù)庫數(shù)據(jù)如圖

web管理系統(tǒng)界面PVI0101對應數(shù)據(jù)信息改變?nèi)鐖D

3 主站遙控、遙調(diào)程序設(shè)計實現(xiàn)
首先,程序會在初始化加載remote_control.json、remote_adjust.json、遙控、遙調(diào)配置文件,配置信息格式主要為信息體地址,對應數(shù)據(jù)庫字段名,對應數(shù)據(jù)庫設(shè)備編號。
{
"25089":{"field":"active_power","num":"PVI0101","descript":"西科逆變器1_有功功率遙調(diào)值","注釋":""},
}
然后,定義存儲遙控、遙調(diào)信息即地址信息和數(shù)據(jù)信息實時值的字典(記錄實時值,是為了只在數(shù)據(jù)庫數(shù)據(jù)狀態(tài)改變的情況下,才會去發(fā)送遙控或遙信命令)
// 記錄存儲遙控、遙調(diào)實時值
Map<String, Integer> remoteControlValues = new HashMap<String,Integer>();
Map<String, Double> remoteAdjustVlaues = new HashMap<String,Double>();
之后,會使用多線程Runable類定義遙控、遙調(diào)信息幀組合并發(fā)送的runnable_db_send方法。同樣使用ScheduledExecutorService類初始化遙信、遙測的多線程定時器得到對象service_A,再使用service_A下的scheduleAtFixedRate方法定時執(zhí)行。 Runnable_db_send方法會提取remote_control.json、remote_adjust.json配置文件信息,根據(jù)地址信息的字段和編號去數(shù)據(jù)庫對應的表單下去提取數(shù)據(jù),對比remoteControlValues、remoteAdjustVlaues字典,如果和字典中信息不同,則更新字典信息并發(fā)送遙控、遙調(diào)命令。 使用PMA模擬從站測試如下: Web管理界面修改逆變器PV0101的控制信息(會更改對應數(shù)據(jù)庫數(shù)據(jù)),如圖

IEC104主站發(fā)送相關(guān)遙控、遙調(diào)命令,并打印信息,如圖

PMA從站會接收到IEC104主站的遙控、遙調(diào)信息,如圖
