📄 iec103_sf.cpp
字号:
pFmt->head.vsq.vsq = 0x81;
pFmt->head.cot = C_QUERY_STAR;//0x09;//通用分类总召唤
pFmt->head.addr = addr;
pFmt->head.fun = GEN_FUN;//0xFE;//254
pFmt->head.inf = GenericQuery;//0xF5;//245
pFmt->rii = m_IEC103Data.m_bySin++;
pFmt->nog = 0;
m_IEC103Data.m_wSendNum = sizeof(ASDU_21_Qury);
}
else
{
ASDU_21_Fmt* pFmt = (ASDU_21_Fmt*)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
pFmt->head.type = C_GC_NA_3;//0x15;
pFmt->head.vsq.vsq = 0x81;
pFmt->head.cot = M_AFM_GENRD;//0x2A;//通用分类读命令
pFmt->head.addr = addr;
pFmt->head.fun = GEN_FUN;//0xFE;
pFmt->head.inf = ReadGroupAttrVal;//0xF1;//241读一个组的全部条目的值或属性
pFmt->rii = m_IEC103Data.m_bySin++;
pFmt->nog = 0x01;
if (pRunIED->bDdQury)//召唤电度量
{
pFmt->group = pRunIED->Grouptotype[eDD].gingroup;//0x0A
//printf("遥脉召唤:pFmt->group = %d\n",pFmt->group);
}
else
{
pFmt->group = pRunIED->Grouptotype[eYC].gingroup;//0x09; //召唤遥测量
//printf("一般模拟量召唤:pFmt->group = %d\n",pFmt->group);
}
pFmt->entry = 0x00;
pFmt->kod = ActVal_kod;//0x01; //描述类别:实际值
m_IEC103Data.m_wSendNum = ASDU21FMTLEN;
}
PackLPDU(byNodeID,SendCon_code);
}//end Pack_ASDU21()
//任务组帧
BOOL CIEC103_SFPtl::PackTask(void)
{
TASK *pTask = NULL;
pTask = m_pCH->GetTask();
//printf("服务:%d,目标ID:%d,任务类型:%d\n",pTask->bySrcServID,pTask->byDestNodeID,pTask->eTaskType);
// 检索通道命令
if (!pTask)
return FALSE;
// 时间校准命令
if (taskAdjustTime == pTask->eTaskType)
{
return FALSE;
/*m_bAdjustTime = true;
return SendAdjustTime103(pTask); */
}
RealRunIED *pDevRun = m_IEC103Data.m_RunIed[pTask->byDestNodeID];
if(!pDevRun)
return FALSE;
if (tsNull == pTask->eStatus)
return FALSE;
//判断是否任务队列已经冻结,如果没有冻结认为是新任务,则清数据区
// 任务检测:数据区、设备描述区、系统描述区
// if(!m_pCH->m_pTaskQue->IsLock())
{
memset(&m_IEC103Data.m_task103, 0, sizeof(m_IEC103Data.m_task103));
// 记录规约运行号
m_IEC103Data.m_task103.wStep = 0;
m_IEC103Data.m_task103.task = *pTask;
}
BOOL bRtn = FALSE;
//在下列任务类型中选择需要冻结得任务类型,然后调用冻结函数冻结任务队列
//在解帧函数中,调用解除任务队列冻结函数
if (!PackLinkCmm(pTask->byDestNodeID))
{
switch(pTask->eTaskType)
{
// 任务类型
case taskCmdYkSelect: // 遥控选择
case taskCmdYkExecute: // 遥控执行
case taskCmdYkCancel: // 遥控取消
{
//printf("遥控任务:%d\n",pTask->eTaskType);
if (m_IEC103PtlPara.bGenSel)//与召唤电度量相同
{
bRtn = Pack_GenYK(pTask,pDevRun);
}
else
bRtn = PackYaoKong(pTask, pDevRun);
// if(bRtn)
// m_pCH->m_pTaskQue->LockTask();
}
break;
case taskAskBhYc: //保护相关:模拟量、定值、复归
{// 召唤保护模拟量
bRtn = PackCallProtMea(pTask, pDevRun);
// if(bRtn)
// m_pCH->m_pTaskQue->LockTask();
}
break;
case taskAskBhdz:
{// 召唤保护定值
bRtn = PackCallProtSetting(pTask, pDevRun);
// if(bRtn)
// m_pCH->m_pTaskQue->LockTask();
}
break;
case taskCmdModifyBhdz:
{// 修改保护定值
bRtn = PackModifyProtSetting(pTask, pDevRun);
// if(bRtn)
// m_pCH->m_pTaskQue->LockTask();
}
break;
case taskCmdEnableBhdz:
{// 确认保护定值
bRtn = PackEnableProtSetting(pTask, pDevRun);
// if(bRtn)
// m_pCH->m_pTaskQue->LockTask();
}
break;
case taskCmdCancelBhdz:
{// 取消修改保护定值
bRtn = PackCancelProtSetting(pTask, pDevRun);
// if(bRtn)
// m_pCH->m_pTaskQue->LockTask();
}
break;
case taskCmdSetBhdzGroup:
{// 设置保护定值组
bRtn = PackModifyProtSettingGroup(pTask, pDevRun);
// if(bRtn)
// m_pCH->m_pTaskQue->LockTask();
}
break;
case taskCmdEnableBhdzGroup:
{// 确认设置的保护定值组
bRtn = PackEnableProtSettingGroup(pTask, pDevRun);
// if(bRtn)
// m_pCH->m_pTaskQue->LockTask();
}
break;
case taskCmdCancelBhDzGroup:
{// 取消修改定值组号
bRtn = PackCancelProtSettingGroup(pTask, pDevRun);
// if(bRtn)
// m_pCH->m_pTaskQue->LockTask();
}
break;
case taskCmdBhReset: // 保护复归
{
//printf("进入保护复归组帧函数:%d\n",taskCmdBhReset);
bRtn = PackProtRes(pTask, pDevRun);;
//m_pCH->m_pTaskQue->LockTask();
}
break;
case taskChThree:
{// 通道任务
bRtn = ChanTask(pTask, pDevRun);
// if(bRtn)
// m_pCH->m_pTaskQue->LockTask();
}
break;
default: // 其他类型任务不支持
pTask->eStatus = tsNull;
break;
}
if (!bRtn && tsNull != pTask->eStatus) //当bRtn为False,执行if中的语句
{
// 召唤1级数据
BYTE byCode = CallClass2_code;
if (pDevRun->acd)
byCode = CallClass1_code;
PackLPDU_Fix(pTask->byDestNodeID, byCode);
bRtn = TRUE;
}
}
return bRtn;
}
// 通道任务 - 校时
BOOL CIEC103_SFPtl::SendAdjustTime103(TASK* pTask)
{
ASDU_6_Fmt *pFmt = (ASDU_6_Fmt *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
memset(pFmt, 0, sizeof(ASDU_6_Fmt));
pFmt->head.type = 6;
pFmt->head.vsq.vsq = 0x81;
pFmt->head.cot = 8;
pFmt->head.addr = 0xff;
pFmt->head.fun = 0xff;
pFmt->head.inf = 0;
TIME_STRUCT st;
g_pMainApp->GetSystime(&st);
pFmt->dataTime.year = st.nYear % 100;
pFmt->dataTime.month = st.byMonth;
pFmt->dataTime.bay = st.byDay;
pFmt->dataTime.week = 0;
pFmt->dataTime.time.Hours = st.byHour;
pFmt->dataTime.time.Minutes = st.byMinute;
WORD wtmp = st.bySecond * 1000 + st.nMs;
pFmt->dataTime.time.byLowMs = lobyte(wtmp);
pFmt->dataTime.time.byHighMs = hibyte(wtmp);
LPDU_Vol_Head *pHead = (LPDU_Vol_Head *)m_IEC103Data.m_bySend;
memset(pHead, 0, sizeof(LPDU_Vol_Head));
pHead->head1 = pHead->head2 = 0x68;
pHead->len1 = pHead->len2 = ASDU6Fmt_LEN + 2;
pHead->ctrl.funcode = NoReply_code;
pHead->ctrl.prm = 1;
pHead->addr = 0xff;
m_IEC103Data.m_wSendNum = sizeof(LPDU_Vol_Head) + ASDU6Fmt_LEN;
m_IEC103Data.m_bySend[m_IEC103Data.m_wSendNum ++] = SumMod(m_IEC103Data.m_bySend + 4, pHead->len1);
m_IEC103Data.m_bySend[m_IEC103Data.m_wSendNum ++] = 0x16;
pTask->eStatus = tsSuccess;
return TRUE;
}
BOOL CIEC103_SFPtl::SendAdjustTime103(BYTE byaddr)
{
ASDU_6_Fmt *pFmt = (ASDU_6_Fmt *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
memset(pFmt, 0, sizeof(ASDU_6_Fmt));
pFmt->head.type = 6;
pFmt->head.vsq.vsq = 0x81;
pFmt->head.cot = 8;
pFmt->head.addr = byaddr;
pFmt->head.fun = 0xff;
pFmt->head.inf = 0;
TIME_STRUCT st;
g_pMainApp->GetSystime(&st);
pFmt->dataTime.year = st.nYear % 100;
pFmt->dataTime.month = st.byMonth;
pFmt->dataTime.bay = st.byDay;
pFmt->dataTime.week = 0;
pFmt->dataTime.time.Hours = st.byHour;
pFmt->dataTime.time.Minutes = st.byMinute;
WORD wtmp = st.bySecond * 1000 + st.nMs;
pFmt->dataTime.time.byLowMs = lobyte(wtmp);
pFmt->dataTime.time.byHighMs = hibyte(wtmp);
/* m_IEC103Data.m_wSendNum = ASDU6Fmt_LEN;
if (byaddr != 0xff)
{
BYTE byNodeID = m_IEC103Data.m_addrtoID[byaddr];
PackLPDU(byNodeID, SendCon_code);
}
else
*/ {
LPDU_Vol_Head *pHead = (LPDU_Vol_Head *)m_IEC103Data.m_bySend;
memset(pHead, 0, sizeof(LPDU_Vol_Head));
pHead->head1 = pHead->head2 = 0x68;
pHead->len1 = pHead->len2 = ASDU6Fmt_LEN + 2;
if(byaddr == 0xff)
pHead->ctrl.funcode = NoReply_code;
else
pHead->ctrl.funcode = SendCon_code;
pHead->ctrl.prm = 1;
pHead->addr = byaddr;
m_IEC103Data.m_wSendNum = sizeof(LPDU_Vol_Head) + ASDU6Fmt_LEN;
m_IEC103Data.m_bySend[m_IEC103Data.m_wSendNum ++] = SumMod(m_IEC103Data.m_bySend + 4, pHead->len1);
m_IEC103Data.m_bySend[m_IEC103Data.m_wSendNum ++] = 0x16;
}
return TRUE;
}
/************************************************************************/
/* 通用分类服务--遥控 */
/************************************************************************/
BOOL CIEC103_SFPtl::Pack_GenYK(TASK *pTask, RealRunIED *pDevRun)
{
Task103& task = m_IEC103Data.m_task103;
YK_COMMAND* pYkCom = (YK_COMMAND *)(pTask->iUserData);
if(!pYkCom || !pDevRun)
return FALSE;
CIED *pIED = pDevRun->pDevData;
if(!pIED)
return FALSE;
if (pYkCom->byYkNode > pIED->m_IEDConfig.nYkNum)//byYkNode遥控路号
return FALSE;
BOOL bChk = FALSE;
YK_PARA para;
if(!pIED->GetDataPara(dataYk,0,pYkCom->byYkNode,(void*)¶))
return FALSE;
ASDU_10_Head* pFmt = (ASDU_10_Head*)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
pFmt->head.type = 0x0A;
pFmt->head.vsq.vsq = 0x81;
pFmt->head.cot = 0x28;
pFmt->head.addr = para.nReserved0;
pFmt->head.funInf.fun = 0xFE;
pFmt->rii = m_IEC103Data.m_bySin ++;
pFmt->ngd.cont = 0;
pFmt->ngd.count = 0;
pFmt->ngd.num =1;
ASDU_10_Item* pItem = (ASDU_10_Item*)(pFmt + sizeof(ASDU_10_Head));
pItem->gin.group = para.nFun;
pItem->gin.entry = para.nInfo;
pItem->kod = 0x01;
pItem->gdd.byDataTyp= 0x03;
pItem->gdd.byDataSize= 0x01;
pItem->gdd.cont = 0;
pItem->gdd.num = 1;
switch (pTask->eTaskType) //此处代码参考NRRCS9000-N103.cpp文件的遥控命令。
{
case taskCmdYkSelect:
{
pFmt->head.funInf.inf = 0xF9;
if (pYkCom->byAction == yk_PrevH)
{
pItem->byVal = 0x01;
m_IEC103Data.m_OldCmd.dcc.dcs = 1;
bChk = TRUE;
}
else if (pYkCom->byAction == yk_PrevF)
{
pItem->byVal = 0;
m_IEC103Data.m_OldCmd.dcc.dcs = 0;
bChk = TRUE;
}
}
break;
case taskCmdYkExecute:
{
if(pYkCom->byAction == yk_exec)
{
pFmt->head.funInf.inf = 0xFA;
pItem->byVal = m_IEC103Data.m_OldCmd.dcc.dcs;
bChk = TRUE;
}
}
break;
case taskCmdYkCancel:
{
if(pYkCom->byAction == yk_cancel)
{
pFmt->head.funInf.inf = 0xFB;
pItem->byVal = m_IEC103Data.m_OldCmd.dcc.dcs;
bChk = TRUE;
}
}
break;
default:
break;
}
//m_IEC103Data.m_OldCmd.dcc = dcc;
m_IEC103Data.m_wSendNum = sizeof(ASDU_10_Head) + ASDU10ITEMLEN;
PackLPDU(pTask->byDestNodeID, SendCon_code);
return bChk;
}//end Pack_GenYK()
//遥控命令组帧
BOOL CIEC103_SFPtl::PackYaoKong(TASK *pTask, RealRunIED *pDevRun)
{
Task103& task = m_IEC103Data.m_task103;
YK_COMMAND* pYkCom = (YK_COMMAND *)(pTask->iUserData);
if(!pYkCom || !pDevRun)
return FALSE;
CIED *pIED = pDevRun->pDevData;
if(!pIED)
return FALSE;
BOOL bChk = FALSE;
if (0 == task.wStep)
{
task.wStep ++;
FunInf funInf;
if(!GetFunInf(pDevRun->pDevData, dataYk, pYkCom->byYkNode, funInf))// 遥控命令fun+inf
return FALSE;
YK_PARA para;
if(!pIED->GetDataPara(dataYk,0,pYkCom->byYkNode,(void*)¶))
return FALSE;
DCC dcc = {0};
switch(pTask->eTaskType)
{
case taskCmdYkSelect: //遥控选择
dcc.se = 1;
if(pYkCom->byAction == yk_PrevH)
{
dcc.dcs = 2;
bChk = TRUE;
}
else if(pYkCom->byAction == yk_PrevF)
{
dcc.dcs = 1;
bChk = TRUE;
}
break;
case taskCmdYkExecute: //遥控执行
if (pYkCom->byAction == yk_exec )
{
dcc.dcs = (m_IEC103Data.m_OldCmd.dcc).dcs; // 动作类型
bChk = TRUE;
}
break;
case taskCmdYkCancel: //遥控撤销
if (pYkCom->byAction == yk_cancel)
{
dcc.dcs = (m_IEC103Data.m_OldCmd.dcc).dcs; // 动作类型描述
dcc.se = 1;
dcc.act = 1;
bChk = TRUE;
}
break;
default:
break;
}
if (!bChk)
return bChk;
// 记录动作类型描述
m_IEC103Data.m_OldCmd.dcc = dcc;
// 组帧
ASDU_64_Fmt *pFmt = (ASDU_64_Fmt *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
pFmt->head.type = 64;
pFmt->head.vsq.vsq = 0x81;
pFmt->head.cot = 12;
pFmt->head.addr = para.nReserved0;//分cpu地址号
pFmt->head.funInf = funInf;
pFmt->dcc = dcc;
pFmt->rii = m_IEC103Data.m_bySin ++;
m_IEC103Data.m_wSendNum = sizeof(ASDU_64_Fmt);
PackLPDU(pTask->byDestNodeID, SendCon_code);
}
return bChk;
}
//召唤保护模拟量
//召唤保护模拟量,pTask->iUserData数组中填放数据说明
// 0 1.....
// 要召唤模拟量组包含的 通用分类组号
// 通用分类组个数
BOOL CIEC103_SFPtl::PackCallProtMea(TASK *pTask, RealRunIED *pDevRun)
{
Task103 &task = m_IEC103Data.m_task103;
GenerReadDesc &genRead = task.genRead;
if (0 == task.wStep)
{
// 没有保护模拟量,则不进行组帧命令
if(pDevRun->pDevData->m_IEDConfig.nBhAcLoopNum <= 0)
{
return FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -