⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iec103_sf.cpp

📁 四方公司103规约
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			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*)&para))
			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*)&para))
				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 + -