Client注冊報(bào)告控制塊

報(bào)告服務(wù)是IEC61850進(jìn)行數(shù)據(jù)交互的重要手段,libIEC61850提供了較為全面的報(bào)告手段,包括:數(shù)據(jù)變化、品質(zhì) 變化、數(shù)據(jù)更新、周期性以及總召,基本涵蓋了61850標(biāo)準(zhǔn)中的要求。

一、常用ClientReportControl API

  1. ClientReportControlBlock IedConnection_getRCBValues(IedConnection self, IedClientError* error, char* rcbReference, ClientReportControlBlock updateRcb)

獲取服務(wù)端指定報(bào)告控制塊信息,并將信息返回至 ClientReportControlBlock 對象。輸入?yún)?shù)中要注意rcbReference, 該參數(shù)是該報(bào)告控制塊的引用字符串信息,由:IEDName + LDevice inst + / + LLN0 + . + buffeded + . + report control name. 其中要注意buffered,如果該報(bào)告控制塊是unbuffered,就用"RP"表示,如果是buffered,就用BR表示,例如官方服務(wù)端例子server_example3中的報(bào)告控制塊就可以表示為"simpleIOGenericIO/LLN0.RP.EventsRCB".

  1. void IedConnection_installReportHandler(IedConnection self, char* rcbReference, char* rptId, ReportCallbackFunction handler, void* handlerParameter)

注冊報(bào)告控制塊的處理程序,其中rptId可以通過ClientReportControlBlock_getRptId(ClientReportControlBlock )函數(shù)獲得,也可以通過解析出ICD文件中rptID屬性獲得;ReportCallbackFunction handler是當(dāng)客戶端收到服務(wù)端報(bào)告時(shí)的回調(diào)函數(shù), ReportCallbackFunction 是一個(gè) void (void * parameter, ClientReport report)類型的函數(shù)指針,parameter是需要傳入的參數(shù),report是收到的報(bào)告信息,里面包含了數(shù)據(jù)值、時(shí)標(biāo)等信息。

  1. void ClientReportControlBlock_setTrgOps(ClientReportControlBlock self, int trgOps)

設(shè)置報(bào)告的觸發(fā)條件,使用TRG_OPT_DATA_CHANGED,TRG_OPT_QUALITY_CHANGED,TRG_OPT_DATA_UPDATE,TRG_OPT_INTEGRITY,TRG_OPT_GI宏設(shè)置條件參數(shù),中間可以使用 or 運(yùn)算設(shè)置多個(gè)觸發(fā)條件。

  1. void ClientReportControlBlock_setRptEna(ClientReportControlBlock self, bool rptEna)

使能報(bào)告控制塊。

  1. void ClientReportControlBlock_setIntgPd(ClientReportControlBlock self, uint32_t intgPd)

設(shè)置周期性上報(bào)時(shí)的周期值,以毫秒(ms)為單位。

  1. void IedConnection_setRCBValues(IedConnection self, IedClientError* error, ClientReportControlBlock rcb, uint32_t parametersMask, bool singleRequest)

設(shè)置報(bào)告控制塊參數(shù),獲取到的報(bào)告控制塊可以通過該方法設(shè)置參數(shù),parameterMask可以通過RCB_ELEMENT_系列宏設(shè)置相關(guān)參數(shù),由于該函數(shù)我還不是太深入理解,在此不作太多說明,待以后補(bǔ)完。

  1. void ClientReportControlBlock_setGI(ClientReportControlBlock self, bool gi)

使能總召報(bào)告。

  1. MmsValue* ClientReport_getDataSetValues(ClientReport self)

獲取報(bào)告中的數(shù)據(jù)值。報(bào)告控制塊是和數(shù)據(jù)集(DataSet)關(guān)聯(lián)的,因此這里獲取到的MmsValue是整個(gè)數(shù)據(jù)集的數(shù)據(jù)集合,可以通過MmsValue_getElement(MmsValue *)函數(shù)獲取其中的數(shù)據(jù)對象(DO)或者數(shù)據(jù)屬性(DA)。

這里有個(gè)吐槽的地方,就是這里獲取到的MmsValue是不包含DA或者DO的Reference的,因此如果沒有獲取數(shù)據(jù)集信息,就無法分辨是哪一個(gè)數(shù)據(jù),好在無論任何情況下返回的報(bào)告總是按照數(shù)據(jù)集里的DO或者DA的索引進(jìn)行排序的,通過這里的索引和獲取到的數(shù)據(jù)集索引進(jìn)行匹配,就可以分辨每個(gè)數(shù)據(jù)。

注:由于存在上面這個(gè)問題,因此最好是使用IedConnection_getDataSetDirectory()方法獲取服務(wù)端實(shí)時(shí)的數(shù)據(jù)集信息,而不是通過解析ICD文件獲取,因?yàn)镮CD文件中的順序和名稱很有可能是錯(cuò)誤的。

  1. ReasonForInclusion ClientReport_getReasonForInclusion(ClientReport self, int elementIndex)

獲取報(bào)告原因。報(bào)告原因就是包括了上面提到的5種觸發(fā)條件。elementIndex就是DO或者DA數(shù)據(jù)集中的索引。

二、使用方法

  1. 注冊報(bào)告控制塊

/創(chuàng)建連接/
IedClientError error;
IedConnection con = IedConnection_create();
IedConnection_connect(con, &error, hostname, tcpPort);

/獲取RCB的信息/
ClientReportControlBlock rcb = IedConnection_getRCBValues(con,&error,"simpleIOGenericIO/LLN0.RP.EventRCB", NULL);

/獲取服務(wù)端的實(shí)時(shí)數(shù)據(jù)集信息/
ClientDataSet clientDataSet = IedConnection_readDataSetValues(con, &error, "simpleIOGenericIO/LLN0$Events", NULL);

if (clientDataSet == NULL)
printf("failed to read dataset\n");

bool deletable;
/獲取數(shù)據(jù)集列表,這里要用LinkedList,順序不能錯(cuò)誤,不然在回調(diào)函數(shù)中匹配的數(shù)據(jù)信息就是錯(cuò)誤的/
LinkedList list = IedConnection_getDataSetDirectory(con,&error,"simpleIOGenericIO/LLN0$Events",&deletable);

/注冊收到報(bào)告時(shí)的回調(diào)函數(shù)/
IedConnection_installReportHandler(con, "simpleIOGenericIO/LLN0.RP.EventRCB", ClientReportControlBlock_getRptId(rcb), reportCallbackFunction, (void *)list);

/設(shè)置報(bào)告的觸發(fā)參數(shù),這里設(shè)置了周期性上報(bào)和數(shù)據(jù)改變時(shí)上報(bào)/
ClientReportControlBlock_setTrgOps(rcb, TRG_OPT_INTEGRITY | TRG_OPT_DATA_CHANGED);
/設(shè)置報(bào)告的觸發(fā)參數(shù),使能報(bào)告控制塊/
ClientReportControlBlock_setRptEna(rcb, true);
/設(shè)置報(bào)告的觸發(fā)參數(shù),設(shè)置周期性報(bào)告周期,這里設(shè)置為5000毫秒上報(bào)一次/
ClientReportControlBlock_setIntgPd(rcb, 5000);
/設(shè)置報(bào)告控制塊參數(shù)/
IedConnection_setRCBValues(con, &error, rcb, RCB_ELEMENT_RPT_ENA | RCB_ELEMENT_TRG_OPS | RCB_ELEMENT_INTG_PD |RCB_ELEMENT_DATSET, true);

if (error != IED_ERROR_OK)
printf("report activation failed (code: %i)\n", error);

/* trigger GI report /
/
使能總召喚/
ClientReportControlBlock_setGI(rcb, true);
/
使在報(bào)告控制塊里添加總召喚的參數(shù)*/
IedConnection_setRCBValues(con, &error, rcb, RCB_ELEMENT_GI, true);

while (state == running)
{
;
}

/關(guān)閉報(bào)告控制塊/
ClientReportControlBlock_setRptEna(rcb, false);

  1. 收到報(bào)告時(shí)的回調(diào)函數(shù)

void reportCallbackFunction(void* parameter, ClientReport report)
{
/獲取報(bào)告中的數(shù)據(jù)/
MmsValue* dataSetValues = ClientReport_getDataSetValues(report);
/獲得數(shù)據(jù)集列表/
LinkedList * list = (LinedList *) parameter;

int i;
/*遍歷數(shù)據(jù)集*/
while (LinkedList_getNext(list) != NULL)
{
     /*獲取下一個(gè)節(jié)點(diǎn),可能是為了便于便利,獲取到的LinkedList的實(shí)際值時(shí)從第二個(gè)節(jié)點(diǎn)開始的*/
    list = LinkedList_getNext(list);
    /*獲取上報(bào)原因*/
    ReasonForInclusion reason = ClientReport_getReasonForInclusion(report, i);
    /*這里如果reason是REASON_NOT_INCLUDED,是不能獲取數(shù)據(jù)值的*/
    /*例如像數(shù)據(jù)變化時(shí),可能只上報(bào)了1個(gè)數(shù)據(jù),但是dataSetValues中會有所有數(shù)據(jù)的索引,只不過其他數(shù)據(jù)的reason將會是REASON_NOT_INCLUDED*/
    if (reason != REASON_NOT_INCLUDED) {
    /*這里MmsValue_getBoolean只是假設(shè)返回的都是boolean類型,實(shí)際應(yīng)用中要根據(jù)實(shí)際數(shù)據(jù)類型調(diào)用不同的函數(shù)*/
        printf("  %s : %i (included for reason %i)\n", list->data, i, MmsValue_getBoolean(MmsValue_getElement(dataSetValues, i)), reason);
    }
}

}

作者:fujicororo
來源:CSDN
原文:https://blog.csdn.net/fujicororo/article/details/40741351
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容