#include "pch.h" #include "ElectricityVOC.h" #include "YD_Public_OCC.h" #include #include #include #include //#ifdef _OCC_MOVE_LINUX //#define CSELEC_DISPATCH_API __declspec(dllexport) //#else //#define CSELEC_DISPATCH_API __declspec(dllimport) //#endif #ifdef _WIN32 // Windows平台 #ifdef _OCC_MOVE_LINUX #define CSELEC_DISPATCH_API __declspec(dllexport) #else #define CSELEC_DISPATCH_API __declspec(dllimport) #endif #else // Linux和其他Unix-like平台 #ifdef _OCC_MOVE_LINUX #define CSELEC_DISPATCH_API __attribute__((visibility("default"))) #else #define CSELEC_DISPATCH_API #endif #endif time_t m_BeginTimeElectricity = -1; int m_timeturns = 3; /******************************************************* 函数名称: Create_Sub_Dispatch 函数功能: 创建子调度模块 输入参数: void 输出参数: nullptr 返回值 : CBaseDispatch* - 子调度模块指针 *******************************************************/ extern "C" CSELEC_DISPATCH_API CBaseDispatch * __stdcall Create_Sub_Dispatch() { printf("-------------ElectricityVOC-Create_Sub_Dispatch--------------------\r"); CBaseDispatch* pPlugin = nullptr; pPlugin = new ElectricityVOC(); return pPlugin; } /******************************************************* 函数名称: Free_Sub_Dispatch 函数功能: 释放子调度模块 输入参数: pPlugin - 子调度模块指针 输出参数: nullptr 返回值 : void *******************************************************/ extern "C" CSELEC_DISPATCH_API void __stdcall Free_Sub_Dispatch(void* pPlugin) { ElectricityVOC* pInstance = (ElectricityVOC*)pPlugin; if (nullptr != pInstance) { delete pInstance; pInstance = nullptr; } } ELCEQPMTALARMINFOMAP ElectricityVOC::m_ElcEqpmtAlarmInfoMap; //计算结果更新线程 xyx新增begin int ObjectPowerValueUpdateAss(void* lpParameter) { if (lpParameter!=nullptr) { ElectricityVOC* lpthis=(ElectricityVOC*)lpParameter; lpthis->m_ObjectPowerThreadOut=false; try { while (!lpthis->m_ObjectPowerThreadOut) { //WaitForSingleObject(m_hExit,INFINITE); lpthis->UpdateEqpmtPowerValue(); //更新设备电气量并发布数据 //ResetEvent(m_hExit); //更新一次完成后,复位触发事件为无信号状态,等待下次触发 } string logstr("调度任务TreadObjectPowerValueUpdateAss线程退出"); lpthis->AddLogItem(logstr,LOG_LEVEL_ERROR); } catch (std::exception& error) { std::ostringstream oss; oss << "TreadObjectCP Have a Error : " << error.what() << ", Trainid = " << lpthis->m_trianid << ", TrainType = " << lpthis->m_subsystype; std::string errorstr = oss.str(); lpthis->AddLogItem(errorstr,LOG_LEVEL_ERROR); } } return 0; } //xyx新增end int GetStationType( int nStation ) { int nRet = StationType_NULL; ELECSTATIONMAP::iterator iterStation =m_MI_powerstation.find(nStation); if ( iterStation != m_MI_powerstation.end() ) { nRet = iterStation->second.stationType; } return nRet; } void GetMainSubStationID( int& nFirstStationID, int& nSecondStationID ) { ELECSTATIONMAP::iterator iterStation =m_MI_powerstation.begin(); for( ; iterStation != m_MI_powerstation.end(); iterStation++ ) { if ( StationType_MainSubStation == iterStation->second.stationType ) { if ( nFirstStationID < 0 ) { nFirstStationID = iterStation->second.stationID; } else { nSecondStationID = iterStation->second.stationID; break; } } } } //电调运算服务,点明这个类的作用 ElectricityVOC::ElectricityVOC(void) { m_subsystype=OCC_SYS_DD_SVR; //InitEqpmtID(); /*PQValuesArray=new DCNodePQValue[All_Power_Station_Nums]; m_AcSysMG=new ACSysMG(); m_DcSysMG=new DCSysMG();*/ //修改初始化位置 PQValuesArray = nullptr; m_AcSysMG = nullptr; m_DcSysMG = nullptr; //m_pBaseElcEqpmt = new BaseElectricEqpmt; } ElectricityVOC::~ElectricityVOC(void) { if (PQValuesArray!=nullptr) { delete[] PQValuesArray; PQValuesArray= nullptr; } for (TrackRelationXDMAP::iterator iterd=m_TrackRelationXDMap.begin();iterd!=m_TrackRelationXDMap.end();iterd++) { if (iterd->second!= nullptr) { delete iterd->second; iterd->second=nullptr; } } ELEEQPMTMAP::iterator iter = ElectricEqpmtMap.begin(); for (;iter!=ElectricEqpmtMap.end();iter++) { if (iter->second==nullptr) { continue; } delete iter->second; iter->second=nullptr; } ElectricEqpmtMap.clear(); EQPMTTELEINFO::iterator iter_tele = m_mapEqpmtTelemetryInfo.begin(); for (;iter_tele != m_mapEqpmtTelemetryInfo.end(); iter_tele++) { delete iter_tele->second; } m_mapEqpmtTelemetryInfo.clear(); //DeleteCriticalSection(&EqpmtMapCriticalSection); } bool ElectricityVOC::GetInteractiveCmds(bool flag) //网络交互信息。。。。消息命令处理,接收网络包消息(主要为教员发所消息) { bool getData = false; OCCCOMMAND tmpItHC; //网路消息包,此结构体包括整个系统的相关定义 if (!m_QI_GetCommands.empty()) //m_QI_GetCommands 接受命令及数据交互时使用该表 { getData = m_QI_GetCommands.pop(tmpItHC);//网路消息队列 } //getData = m_QI_GetCommands.pop(tmpItHC);//网路消息队列 if (getData) { ////////////////////////////////////////////////////////////////////////// if (tmpItHC.TrainningID ==m_trianid)//训练号 { //保护复归信息 if (tmpItHC.cmdType==OCCCOMMAND::eUpdateProtectRest) { NORMALCMDC cmd; cmd.cmdType = Power_Breaker_ProtectReset; cmd.paraInt7 = tmpItHC.ScrNetID;//added by zhangjiahua //strcpy(tmpItHC.Net_Elc_ProtectReset.Eqpmtid, cmd.StrPara1); //strcpy(tmpItHC.Net_Elc_ProtectReset.ProtecResetType); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_Elc_ProtectReset.Eqpmtid); snprintf(cmd.StrPara2, sizeof(cmd.StrPara2), tmpItHC.Net_Elc_ProtectReset.ProtecResetType); _QI_eventF1List.push(cmd); } //保护复归信息 else if (tmpItHC.cmdType == OCCCOMMAND::eUpdateProtectAllRest) { NORMALCMDC cmd; cmd.cmdType = Power_Breaker_ProtectAllReset; //strcpy(tmpItHC.Net_Elc_ProtectAllReset.StationID, cmd.StrPara1, sizeof(cmd.StrPara1)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_Elc_ProtectAllReset.StationID); _QI_eventF1List.push(cmd); } //防灾系统联动 else if (tmpItHC.cmdType == OCCCOMMAND::eUpdateDisasterPrevention) { OCCCOMMAND tmpSendHC; tmpSendHC.setPacketValue(&tmpItHC.Net_Elc_DisasterPreventionToDDsys, OCCCOMMAND::eUpdateMainInOutI); tmpSendHC.DesSysType = OCC_SYS_DD_CLIENT; tmpSendHC.TrainningID = m_trianid;//训练编号 tmpSendHC.ScrSysType = OCC_SYS_DD_SVR; SendNetMsg(tmpSendHC); } else if (tmpItHC.cmdType == OCCCOMMAND::eUpdateFixedValueArea) //设备定值区切换 { NORMALCMDC cmd; cmd.cmdType = Elect_Eqpmt_FixedValueArea; //设备未操作 cmd.paraInt1 = tmpItHC.Net_Elc_FixedValueInfoUpdate.CtrlType; cmd.paraInt2 = tmpItHC.Net_Elc_FixedValueInfoUpdate.FixedArea; //设备控制类型 //Str_To_CharBuf(tmpItHC.Net_Elc_FixedValueInfoUpdate.EqpmtStrID, cmd.StrPara1, sizeof(cmd.StrPara1)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_Elc_FixedValueInfoUpdate.EqpmtStrID); _QI_eventF2List.push(cmd); } //控制闭锁信息 else if ( tmpItHC.cmdType==OCCCOMMAND::eUpdateShieldStatus ) { NORMALCMDC cmd; cmd.cmdType = tmpItHC.Net_Elc_SetShield.ShieldStatus; cmd.paraInt7 = tmpItHC.ScrNetID;//added by zhangjiahua //Str_To_CharBuf(tmpItHC.Net_Elc_SetShield.Eqpmtid, cmd.StrPara1, sizeof(cmd.StrPara1)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_Elc_SetShield.Eqpmtid); _QI_eventF1List.push(cmd); } else if (tmpItHC.cmdType==OCCCOMMAND::eUpdateAutoBolt_CtrlMode) { NORMALCMDC cmd; //cmd.paraInt1 = tmpItHC.Net_Elc_PowerAutoBoltCtrlMode.AutoBoltCtrlMode; cmd.cmdType = tmpItHC.Net_Elc_PowerAutoBoltCtrlMode.AutoBoltCtrlMode; cmd.paraInt1 = m_trianid; cmd.paraInt7 = tmpItHC.ScrNetID;//added by zhangjiahua //Str_To_CharBuf(tmpItHC.Net_Elc_PowerAutoBoltCtrlMode.Eqpmtid,cmd.StrPara1,sizeof(cmd.StrPara1)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_Elc_PowerAutoBoltCtrlMode.Eqpmtid); _QI_eventF1List.push(cmd); } else if (tmpItHC.cmdType == OCCCOMMAND::eUpdateAccident) //更新故障信息 { NORMALCMDC cmd;//线程函数的参数(任务标号) cmd.cmdType = tmpItHC.Net_ELC_Accident.EventType;//Net_ELC_Accident电调的各类故障 cmd.paraInt2 = tmpItHC.Net_ELC_Accident.parm; //Str_To_CharBuf(tmpItHC.Net_ELC_Accident.EqpmtStrID, cmd.StrPara1, sizeof(cmd.StrPara1)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_ELC_Accident.EqpmtStrID); _QI_eventF1List.push(cmd); //F1线程处理 // 转发故障命令到客户端 tmpItHC.DesSysType = OCC_SYS_DD_CLIENT; cmd.paraInt7 = tmpItHC.ScrNetID;//added by zhangjiahua m_pQI_SendCmdsList->push(tmpItHC); } else if (tmpItHC.cmdType == OCCCOMMAND::eUpdateOper) //设备操作命令,,,,消息类型 { printf("-------------ElectricityVOC-eUpdateOper--------------------\r"); printf("-------------ElectricityVOC-eUpdateOper-EqpmtStrID:%s--------------------\r",tmpItHC.Net_DH_EqpmtOper.EqpmtStrID); NORMALCMDC cmd; cmd.cmdType = POWER_EQPMT_OPERNO; //设备未操作 cmd.paraInt2 = tmpItHC.Net_DH_EqpmtOper.EqpmtStatus; cmd.paraInt4 = tmpItHC.Net_DH_EqpmtOper.CtrlType; //设备控制类型 cmd.paraInt5 = tmpItHC.Net_DH_EqpmtOper.OpeMark; cmd.paraInt7 = tmpItHC.ScrNetID;//added by zhangjiahua //Str_To_CharBuf(tmpItHC.Net_DH_EqpmtOper.EqpmtStrID, cmd.StrPara1, sizeof(cmd.StrPara1)); //Str_To_CharBuf(tmpItHC.Net_DH_EqpmtOper.StdName, cmd.StrPara2, sizeof(cmd.StrPara2)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_DH_EqpmtOper.EqpmtStrID); snprintf(cmd.StrPara2, sizeof(cmd.StrPara2), tmpItHC.Net_DH_EqpmtOper.StdName); _QI_eventF2List.push(cmd); } else if (tmpItHC.cmdType == OCCCOMMAND::eUpdateEqpmtTelemeteryValue) //设备设置电压、电流遥测量,,,,消息类型 { NORMALCMDC cmd; cmd.cmdType = Power_EQPMT_TELEMETERYVALUE; //设备设置电压、电流遥测量 cmd.fPara = tmpItHC.Net_DH_EqpmtTelemtryValue.fValue; cmd.paraInt3 = tmpItHC.Net_DH_EqpmtTelemtryValue.nType; //遥测量类型 cmd.paraInt4 = tmpItHC.Net_DH_EqpmtTelemtryValue.IsReset; //是否复位 //Str_To_CharBuf(tmpItHC.Net_DH_EqpmtTelemtryValue.EqpmtStrID, cmd.StrPara1, sizeof(cmd.StrPara1)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_DH_EqpmtTelemtryValue.EqpmtStrID); _QI_eventF2List.push(cmd); } else if (tmpItHC.cmdType == OCCCOMMAND::eUpdateStationCommunication) //设置车站通信状态,,,,消息类型 { NORMALCMDC cmd; cmd.cmdType = POWER_STATIONCOMMUNICATION_SET; //设置车站通信状态 cmd.paraInt1 = tmpItHC.Net_Elc_StationCommunicationStatus.nStationID; //车站 cmd.paraInt2 = tmpItHC.Net_Elc_StationCommunicationStatus.IsReset; //是否复位 _QI_eventF2List.push(cmd); } else if (tmpItHC.cmdType == OCCCOMMAND::eUpdateOperCheck) //设备控制校验,,,设备操作校验 { printf("-------------ElectricityVOC-eUpdateOperCheck--------------------\r"); printf("-------------ElectricityVOC-eUpdateOperCheck-EqpmtStrID:%s--------------------\r", tmpItHC.Net_DH_OperCheck.EqpmtStrID); NORMALCMDC cmd; //常规命令传送使用的结构 typedef struct tgNormalCMDC{}NORMALCMDC; cmd.cmdType = POWER_EQPMT_OPERCHECK; cmd.paraInt1 = tmpItHC.Net_DH_OperCheck.ViewID; //视图ID,用于区分高、中、低压,6个参数,分别为typedef struct tgDHOperCheck的成员变量的值 cmd.paraInt2 = tmpItHC.Net_DH_OperCheck.EqpmtStatus; cmd.paraInt3 = tmpItHC.Net_DH_OperCheck.StdID; //学员ID cmd.paraInt4 = tmpItHC.Net_DH_OperCheck.CtrlArea; //控制区域 cmd.paraInt5 = tmpItHC.Net_DH_OperCheck.Grade; //等级 cmd.paraInt6 = tmpItHC.Net_DH_OperCheck.StationID; //车站ID cmd.paraDWORD1 = tmpItHC.Net_DH_OperCheck.SubSysID; //子系统ID cmd.paraInt7 = tmpItHC.Net_DH_OperCheck.nOperType; //added by zhangjiahua //Str_To_CharBuf(tmpItHC.Net_DH_OperCheck.EqpmtStrID, cmd.StrPara1, sizeof(cmd.StrPara1)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_DH_OperCheck.EqpmtStrID); _QI_eventF2List.push(cmd); } else if (tmpItHC.cmdType==OCCCOMMAND::eUpdateTrain) //车辆更新信息 { DCSysTrain Ptmptrain; //列车信息(与列车相关)类 Ptmptrain.LineSectionID = tmpItHC.Net_XD_SimulateTrain.NoceCircuitryID; //NoceCircuitryID;//列车当前所在轨道电路编号 Ptmptrain.excursion = tmpItHC.Net_XD_SimulateTrain.NoceCircuitryExute; //_XD_行调//列车在当前轨道电路上的偏移 Ptmptrain.arrow = tmpItHC.Net_XD_SimulateTrain.RunArrow; //运行方向 Ptmptrain.PowerRate = tmpItHC.Net_XD_SimulateTrain.PowerRate; //功率(电调用) Ptmptrain.Speed = tmpItHC.Net_XD_SimulateTrain.NoceSpeed; //列车当前速度 Ptmptrain.ID = tmpItHC.Net_XD_SimulateTrain.trainID; //列车ID Ptmptrain.acceleration = tmpItHC.Net_XD_SimulateTrain.A; //当前加速度 Ptmptrain.status = tmpItHC.Net_XD_SimulateTrain.nTrainElectryState; //列车电力状态 Ptmptrain.powerbowstatus = tmpItHC.Net_XD_SimulateTrain.Electricbow; //受电弓 if (m_DcSysMG != nullptr && m_DcSysMG->UpdataTrainData(Ptmptrain)) //用Ptmptrain信息更新列车相关信息 { CheckTrainAccident(Ptmptrain); //校验Ptmptrain是否故障 } } else if( tmpItHC.cmdType == OCCCOMMAND::eMaincontrolInit ) { NORMALCMDC cmd; cmd.cmdType = Elect_Eqpmt_Init; cmd.paraInt7 = tmpItHC.ScrNetID;//added by yangs _QI_eventF2List.push(cmd); } else if ( tmpItHC.cmdType==OCCCOMMAND::eUpdateTurnOffArea ) { NORMALCMDC cmd; cmd.cmdType = Power_HD_Fault; cmd.paraInt1 = tmpItHC.Net_Elc_NetElcTurnOffArea.AreaID; _QI_eventF2List.push(cmd); } else if ( tmpItHC.cmdType==OCCCOMMAND::eUpdateStationThreeLoadCut ) { NORMALCMDC cmd; cmd.cmdType = Power_400V_ThreeLoadCut; cmd.paraInt1 = tmpItHC.Net_Elc_StationThreeLoadCut.StationID; cmd.paraInt2 = tmpItHC.Net_Elc_StationThreeLoadCut.ThreeLoadUnitID; cmd.paraInt3 = tmpItHC.Net_Elc_StationThreeLoadCut.Mark; _QI_eventF2List.push(cmd); } //遥信封锁信息处理 else if(tmpItHC.cmdType==OCCCOMMAND::eUpdateRemoteLock) { NORMALCMDC cmd; cmd.cmdType = tmpItHC.Net_Elc_RemoteLock.isRemoteLock; cmd.paraInt1 = tmpItHC.Net_Elc_RemoteLock.nLockStatus; cmd.paraInt2 = tmpItHC.Net_Elc_RemoteLock.nCtrlType; cmd.paraInt3 = tmpItHC.Net_Elc_RemoteLock.nLockType; cmd.paraInt7 = tmpItHC.ScrNetID;//added by zhangjiahua //Str_To_CharBuf(tmpItHC.Net_Elc_RemoteLock.Eqpmtid, cmd.StrPara1, sizeof(cmd.StrPara1)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_Elc_RemoteLock.Eqpmtid); _QI_eventF2List.push(cmd); } //控制权限转换信息处理 else if (tmpItHC.cmdType==OCCCOMMAND::eUpdateControlPermission) { NORMALCMDC cmd; cmd.cmdType = ControlPermissionChange; cmd.paraInt1 = tmpItHC.Net_Elc_ControlPermission.nStationID; cmd.paraInt2 = tmpItHC.Net_Elc_ControlPermission.nControlArea; cmd.paraInt7 = tmpItHC.ScrNetID;//added by zhangjiahua _QI_eventF2List.push(cmd); } //更新模式信息 else if (tmpItHC.cmdType==OCCCOMMAND::eUpdateModeInfo) { NORMALCMDC cmd; cmd.cmdType = Power_Mode_Control; cmd.paraInt1 = tmpItHC.Net_Elc_ModeControl.ModeID; //模式号 cmd.paraInt2 = tmpItHC.Net_Elc_ModeControl.nModeStatus; //模式运行状态 _QI_eventF2List.push(cmd); } //教员课程事件触发处理 else if (tmpItHC.cmdType==OCCCOMMAND::eDispatchCourseEvent) { if (JY_CourseEventType_DD == tmpItHC.Net_JY_DispatchCourseEvent.nEventType) //课程事件类型-电调 { if ( JY_CourseEventsubType1_DD_Normal == tmpItHC.Net_JY_DispatchCourseEvent.EventSubType1) //事件子类型1-基本事件 { NORMALCMDC cmd; //mod by yangsong 20200311 /* cmd.cmdType = Power_Mode_Control; //(1)模式控制 string strModeID = ""; strcpy(strModeID.GetBuffer(GUID_LEN),tmpItHC.Net_JY_DispatchCourseEvent.AssociPara1); //(2)关联参数1:模式编号(电调各类模式) cmd.paraInt1 = atoi(strModeID); strModeID.ReleaseBuffer(GUID_LEN); cmd.paraInt2 = MODECTRL_STATUS_RUNING; //(3)模式运行状态:默认为模式运行 _QI_eventF2List.push(cmd); //F2线程处理 */ switch(tmpItHC.Net_JY_DispatchCourseEvent.EventSubType2) { case 1://分闸 cmd.cmdType = POWER_EQPMT_OPERNO; //设备未操作 cmd.paraInt2 = 0; cmd.paraInt4 = 2001; //设备控制类型 cmd.paraInt5 = 1; //Str_To_CharBuf(tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2, cmd.StrPara1, sizeof(cmd.StrPara1)); //Str_To_CharBuf("OCC", cmd.StrPara2, sizeof(cmd.StrPara2)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2); snprintf(cmd.StrPara2, sizeof(cmd.StrPara2), "OCC"); _QI_eventF2List.push(cmd); break; case 2://合闸 cmd.cmdType = POWER_EQPMT_OPERNO; //设备未操作 cmd.paraInt2 = 1; cmd.paraInt4 = 2001; //设备控制类型 cmd.paraInt5 = 1; //Str_To_CharBuf(tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2, cmd.StrPara1, sizeof(cmd.StrPara1)); //Str_To_CharBuf("OCC", cmd.StrPara2, sizeof(cmd.StrPara2)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2); snprintf(cmd.StrPara2, sizeof(cmd.StrPara2), "OCC"); _QI_eventF2List.push(cmd); break; case 3://遥信封锁 分 cmd.cmdType = RemoteLock_Set; cmd.paraInt1 = 0; cmd.paraInt2 = 6604; cmd.paraInt3 = RemoteLockType_Off; //Str_To_CharBuf(tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2, cmd.StrPara1, sizeof(cmd.StrPara1)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2); _QI_eventF2List.push(cmd); break; case 4://遥信封锁 合 cmd.cmdType = RemoteLock_Set; cmd.paraInt1 = 1; cmd.paraInt2 = 6604; cmd.paraInt3 = RemoteLockType_On; //Str_To_CharBuf(tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2, cmd.StrPara1, sizeof(cmd.StrPara1)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2); _QI_eventF2List.push(cmd); break; case 5://遥信封锁就地 cmd.cmdType = RemoteLock_Set; cmd.paraInt1 = 1; cmd.paraInt2 = 6602; cmd.paraInt3 = RemoteLockType_Local; //Str_To_CharBuf(tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2, cmd.StrPara1, sizeof(cmd.StrPara1)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2); _QI_eventF2List.push(cmd); break; case 6://遥信解锁 cmd.cmdType = RemoteLock_Cancle; cmd.paraInt1 = 1; cmd.paraInt2 = 6604; cmd.paraInt3 = RemoteLockType_No; //Str_To_CharBuf(tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2, cmd.StrPara1, sizeof(cmd.StrPara1)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2); _QI_eventF2List.push(cmd); break; case 7://控制闭锁 cmd.cmdType = ShieldStatus_Set; //Str_To_CharBuf(tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2, cmd.StrPara1, sizeof(cmd.StrPara1)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2); _QI_eventF1List.push(cmd); break; case 8://闭锁解锁 cmd.cmdType = ShieldStatus_Cancle; //Str_To_CharBuf(tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2, cmd.StrPara1, sizeof(cmd.StrPara1)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2); _QI_eventF1List.push(cmd); break; case 9://故障复归 cmd.cmdType = Power_Breaker_ProtectReset; //Str_To_CharBuf(tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2, cmd.StrPara1, sizeof(cmd.StrPara1)); //Str_To_CharBuf("保护复归", cmd.StrPara2, sizeof(cmd.StrPara2)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2); snprintf(cmd.StrPara2, sizeof(cmd.StrPara2), "保护复归"); _QI_eventF1List.push(cmd); break; case 10://手车试验 cmd.cmdType = RemoteLock_Set; cmd.paraInt1 = 3; cmd.paraInt2 = 6603; cmd.paraInt3 = RemoteLockType_Test; //Str_To_CharBuf(tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2, cmd.StrPara1, sizeof(cmd.StrPara1)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2); _QI_eventF2List.push(cmd); break; case 11://手车工作 cmd.cmdType = RemoteLock_Set; cmd.paraInt1 = 2; cmd.paraInt2 = 6603; cmd.paraInt3 = RemoteLockType_Work; //Str_To_CharBuf(tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2, cmd.StrPara1, sizeof(cmd.StrPara1)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2); _QI_eventF2List.push(cmd); break; default: break; } //mod end } else if ( JY_CourseEventsubType1_DD_Fault == tmpItHC.Net_JY_DispatchCourseEvent.EventSubType1) //事件子类型2-故障事件 { NORMALCMDC cmd; cmd.cmdType = POWER_ERORR_OCCAR; //(1)默认为故障触发 //Str_To_CharBuf(tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2, cmd.StrPara1, sizeof(cmd.StrPara1)); //(2)关联参数2:故障设备编号 //string strFaultID = ""; //strcpy(strFaultID.GetBuffer(GUID_LEN),tmpItHC.Net_JY_DispatchCourseEvent.AssociPara1); //(3)关联参数1:故障类型编号(电调各类故障) //cmd.paraInt2 = atoi(strFaultID); //strFaultID.ReleaseBuffer(GUID_LEN); // snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), tmpItHC.Net_JY_DispatchCourseEvent.AssociPara2); cmd.paraInt2 = atoi(tmpItHC.Net_JY_DispatchCourseEvent.AssociPara1); _QI_eventF1List.push(cmd); //F1线程处理 tmpItHC.DesSysType = OCC_SYS_DD_CLIENT; // 转发故障命令到客户端 m_pQI_SendCmdsList->push(tmpItHC); } } } else if (tmpItHC.cmdType==OCCCOMMAND::eUpdateEqpmtInitStatus)//设备状态初始化 { m_ElectricEvent.EqpmetInit(); if (!m_ElectricEvent.CloseOffSwicth()) //是否关闭开关,,初始化断路器合闸 { return false; } tmpItHC.DesSysType = OCC_SYS_DD_CLIENT; // 转发初始化命令到客户端 m_pQI_SendCmdsList->push(tmpItHC); } else if (tmpItHC.cmdType == OCCCOMMAND::eUpdateDHMsgNotice)//真实设备报警 { tmpItHC.DesSysType = OCC_SYS_DD_CLIENT; // 转发初始化命令到客户端 tmpItHC.ScrSysType = OCC_SYS_DD_SVR; m_pQI_SendCmdsList->push(tmpItHC); } else if (tmpItHC.cmdType==OCCCOMMAND::CMD_INPUT_FROM_IO)//设备状态初始化 { string str1 = tmpItHC.Net_IBP_SERVER.EqpmtStrID; // 设备编号 string str2 = tmpItHC.Net_IBP_SERVER.strParam1; // 字符串参1 string str3 = tmpItHC.Net_IBP_SERVER.strParam2; // 字符串参2 string str4 = tmpItHC.Net_IBP_SERVER.strParam3; // 字符串参3 string str5 = tmpItHC.Net_IBP_SERVER.strParam4; // 字符串参4 DealWith_IBPEvent(tmpItHC.ScrNetID,tmpItHC.Net_IBP_SERVER.nCmdValue,tmpItHC.Net_IBP_SERVER.param1,tmpItHC.Net_IBP_SERVER.param2,tmpItHC.Net_IBP_SERVER.param3,tmpItHC.Net_IBP_SERVER.param4,tmpItHC.Net_IBP_SERVER.nStatus ,str1,str2,str3,str4,str5,tmpItHC.Net_IBP_SERVER.nIBPStationID); } else if ( tmpItHC.cmdType == OCCCOMMAND::eUpdateMSFVO ) //行-电客户端数据转发 { OCCCOMMAND TmpNetCmd = tmpItHC; TmpNetCmd.DesSysType = OCC_SYS_DD_CLIENT; TmpNetCmd.ScrSysType = OCC_SYS_DD_SVR; m_pQI_SendCmdsList->push(TmpNetCmd); TmpNetCmd.DesSysType = OCC_SYS_XD_CLIENT; m_pQI_SendCmdsList->push(TmpNetCmd); } bool bSend = Send_DispatchSys_OperR(tmpItHC,1); } } if (m_ElectricEvent.NeedDelayTimeDeal()) //判断是否需要延时处理 { NORMALCMDC cmd; cmd.cmdType = Power_Deal_DelayTime; _QI_eventF2List.push(cmd); //延时处理由F2线程 } return getData; } void ElectricityVOC::CheckTrainAccident(DCSysTrain& train) //列车事故检查 { if (train.status==OCC_TRAIN_SHROTCUT_STATUS && m_DcSysMG != nullptr) //train是否处于短路状态 { NORMALCMDC cmd; //常规命令数据结构 cmd.cmdType = POWER_ERORR_OCCAR; //事故发生(电力错误) string Str_Temp = ""; Str_Temp = m_DcSysMG->GetTouchNetByPosition(train.LineSectionID,train.excursion); //根据线区ID号和列车偏移量获取接触网的位置 cmd.paraInt2 = 5000; //cmd.paraInt2 = tmpItHC.Net_DH_OperCheck.EqpmtStatus;接触网金属性短路 //Str_To_CharBuf(Str_Temp, cmd.StrPara1, sizeof(cmd.StrPara1)); snprintf(cmd.StrPara1, sizeof(cmd.StrPara1), Str_Temp.c_str()); _QI_eventF1List.push(cmd); } } void ElectricityVOC::UpdateACPowerLineStatus_Init() { if (m_AcSysMG == nullptr) { return; } map::iterator iterEqpmt=m_AcSysMG->m_EqpmtInfoMap.begin(); for (;iterEqpmt!=m_AcSysMG->m_EqpmtInfoMap.end();iterEqpmt++) { PowerLine* pline=(PowerLine*)iterEqpmt->second; int status=1; for (int i=0;im_vecSwitchStrID.size();i++) { ELEEQPMTMAP::iterator iterElc = ElectricEqpmtMap.find(pline->m_vecSwitchStrID[i]); if (iterElc!=ElectricEqpmtMap.end()) { if (!iterElc->second->GetPower()) { status=0; break; } } } pline->SetStatus(status); } } void ElectricityVOC::UpdateNodeStatus_Init() { if (m_AcSysMG == nullptr) { return; } for (int i=0;im_PQNodes.size();i++) { ELEEQPMTMAP::iterator iterElc = ElectricEqpmtMap.find(m_AcSysMG->m_PQNodes[i].BgkID); if (iterElc!=ElectricEqpmtMap.end()) { if (!iterElc->second->GetPower()) { m_AcSysMG->m_PQNodes[i].Status=0; m_AcSysMG->m_PQNodes[i].E=0; m_AcSysMG->m_PQNodes[i].F=0; } else { m_AcSysMG->m_PQNodes[i].Status=1; m_AcSysMG->m_PQNodes[i].E=m_AcSysMG->m_PQNodes[i].m_IniE; m_AcSysMG->m_PQNodes[i].F=m_AcSysMG->m_PQNodes[i].m_IniF; } } } } BOOL ElectricityVOC::InitInstance() //初始化实例 { printf("-------------ElectricityVOC-InitInstance-begin--------------------"); m_ElectricEvent.SetEqpmtMap(&ElectricEqpmtMap, &EqpmtMapCriticalSection, &m_mapEqpmtTelemetryInfo); //电力事件处理 m_ElectricEvent.SetInitInfo(m_pQI_SendCmdsList,m_trianid); //设置初始化信息 //InitializeCriticalSection(&EqpmtMapCriticalSection); if (m_curseinfo.m_nTaskType==CourseType_Examination) { m_ElectricEvent.IsExamMOde=true; } else { m_ElectricEvent.IsExamMOde = false; } if (!InitPowerStationData()) //初始化车站数据 { return FALSE; } if (!m_ElectricEvent.CloseOffSwicth()) //是否关闭开关,,初始化断路器合闸 { return FALSE; } //m_ElectricEvent.SystemInit(); //m_ElectricEvent.EqpmetInit();//added by zhangjiahua 修改设备初始化方式 m_ElectricEvent.SendControlPermission(); SendIniCmd(); //m_hExit= CreateEvent( FALSE, TRUE, nullptr, nullptr ); // 使用lambda std::thread tUpdateAss([this]() { ObjectPowerValueUpdateAss(this); }); // 记得join或detach // join会导致主线线程等待 detach让子线程独自运行 tUpdateAss.detach(); printf("-------------ElectricityVOC-InitInstance-end--------------------"); return TRUE; } int ElectricityVOC::ExitInstance()//释放资源, { //m_RunStatus=DISPATCH_RUN_STATUS_STOP;//运行状态停止 EqpmtMapCriticalSection.lock(); if (m_AcSysMG != nullptr) { delete m_AcSysMG; } if (m_DcSysMG != nullptr) { delete m_DcSysMG; } //added by zhangjiahua m_MultiModeMap.clear(); m_ModeDataMap.clear(); m_ModeIDDataMap.clear(); m_mapPowerValueUpdateEqpmt.clear(); m_ObjectPowerThreadOut=true; m_MI_powerstation.clear(); EqpmtMapCriticalSection.unlock(); return 0; } bool ElectricityVOC::AddStationToPointList()//初始化车站节点 { ELECSTATIONMAP::iterator iter =m_MI_powerstation.begin(); for (int i=0;iter!=m_MI_powerstation.end();++iter,i++) { //PQValuesArray[i].P_HK = 1230000;//副站有功功率 //PQValuesArray[i].Q_HK = 400000; PQValuesArray[i].P_HK = 1000000;//有功功率 PQValuesArray[i].Q_HK = 750000; PQValuesArray[i].StationID=iter->second.stationID; } return true; //需要默认函数继续处理 } bool ElectricityVOC::InitPowerStationData()//初始化车站数据 { //if (!m_DcSysMG->CreateFixYNodes()) // return false; if (!AddStationToPointList()) return false; //if (!m_AcSysMG->CreatePQNodeMatrix()) // return false; if (m_DcSysMG != nullptr) { m_DcSysMG->SetPQValueArr(PQValuesArray);//直流子系统,设置PQ节点数组 } if (m_AcSysMG != nullptr) { m_AcSysMG->SetPQValueArr(PQValuesArray); //交流子系统 } return true; } ////////////////////////////////////////////////////////////////////////// bool ElectricityVOC::EventF1Ass(NORMALCMDC&NCmd)//线程函数,事件处理(svrn) NORMALCMDC为常规命令集 { if ( m_RunStatus != DISPATCH_RUN_STATUS_RUNNING ) { return false; } m_bF1ThreadFinish = false; //根据设备ID的故障类型和对应的参数对故障进行处理 m_ElectricEvent.SetProtectSetStr(NCmd.StrPara1);//获得保护复归断路器设备ID m_ElectricEvent.DealWithAutoBoltCtrlMothod(NCmd.paraInt1,NCmd.StrPara1,NCmd.cmdType); //更新备自投控制模式 m_ElectricEvent.DealEvent(NCmd,NCmd.cmdType,NCmd.StrPara1,NCmd.paraInt2,NCmd.StrPara2);//处理故障(电力事件处理) m_bF1ThreadFinish = true; return true; } ////////////////////////////////////////////////////////////////////////// // 普通事件处理辅助函数 // 返回true表示需要默认函数继续处理 bool ElectricityVOC::EventF2Ass(NORMALCMDC&NCmd) //设备控制线程函数,NORMALCMDC为常规命令传送使用的结构 { if ( m_RunStatus != DISPATCH_RUN_STATUS_RUNNING ) { return false; } m_bF2ThreadFinish = false; if ( POWER_EQPMT_OPERNO == NCmd.cmdType ) //设备未操作(初始状态) { printf("-------------ElectricityVOC-EventF2Ass-EqpmtCtrl--------------------\r"); printf("-------------ElectricityVOC-EventF2Ass-EqpmtCtrl-Timer: %d--------------------\r", GetSys_SecondTime_2()); m_ElectricEvent.EqpmtCtrl(NCmd,NCmd.StrPara1,NCmd.paraInt2,NCmd.StrPara2,NCmd.paraInt4,NCmd.paraInt5);//设备控制函数 } else if (POWER_EQPMT_OPERCHECK == NCmd.cmdType ) //设备操作检查 { printf("-------------ElectricityVOC-EventF2Ass-EqpmtCtrlCheck--------------------\r"); printf("-------------ElectricityVOC-EventF2Ass-EqpmtCtrlCheck-Timer: %d--------------------\r", GetSys_SecondTime_2()); m_ElectricEvent.EqpmtCtrlCheck(NCmd.paraInt1,NCmd.paraDWORD1,NCmd.StrPara1,NCmd.paraInt2,NCmd.paraInt3,NCmd.paraInt4,NCmd.paraInt5,NCmd.paraInt6, NCmd.paraInt7); m_ElectricEvent.SetStaionID(NCmd.paraInt6); m_ElectricEvent.SetViewID(NCmd.paraInt1); m_ElectricEvent.SetSubSystemID(NCmd.paraDWORD1); m_ElectricEvent.SetStdID(NCmd.paraInt3); } else if (Power_Deal_DelayTime ==NCmd.cmdType) //电力延时处理 { m_ElectricEvent.handle_delaytime(); } else if ( Elect_Eqpmt_Init == NCmd.cmdType ) { m_ElectricEvent.SystemInit(NCmd.paraInt7); //m_ElectricEvent.SendControlPermission(); SendIniCmd();//初始化完成后通知客户端 } else if ( Power_HD_Fault == NCmd.cmdType ) { m_ElectricEvent.PowerCutArea( NCmd.paraInt1 ); } else if ( Power_400V_ThreeLoadCut == NCmd.cmdType ) { m_ElectricEvent.Deal400VLoad( NCmd.paraInt1,NCmd.paraInt2,NCmd.paraInt3 ); } else if (RemoteLock_Set == NCmd.cmdType||RemoteLock_Cancle==NCmd.cmdType) { m_ElectricEvent.DealRemoteLock(NCmd); } else if (ControlPermissionChange==NCmd.cmdType) { //ELECSTATIONMAP::iterator iter= m_MI_powerstation.find(NCmd.paraInt1); //if (iter!=m_MI_powerstation.end()) //{ // iter->second.ctrlarea=NCmd.paraInt2; //} //SendControlPermission(); m_ElectricEvent.DealPermissionChange(NCmd); } else if (Power_Mode_Control==NCmd.cmdType) { ModeControlDeal(NCmd.paraInt1,NCmd.paraInt2); } else if(Power_EQPMT_TELEMETERYVALUE == NCmd.cmdType) { m_ElectricEvent.SetEqpmtTelemeteryValue(NCmd.StrPara1, NCmd.paraInt3, NCmd.fPara, NCmd.paraInt4); } else if(POWER_STATIONCOMMUNICATION_SET == NCmd.cmdType) { m_ElectricEvent.DealWith_StationCommunicationStatus( NCmd.paraInt1, NCmd.paraInt2); } else if (Elect_Eqpmt_FixedValueArea == NCmd.cmdType) { m_ElectricEvent.DealWith_EqpmtFixedAreaCtrl(NCmd.StrPara1, NCmd.paraInt1, NCmd.paraInt2, NCmd.paraInt7); } m_bF2ThreadFinish = true; return true; } ////////////////////////////////////////////////////////////////////////// // 事件发起辅助函数 // 返回true表示需要重设时间 bool ElectricityVOC::EventBeginAss(const time_t &time, const time_t &lpTimeSpan)//事件发起辅助函数 { if ( m_RunStatus != DISPATCH_RUN_STATUS_RUNNING && m_RunStatus != DISPATCH_RUN_STATUS_RUNINT ) { return false; } m_bBeginThreadFinish = false; bool bFlag = GetInteractiveCmds(true); m_bBeginThreadFinish = true; return bFlag; } void ElectricityVOC::SendNetMsg(OCCCOMMAND& msg)//发送网络消息 { if (msg.DesSysType==OCC_SYS_DD_GROUP) { m_pQI_SendGroupList->push(msg); } else { m_pQI_SendCmdsList->push(msg); } //Sleep(TIMESPAN_LVS); std::this_thread::sleep_for(std::chrono::milliseconds(TIMESPAN_LVS)); } bool ElectricityVOC::PublishData()//电力数据发布 { if (m_DcSysMG != nullptr) { m_DcSysMG->SetElcEqpmtMap(ElectricEqpmtMap); } ELEEQPMTMAP::iterator iterEqpmtMap; TrackRelationXDMAP::iterator iterTrackMap = m_TrackRelationXDMap.begin(); for (; iterTrackMap != m_TrackRelationXDMap.end(); iterTrackMap++) { iterEqpmtMap = ElectricEqpmtMap.find(iterTrackMap->second->m_strID); if (iterEqpmtMap != ElectricEqpmtMap.end()) { //if (iterEqpmtMap->second->m_TrackRelationXD.m_PreIsPower != iterEqpmtMap->second->m_TrackRelationXD.m_IsPower) { //itetrackXD->second->m_IsPower = trackpower; COMMANDTOXD cmdtoxd; cmdtoxd.type = DDTOXD_ELCTRACK_STATUS; cmdtoxd.ObjectID = iterTrackMap->second->GetNoID(); cmdtoxd.data1 = iterEqpmtMap->second->GetStatus(); cmdtoxd.data2 = iterTrackMap->second->GetDirection(); OCCCOMMAND tmpSendOC; tmpSendOC.cmdType = OCCCOMMAND::CmdType::eCommantoXD; //tmpSendOC.DesSysType = OCC_SYS_XD_CLIENT; tmpSendOC.DesSysType = OCC_SYS_XD_SVR; tmpSendOC.ScrSysType = OCC_SYS_DD_SVR; tmpSendOC.TrainningID = m_trianid; tmpSendOC.DateLen = sizeof(COMMANDTOXD); tmpSendOC.Net_LS_CommandtoXD = cmdtoxd; m_pQI_SendCmdsList->push(tmpSendOC); } //iterEqpmtMap->second->m_TrackRelationXD.m_PreIsPower = iterEqpmtMap->second->m_TrackRelationXD.m_IsPower; } } std::vector PQIUpdataList; //第i个PQ节点数据,,有功无功功率数据节点 if (m_AcSysMG != nullptr) { m_AcSysMG->GetPQIPublishLine(PQIUpdataList); //交流侧,有功、无功和电流数据发布信息列表,第i个节点的有功与无功功率(交流信息) } for(size_t n=0;nGetIPublishLine(PQIUpdataList); //交流侧:获取电流数据发布信息 } for(size_t e=0;eGetMLVPublish(PQIUpdataList); //交流侧:获取母线电压发布数据 } for(size_t k=0;kGetRectiterVPublish(PQIUpdataList); //直流侧:获取整流器电压 } for(size_t j=0;jGetBackVIPublish(PQIUpdataList); //直流侧:获取回流线电流电压发布数据 } for(size_t c=0;cGetTrianVPublish(PQIUpdataList); //直流侧:得到列车电压发布数据 //} //for(size_t j=0;j0 &&updatadata.Trianid < 1000) // { // if (MRunLineID == 200) // { // updatadata.V= PQIUpdataList[j].V/2; // } // else // { // updatadata.V= PQIUpdataList[j].V; // } // // OCCCOMMAND tmpSendHC; // tmpSendHC.setPacketValue(&updatadata,OCCCOMMAND::eUpdateTrainV); // tmpSendHC.DesSysType=OCC_SYS_XD_SVR; // tmpSendHC.TrainningID = m_trianid; // tmpSendHC.ScrSysType=OCC_SYS_DD_SVR; // SendNetMsg(tmpSendHC); // TRACE("列车:%d 网压:%f\n",updatadata.Trianid,updatadata.V); // } //} map TrainMap; if (m_DcSysMG != nullptr) { TrainMap = m_DcSysMG->TrainSInStationMap; } map::iterator iter =TrainMap.begin(); while(iter!=TrainMap.end()) { string touchnet = m_DcSysMG->GetTouchNetByPosition(iter->second.LineSectionID,iter->second.excursion); if (touchnet!="") { ELEEQPMTMAP::iterator iterEqpmet=ElectricEqpmtMap.find(touchnet); if (iterEqpmet!=ElectricEqpmtMap.end()) { TRIANV updatadata; updatadata.Trianid=iter->second.ID; if (iterEqpmet->second->GetStatus()) { updatadata.V=1593.0; } else { updatadata.V= 0.0; } OCCCOMMAND tmpSendHC; tmpSendHC.setPacketValue(&updatadata,OCCCOMMAND::eUpdateTrainV); tmpSendHC.DesSysType=OCC_SYS_XD_SVR; tmpSendHC.TrainningID = m_trianid; tmpSendHC.ScrSysType=OCC_SYS_DD_SVR; SendNetMsg(tmpSendHC); //TRACE("列车:%d 网压:%f\n",updatadata.Trianid,updatadata.V); } } iter++; } //Sleep(TIMESPAN_LVN); std::this_thread::sleep_for(std::chrono::milliseconds(TIMESPAN_LVS)); return true; } ////////////////////////////////////////////////////////////////////////// // 对象计算辅助函数 // 返回true表示需要重设时间 bool ElectricityVOC::ObjectCPAss(const time_t &time, const time_t &lpTimeSpan)//电力模型计算,time线程时间,lpTimeSpan计算周期时间跨度 { //只允许在课程运行阶段进行逻辑判断 if ( m_RunStatus != DISPATCH_RUN_STATUS_RUNNING && m_RunStatus != DISPATCH_RUN_STATUS_RUNINT) { return false; } m_bObjectCPThreadFinish = false; //MOD BY yangs //if(m_RunStatus!= DISPATCH_RUN_STATUS_RUNNING) return false; //只允许在课程运行阶段进行逻辑判断 if (m_RunStatus == DISPATCH_RUN_STATUS_RUNNING) { //m_RunTime = (CTime::GetCurrentTime().GetTime()-m_RunBeginTime) + m_TrainBeginTime; //记录当前仿真时间 //m_CurTime = CTime::GetCurrentTime().GetTime(); //记录当前物理时间 // 获取当前时间毫秒数 auto now = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()).count(); // 计算运行时间 m_RunTime = (now - m_RunBeginTime) + m_TrainBeginTime; m_CurTime = now; /*************************以下本函数原来的部分********************************/ if (m_BeginTimeElectricity < 0) { //m_BeginTimeElectricity = CTime::GetCurrentTime().GetTime(); m_BeginTimeElectricity = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()).count(); } m_ElectricEvent.DealThirdTrackPowerLose(); if (lpTimeSpan > 1) { //add by chenht 2020 0723 /*if ( MRunLineID == 1400 || MRunLineID == 400 || MRunLineID == 300 || MRunLineID == 314 || MRunLineID == 324 || MRunLineID == 331 || MRunLineID == 325)*/ { ElcTrackInfo_2_XD(); m_bObjectCPThreadFinish = true; return true; } //2011-10-8无法运行时候屏蔽 if (m_DcSysMG==nullptr) { m_bObjectCPThreadFinish = true; return false; } m_DcSysMG->CreateFixYNodes(); m_DcSysMG->CheckSpanNetInfo(); //added by zhangjiahua m_DcSysMG->AdjustShortCutNode(); m_DcSysMG->CalculValue(); //计算直流信息数据 if (m_DcSysMG->HaveRightResult()) //计算电力模型,计算结果正确性的判断 { //2011-10-8无法运行时候屏蔽 if (m_AcSysMG==nullptr) { m_bObjectCPThreadFinish = true; return false; } UpdateACPowerLineStatus_Init(); UpdateNodeStatus_Init(); if (!m_AcSysMG->CreatePQNodeMatrix()) { m_bObjectCPThreadFinish = true; return false; } if (m_AcSysMG->RunCalValue()) //动态计算交流侧的相关电力值。。。。RunCalValue()交流侧计算(牛顿-拉夫逊 方法) { // if (m_timeturns>=3) { PublishData(); //发布网络消息 //SetEvent(m_hExit); //潮流计算完成后,将设备电气量更新事件触发,置为有信号状态:ObjectPowerValueUpdateAss xyx注释 m_timeturns=0; } m_timeturns++; } else { //TRACE("电力调度交流计算未收敛!\n"); } } else { m_DcSysMG->OutPutTrainSMap(); //TRACE("电力调度直流计算未收敛!\n"); } m_DcSysMG->DeleteSpanNetInfo(); //added by zhangjiahua m_bObjectCPThreadFinish = true; return true; } /*************************以上本函数原来的部分********************************/ } else { m_bObjectCPThreadFinish = true; return false; } m_bObjectCPThreadFinish = true; return false; } bool ElectricityVOC::InitSubSysDBDate(int courseid,int parm1,int parm2,InitCourInfo* curseinfo) { m_TrainBeginTime = parm2; m_RunTime = m_TrainBeginTime; InitDDRunLineID(); m_ElectricEvent.SetCourseID(courseid);//added by zhangjiahua printf("-------------ElectricityVOC-InitSubSysDBDate-begin--------------------\r"); if (m_DataBaseManger.InitDataBase(m_pDataBaseOper,courseid, MRunLineID)) { //读取设备数据前先读取设备基础定义 if (!InitDDServerConfig()) { return false; } if (!InitBaseEqpmtDefineInfo()) { return false; } if (!m_DataBaseManger.GetPowerStationFromDB(m_MI_powerstation)) //从数据库获得车站的数据 { return false; } BaseElectricEqpmt::m_stationMap=m_MI_powerstation; m_ElectricEvent.m_MI_powerstation=m_MI_powerstation;//added by zhangjiahua if ( !m_DataBaseManger.GetRepeatShutData() || !m_DataBaseManger.GetErrorToProtectData() ) { return false; } printf("-------------ElectricityVOC-InitSubSysDBDate-GetEqpmtsFromDB--------------------\r"); if (!m_DataBaseManger.GetEqpmtsFromDB(&ElectricEqpmtMap)) { return false; } printf("-------------ElectricityVOC-InitSubSysDBDate-GetEqpmt_TouchNet_FromDB--------------------\r"); if (m_DcSysMG!=nullptr&&!m_DataBaseManger.GetEqpmt_TouchNet_FromDB(&ElectricEqpmtMap,m_DcSysMG->GetTouchNetMap())) { return false; } if (!m_DataBaseManger.GetEqpmt_TouchNet_Track_Relation_FromDB(*m_DcSysMG)) { return false; } if (!m_DataBaseManger.GetEqpmt_InPutRelation_FromDB(&ElectricEqpmtMap)) { return false; } if ( !m_DataBaseManger.UpdateProtectLockingEqpmt(&ElectricEqpmtMap) ) { return false; } if (!m_DataBaseManger.UpdateFaultSceneLockingEqpmt(&ElectricEqpmtMap)) { return false; } if (!m_DataBaseManger.InitDC_StationInfo(*m_DcSysMG)) { return false; } if (!m_DataBaseManger.InitAc_PowerLineInfo((*m_AcSysMG))) { return false; } if (!m_DataBaseManger.InitAc_PowerCalNodeInfo((*m_AcSysMG))) { return false; } if (!m_DataBaseManger.InitAc_PowerLineSwitch(*m_AcSysMG)) //added by zhangjiahua { return false; } if (!m_DataBaseManger.GetMultiModeData(m_MultiModeMap)) { return false; } if (!m_DataBaseManger.GetModeInfoData(m_ModeDataMap,m_ModeIDDataMap)) { return false; } if (!m_DataBaseManger.GetEqpmtAlarmInfoFromDB(&m_ElcEqpmtAlarmInfoMap)) { return false; } BaseElectricEqpmt::SetElcEqpmtAlarmInfoMap(&m_ElcEqpmtAlarmInfoMap); if (MRunLineID == 200) { } else /*if(MRunLineID == 300||MRunLineID == 400||MRunLineID == 500||MRunLineID == 600)*/ { if (!m_DataBaseManger.GetTrackRelationXDData(m_TrackRelationXDMap)) { return false; } //if (nullptr !=m_pBaseElcEqpmt) { BaseElectricEqpmt::SetTrackRelationXDMap(m_TrackRelationXDMap); } } if ( !m_DataBaseManger.LoadTelesignalisationData(m_ElectricEvent.m_TelesignalisationMng, &ElectricEqpmtMap) ) { return false; } if ( !m_DataBaseManger.LoadElcTurnOffAreaData( &ElectricEqpmtMap, m_ElectricEvent.m_ElcTurnOffAreaMng) ) { return false; } if ( !m_DataBaseManger.LoadElcEqpmtAutoBoltLogic(&ElectricEqpmtMap) ) { return false; } if ( !m_DataBaseManger.LoadStation400VLoadMng( &m_ElectricEvent.m_400VLoadMng, &ElectricEqpmtMap ) ) { return false; } if (!m_DataBaseManger.GetEqpmtTelemeteryValue(m_mapEqpmtTelemetryInfo)) { return false; } if (MRunLineID == 1100) { if (!m_DataBaseManger.GetEqpmt_EarthSwitchRelation_FromDB(&ElectricEqpmtMap)) { return false; } } if ( !m_DataBaseManger.GetElectric_EqpmtStatusToIBPLight_FromDB( m_ElectricEvent.m_MIEqpmtStatusToIBPLight ) ) { return false; } // 获取真实设备映射 if (!m_DataBaseManger.loadRealEqpmtRelationFromDB(&ElectricEqpmtMap)) { return false; } m_AcSysMG->SetEqpmentMap(&ElectricEqpmtMap); //SetElectricEqpmtMap(ElectricEqpmtMap); SetPowerValueUpdateEqpmt(&ElectricEqpmtMap); } printf("-------------ElectricityVOC-InitSubSysDBDate-end--------------------\r"); return true; } bool ElectricityVOC::StartTask(int& ret)//开始 { printf("-------------ElectricityVOC-StartTask-begin--------------------\r"); //m_RunStatus=DISPATCH_RUN_STATUS_RUNNING; //m_DcSysMG->SetRunStatus(m_RunStatus); if (m_RunStatus != DISPATCH_RUN_STATUS_RUNINT && m_RunStatus != DISPATCH_RUN_STATUS_RUNNING) { m_RunStatus = DISPATCH_RUN_STATUS_RUNNING; m_DcSysMG->SetRunStatus(m_RunStatus); printf("-------------ElectricityVOC-StartTask-end--------------------\r"); return true; } else { return false; } printf("-------------ElectricityVOC-StartTask-end--------------------\r"); return true; } bool ElectricityVOC::StopTask(int& ret) { m_RunStatus=DISPATCH_RUN_STATUS_STOP; m_DcSysMG->SetRunStatus(m_RunStatus); return true; } bool ElectricityVOC::PauseTask(int& ret) { m_RunStatus=DISPATCH_RUN_STATUS_PAUSE; m_DcSysMG->SetRunStatus(m_RunStatus); return true; } bool ElectricityVOC::ResumeTask(int& ret) { m_RunStatus=DISPATCH_RUN_STATUS_RUNNING; m_DcSysMG->SetRunStatus(m_RunStatus); return true; } void ElectricityVOC::InitDDRunLineID() { string Str_FileName = GetFolder_AppEXE_2() + "/ParamSetting.ini"; int nCourseRunLineID = m_nRunLineID; m_DataBaseManger.m_nLineID = ReadCfg_Int(Str_FileName,"DDDATABASE", "RunLineID", nCourseRunLineID); MRunLineID = m_DataBaseManger.m_nLineID; } bool ElectricityVOC::InitDDServerConfig() { if (m_DataBaseManger.initDDServerConfigInfo()) { PQValuesArray = new DCNodePQValue[All_Power_Station_Nums]; m_AcSysMG = new ACSysMG(); m_DcSysMG = new DCSysMG(); if (m_AcSysMG == nullptr || m_DcSysMG == nullptr) { return false; } } else { return false; } return true; } bool ElectricityVOC::InitBaseEqpmtDefineInfo() { return m_DataBaseManger.initBaseEqpmtDefineInfo(); } //void ElectricityVOC::SendControlPermission() //{ // for (int i=0;ifirst; if (OCC_EQPMTTYPE_110kVBreaker==iterEqpmt->second->GetBaseType() //交流断路器电力数据更新 ||OCC_EQPMTTYPE_35kVBREAKER==iterEqpmt->second->GetBaseType() ||OCC_EQPMTTYPE_400vACControlBreaker==iterEqpmt->second->GetBaseType()) { pEqpmtPowerValue=new ELCEQPMTPOWERVALUEUPDATE(); strncpy(pEqpmtPowerValue->EqpmtUnitID,EqpmtID.c_str(),sizeof(pEqpmtPowerValue->EqpmtUnitID)); pEqpmtPowerValue->Ia = iterEqpmt->second->m_EqpmtPowerValue.Ia; pEqpmtPowerValue->Ib = iterEqpmt->second->m_EqpmtPowerValue.Ib; pEqpmtPowerValue->Ic = iterEqpmt->second->m_EqpmtPowerValue.Ic; pEqpmtPowerValue->S = iterEqpmt->second->m_EqpmtPowerValue.S; pEqpmtPowerValue->P = iterEqpmt->second->m_EqpmtPowerValue.P; pEqpmtPowerValue->Q = iterEqpmt->second->m_EqpmtPowerValue.Q; pEqpmtPowerValue->PF = iterEqpmt->second->m_EqpmtPowerValue.PF; pEqpmtPowerValue->Forward_P = iterEqpmt->second->m_EqpmtPowerValue.Forward_P; pEqpmtPowerValue->Forward_Q = iterEqpmt->second->m_EqpmtPowerValue.Forward_Q; pEqpmtPowerValue->Backward_P = iterEqpmt->second->m_EqpmtPowerValue.Backward_P; pEqpmtPowerValue->Backward_Q = iterEqpmt->second->m_EqpmtPowerValue.Backward_Q; if (OCC_EQPMTTYPE_110kVBreaker==iterEqpmt->second->GetBaseType() //110kV、35kV断路器电压(kV)、参数显示的位置区分 ||OCC_EQPMTTYPE_35kVBREAKER==iterEqpmt->second->GetBaseType()) { pEqpmtPowerValue->Ua = iterEqpmt->second->m_EqpmtPowerValue.Ua; pEqpmtPowerValue->Ub = iterEqpmt->second->m_EqpmtPowerValue.Ub; pEqpmtPowerValue->Uc = iterEqpmt->second->m_EqpmtPowerValue.Uc; pEqpmtPowerValue->Uab = iterEqpmt->second->m_EqpmtPowerValue.Uab; pEqpmtPowerValue->Ubc = iterEqpmt->second->m_EqpmtPowerValue.Ubc; pEqpmtPowerValue->Uca = iterEqpmt->second->m_EqpmtPowerValue.Uca; } else if(OCC_EQPMTTYPE_400vACControlBreaker==iterEqpmt->second->GetBaseType()) //400V断路器电压(V)、参数显示的位置区分 { pEqpmtPowerValue->Ua = iterEqpmt->second->m_EqpmtPowerValue.Ua*1000; pEqpmtPowerValue->Ub = iterEqpmt->second->m_EqpmtPowerValue.Ub*1000; pEqpmtPowerValue->Uc = iterEqpmt->second->m_EqpmtPowerValue.Uc*1000; pEqpmtPowerValue->Uab = iterEqpmt->second->m_EqpmtPowerValue.Uab*1000; pEqpmtPowerValue->Ubc = iterEqpmt->second->m_EqpmtPowerValue.Ubc*1000; pEqpmtPowerValue->Uca = iterEqpmt->second->m_EqpmtPowerValue.Uca*1000; } pEqpmtPowerValue->Position = iterEqpmt->second->m_EqpmtPowerValue.Position; } else if (OCC_EQPMTTYPE_110kVACMLine==iterEqpmt->second->GetBaseType() //交流母线电力数据更新 ||OCC_EQPMTTYPE_35kVMOTHERLINE==iterEqpmt->second->GetBaseType() ||OCC_EQPMTTYPE_400vACMLine==iterEqpmt->second->GetBaseType()) { pEqpmtPowerValue=new ELCEQPMTPOWERVALUEUPDATE(); strncpy(pEqpmtPowerValue->EqpmtUnitID,EqpmtID.c_str(), sizeof(pEqpmtPowerValue->EqpmtUnitID)); if (OCC_EQPMTTYPE_110kVACMLine==iterEqpmt->second->GetBaseType() //110kV、35kV母线线电压(kV) ||OCC_EQPMTTYPE_35kVMOTHERLINE==iterEqpmt->second->GetBaseType()) { pEqpmtPowerValue->Uab = iterEqpmt->second->m_EqpmtPowerValue.Uab; pEqpmtPowerValue->Ubc = iterEqpmt->second->m_EqpmtPowerValue.Ubc; pEqpmtPowerValue->Uca = iterEqpmt->second->m_EqpmtPowerValue.Uca; } else if (OCC_EQPMTTYPE_400vACMLine==iterEqpmt->second->GetBaseType()) //400V母线线电压(V) { pEqpmtPowerValue->Uab = iterEqpmt->second->m_EqpmtPowerValue.Uab*1000; pEqpmtPowerValue->Ubc = iterEqpmt->second->m_EqpmtPowerValue.Ubc*1000; pEqpmtPowerValue->Uca = iterEqpmt->second->m_EqpmtPowerValue.Uca*1000; } pEqpmtPowerValue->Position = iterEqpmt->second->m_EqpmtPowerValue.Position; } else if ( OCC_EQPMTTYPE_BREAKER_DC==iterEqpmt->second->GetBaseType() //直流侧电力数据更新 ||OCC_EQPMTTYPE_1500vDCMLine==iterEqpmt->second->GetBaseType() ) { pEqpmtPowerValue=new ELCEQPMTPOWERVALUEUPDATE(); strncpy(pEqpmtPowerValue->EqpmtUnitID, EqpmtID.c_str(), sizeof(pEqpmtPowerValue->EqpmtUnitID)); if (OCC_EQPMTTYPE_BREAKER_DC==iterEqpmt->second->GetBaseType()) //直流断路器电压(V)、电流(A) { pEqpmtPowerValue->U = iterEqpmt->second->m_EqpmtPowerValue.U; pEqpmtPowerValue->I = iterEqpmt->second->m_EqpmtPowerValue.I; pEqpmtPowerValue->Position = iterEqpmt->second->m_EqpmtPowerValue.Position; } else if (OCC_EQPMTTYPE_1500vDCMLine==iterEqpmt->second->GetBaseType()) //直流母线电压(V) { pEqpmtPowerValue->U = iterEqpmt->second->m_EqpmtPowerValue.U; pEqpmtPowerValue->Position =iterEqpmt->second->m_EqpmtPowerValue.Position; } } if (pEqpmtPowerValue!=nullptr && pEqpmtPowerValue->Position!= -1) { OCCCOMMAND tmpSendHC; tmpSendHC.setPacketValue(pEqpmtPowerValue,OCCCOMMAND::eUpdateEqpmtPowerValue); tmpSendHC.DesSysType = OCC_SYS_DD_GROUP;//目的系统,电调组播 tmpSendHC.TrainningID = m_trianid;//训练编号 tmpSendHC.ScrSysType = OCC_SYS_DD_SVR;//电调服务端 SendNetMsg(tmpSendHC); } delete pEqpmtPowerValue; } //LeaveCriticalSection(&EqpmtMapCriticalSection); } void ElectricityVOC::SetPowerValueUpdateEqpmt( ELEEQPMTMAP *Elceqpmtmap ) { ELEEQPMTMAP::iterator iterEqpmt=ElectricEqpmtMap.begin(); for (;iterEqpmt!=ElectricEqpmtMap.end();iterEqpmt++) { if ( OCC_EQPMTTYPE_110kVBreaker==iterEqpmt->second->GetBaseType() ||OCC_EQPMTTYPE_35kVBREAKER==iterEqpmt->second->GetBaseType() ||OCC_EQPMTTYPE_400vACControlBreaker==iterEqpmt->second->GetBaseType() ||OCC_EQPMTTYPE_BREAKER_DC==iterEqpmt->second->GetBaseType() ||OCC_EQPMTTYPE_110kVACMLine==iterEqpmt->second->GetBaseType() ||OCC_EQPMTTYPE_35kVMOTHERLINE==iterEqpmt->second->GetBaseType() ||OCC_EQPMTTYPE_400vACMLine==iterEqpmt->second->GetBaseType() ||OCC_EQPMTTYPE_1500vDCMLine==iterEqpmt->second->GetBaseType() ) { ELEEQPMTMAP::iterator iterPowerEqpmt=m_mapPowerValueUpdateEqpmt.find(iterEqpmt->first); if (iterPowerEqpmt==m_mapPowerValueUpdateEqpmt.end()) { m_mapPowerValueUpdateEqpmt.insert(make_pair(iterEqpmt->first,iterEqpmt->second)); } } } } void ElectricityVOC::ModeControlDeal( int nModeID, int nModeStatus ) { string str_EqpmtID; int n_DesStatus; string str_StdId; int n_CtrlType; MODEIDDATAMAP::iterator iterModeID = m_ModeIDDataMap.find(nModeID); if ( iterModeID!= m_ModeIDDataMap.end()) { if ( MODECTRL_STATUS_RUNING == nModeStatus) { map mapModeIndex; mapModeIndex=iterModeID->second; map::iterator iterModeIndex= mapModeIndex.begin(); for (;iterModeIndex!=mapModeIndex.end();iterModeIndex++) { str_EqpmtID = iterModeIndex->second.strid; n_DesStatus = iterModeIndex->second.dstatus; str_StdId = "系统"; n_CtrlType = CTRLTYPE_STATUS; NORMALCMDC NCmd; m_ElectricEvent.EqpmtCtrl(NCmd,str_EqpmtID,n_DesStatus,str_StdId,n_CtrlType); } } } } void ElectricityVOC::ElcTrackInfo_2_XD() { //发布接触轨带电信息 ELEEQPMTMAP::iterator iterEqpmtMap; TrackRelationXDMAP::iterator iterTrackMap = m_TrackRelationXDMap.begin(); for (;iterTrackMap != m_TrackRelationXDMap.end();iterTrackMap++) { iterEqpmtMap = ElectricEqpmtMap.find(iterTrackMap->second->m_strID); if (iterEqpmtMap != ElectricEqpmtMap.end()) { if (iterEqpmtMap->second->m_TrackRelationXD.m_PreIsPower != -1) { //itetrackXD->second->m_IsPower = trackpower; COMMANDTOXD cmdtoxd; cmdtoxd.type = DDTOXD_ELCTRACK_STATUS; cmdtoxd.ObjectID = iterEqpmtMap->second->m_TrackRelationXD.m_NoID; cmdtoxd.data1 = iterEqpmtMap->second->m_TrackRelationXD.m_IsPower; cmdtoxd.data2 = iterEqpmtMap->second->m_TrackRelationXD.m_Direction; OCCCOMMAND tmpSendOC; tmpSendOC.cmdType = OCCCOMMAND::CmdType::eCommantoXD; //tmpSendOC.DesSysType = OCC_SYS_XD_CLIENT; tmpSendOC.DesSysType = OCC_SYS_XD_SVR; tmpSendOC.ScrSysType = OCC_SYS_DD_SVR; tmpSendOC.TrainningID = m_trianid; tmpSendOC.DateLen = sizeof(COMMANDTOXD); tmpSendOC.Net_LS_CommandtoXD = cmdtoxd; m_pQI_SendCmdsList->push(tmpSendOC); } iterEqpmtMap->second->m_TrackRelationXD.m_PreIsPower = iterEqpmtMap->second->m_TrackRelationXD.m_IsPower; } } /* //发布列车电压 map* pTrainMap = nullptr; m_DcSysMG->EnterTrainSInStationMapCritilSec(); m_DcSysMG->SetElcEqpmtMap(ElectricEqpmtMap); pTrainMap = m_DcSysMG->GetTrainSInStationMap(); if (pTrainMap == nullptr) { return; } map::iterator iter =pTrainMap->begin(); while(iter!=pTrainMap->end()) { string touchnet = m_DcSysMG->GetTouchNetByPosition(iter->second.LineSectionID,iter->second.excursion); if (touchnet!="") { ELEEQPMTMAP::iterator iterEqpmet=ElectricEqpmtMap.find(touchnet); if (iterEqpmet!=ElectricEqpmtMap.end()) { TRIANV updatadata; updatadata.Trianid=iter->second.ID; if (iterEqpmet->second->GetStatus()) { updatadata.V=1593.0; } else { updatadata.V= 0.0; } OCCCOMMAND tmpSendHC; tmpSendHC.setPacketValue(&updatadata,OCCCOMMAND::eUpdateTrainV); tmpSendHC.DesSysType=OCC_SYS_XD_SVR; tmpSendHC.TrainningID = m_trianid; tmpSendHC.ScrSysType=OCC_SYS_DD_SVR; SendNetMsg(tmpSendHC); TRACE("列车:%d 网压:%f\n",updatadata.Trianid,updatadata.V); } } iter++; } m_DcSysMG->LeaveTrainSInStationMapCritilSec(); //发布列车电压结束 */ } void ElectricityVOC::SendIniCmd() { EQPMTINITSTATUS oper; oper.StationID = 0; oper.Status = 0; OCCCOMMAND occcommand; //occcommand.DesNetID = m_nXDServerID; occcommand.TrainningID = m_trianid; occcommand.DesSysType = OCC_SYS_DD_CLIENT; occcommand.ScrSysType = OCC_SYS_DD_SVR; occcommand.setPacketValue(&oper, OCCCOMMAND::eUpdateEqpmtInitStatus); m_pQI_SendCmdsList->push(occcommand); } //IBP接收事件 void ElectricityVOC::DealWith_IBPEvent( int nIBPSysID, int nCmdType, int nParam1, int nParam2,int nParam3, int nParam4, int nParam5, string& strParam1, string& strParam2, string& strParam3, string& strParam4, string& strParam5,int nStationID ) { string strName = "IBP紧急分闸"; NORMALCMDC NCmd; int n_CtrlType = CTRLTYPE_STATUS; int n_DesStatus = 0; string str_StdId = "IBP"; if ( Electric_IBPEvent_DCBreakerCtrl == nCmdType ) { if (nParam5 < 1) { n_DesStatus = 1; } //对断路器停送电 vector vecKey; string strFindKey = ";"; if ( !strParam1.empty() ) { vecKey = str_split_2( strParam1, strFindKey ); } if ( !vecKey.empty() ) { for (int i = 0;i < vecKey.size(); i++) { m_ElectricEvent.EqpmtCtrl(NCmd,vecKey[i],n_DesStatus,str_StdId,n_CtrlType); } } } }