/** @file InterLockImpl.cpp @brief 闭锁接口类的实现文件 @author 周正龙 */ #include "InterLockImpl.h" #include "Common.h" #include "pub_logger_api/logger.h" #include "pub_lua_engine_api/LuaEngineInterface.h" #include "service/common/RdbTableDefine.h" #include "pub_utility_api/I18N.h" using namespace std; using namespace kbd_public; using namespace kbd_service; using namespace kbd_dbms; CInterLockImpl::CInterLockImpl(const kbd_public::SRunAppInfo &stRunAppInfo,const string &strProcess) { m_stRunAppInfo = stRunAppInfo; m_strProcessName = strProcess; } CInterLockImpl::~CInterLockImpl() { if(m_ptrRdbTableMng) { m_ptrRdbTableMng.reset(); m_ptrRdbTableMng = NULL; } return; } /* @brief 初始化 */ int CInterLockImpl::initialize() { LOGINFO("闭锁库参数初始化....."); //kbd_public::initI18N("/interlock_api/translate", "interlock_api"); if(createSysInfoInstance(m_ptrSysInfoPtr) == false) { LOGERROR("InstName=%s ,CInterLockImpl::initialize(), createSysInfoInstance fail!\n", m_strProcessName.c_str()); return kbdFailed; } if(m_ptrSysInfoPtr == NULL) { LOGERROR("InstName=%s ,CInterLockImpl::initialize(), Get System Info fail!\n", m_strProcessName.c_str()); return kbdFailed; } //RDB管理实例 m_ptrRdbTableMng = boost::make_shared(m_stRunAppInfo.strAppName); if (m_ptrRdbTableMng == NULL) { LOGERROR("CInterLockImpl ::initialize(), make_shared fail!\n"); return kbdFailed; } return kbdSuccess; } /** @brief 判断联锁关系 @param const char *strCtrlPointName IN:需要进行互锁判断的测点,一般为控制点,如AO,DO,MO等 string &strInterlockResult OUT 返回结果字符串 string &bInterlockSuccess OUT 返回结果,成功/失败 @return 成功返回kbdSucces,失败返回 kbdFailed */ int CInterLockImpl::CheckCtrlInterlock(const char *strCtrlPointName,const double dTargValue, string &strResult, bool &bSuccess) { int nRetCode = -1 ; vector vecInterlockInTag; SInterLockParaAll stInterLockParaAll; string strTagName = strCtrlPointName; strTagName.resize(64); nRetCode = m_ptrRdbTableMng->getRecordAllColumnByKey(RT_OPT_INTERLOCK_PARA,strTagName.c_str(),stInterLockParaAll);//得到闭锁参数 if (nRetCode <0 ) { LOGERROR( "CheckCtrlInterlock, 得到闭锁参数表[OPT_INTERLOCK_PARA] getRecordAllColumnByKey error! \n"); strResult = I18N("获取控制点闭锁参数表失败 !") ; return kbdFailed; } else if (nRetCode == 0) { bSuccess = true; strResult = I18N("控制点没有配置闭锁,检查通过 !"); LOGDEBUG( "CheckCtrlInterlock, 该控制点[%s]没有配置闭锁参数 ! \n",strTagName.c_str()); return kbdSuccess; } string strInterlockTag = stInterLockParaAll.interlock_tag; int nInterlockTagNum = stInterLockParaAll.interlock_num; if ( (strInterlockTag.size() <=0) || (nInterlockTagNum <= 0) ) { strResult = I18N("闭锁入口参数小于等于零,请检查配置 !"); return kbdFailed; } for(int i=0;i &vecInterlockKey:IN 输入参数队列 VECTOR string &strInterlockResult OUT 返回结果字符串 string &bInterlockSuccess OUT 返回结果,成功/失败 @return 成功返回kbdSucces,失败返回 kbdFailed */ int CInterLockImpl::CheckCtrlInterlock(const char *strInterlockName, const double dTargValue,const int nInterlockNum, const vector &vecInterLockInPara, string &strInterlockResult, bool &bInterlockSuccess) { int nRetCode; kbd_public::LuaVariantTypeSeq vecValue; //param 1 kbd_public::LuaVariantTypeSeq vecStatus; kbd_public::LuaVariantTypeSeq vecName; kbd_public::LuaVariantTypeSeq vecTargValue; vecTargValue.push_back(dTargValue); for (int i = 0; i != nInterlockNum; ++i) { int nDomainId ; int nAppNo ; string strTableName ; string strTagName ; string strColumnName; string strInterLockInPara = vecInterLockInPara[i]; string strName; //DESC //1.拆分标签 //=================================================================================== if (SplitDmAppKeyidTag(strInterLockInPara, nDomainId, nAppNo, strTableName, strTagName, strColumnName) < 0) { LOGERROR("CheckCtrlInterlock, i = %d, dm_app_key_id_tag = %s, SplitDmAppKeyidTag error!", i, strInterLockInPara.c_str()); return -1; } //2:获取点的类型 SOptValueStatus stValueStatus; int nPointType = GetPointTypeByTableName(strTableName); if (nPointType < 0) { LOGERROR("CheckCtrlInterlock, i = %d, strTableName = %s, GetPointTypeByTableName error!", i, strTableName.c_str()); return -1; } //3:获取点的值;状态;描述 stValueStatus.point_type = nPointType; if (GetValueStatusName(strTagName, stValueStatus,vecValue,strName ,nDomainId,nAppNo) < 0) { LOGERROR("CheckCtrlInterlock, i = %d, dm_app_key_id_tag = %s, GetValueStatusName error!", i, strInterLockInPara.c_str()); return -1; } vecStatus.push_back(stValueStatus.status); vecName.push_back(strName); } string strInterlock; nRetCode = m_ptrRdbTableMng->getRecordOneColumnByKey(RT_OPT_INTERLOCK_DEFINE,strInterlockName,"interlock_str",strInterlock);//得到闭锁字符串 if (nRetCode == false) { LOGERROR( "CheckCtrlInterlock, strTableName = %s, strInterlockName = %s, getRecordOneColumnByKey error!", RT_OPT_INTERLOCK_DEFINE,strInterlockName); return -1; } string strInterLockScript = strInterlock; kbd_public::CLuaEngineInterface m_objLuoInterface; if(m_objLuoInterface.initialize() != kbdSuccess) { LOGERROR("CInterLockImpl::initialize(),initialize lua interface fail !\n"); return -1;//kbdFailed; } string strInterlockOutput; // 闭锁检测输出;空表示检查通过,否则输出错误信息; nRetCode = m_objLuoInterface.execFunction(strInterlockName,strInterLockScript,vecTargValue,vecValue,vecStatus,vecName,strInterlockOutput); if (nRetCode != kbdSuccess) { LOGWARN( "CheckCtrlInterlock, exec Function[%s] error!", strInterlockName); bInterlockSuccess = false; strInterlockResult = I18N("闭锁函数执行失败!"); return 0; } if(strInterlockOutput.size()>0) { bInterlockSuccess = false ; strInterlockResult = I18N("闭锁检查不通过:"); strInterlockResult+= strInterlockOutput ; } else { bInterlockSuccess = true ; strInterlockResult = I18N("闭锁检查通过! "); } //LOGINFO("CheckCtrlInterlock, bInterlockSuccess = %d", bInterlockSuccess); return 1; } /** @brief 通过标签点获取标签点的状态和值 @return 成功返回kbdSucces,失败返回相应错误码 */ int CInterLockImpl::GetValueStatusName(const std::string &strTagName, SOptValueStatus &stValueStatus,\ kbd_public::LuaVariantTypeSeq &vecValue, std::string& strName,int nDomainId ,int nAppNo) { int nRetCode; string strKeyTagName = strTagName ; strKeyTagName.resize(64); //通过LOCATION 得到 应用;通过专业获得 应用 //=============================================================================== if(m_stRunAppInfo.nDomainId !=nDomainId || m_stRunAppInfo.nAppId != nAppNo) { LOGDEBUG("GetValueStatus::strTagName = %s nDomainId=%d,nAppId=%d",strTagName.c_str(), nDomainId,nAppNo); } //只考虑本域本应用的情况的情况 //=============================================================================== vector vecSelColumn = {"value","status","description"}; if (stValueStatus.point_type == POINT_TYPE_DIG ) { SDigValueStatusName stDigValueStatus; nRetCode = m_ptrRdbTableMng->getRecordSelColumnByKey(RT_DIG_TBL, strKeyTagName.c_str(),vecSelColumn,stDigValueStatus); if (nRetCode == false) { LOGWARN("GetValueStatus::getRecordByKey,tag = %s error,ret=%d",strTagName.c_str(), nRetCode); return -1; } stValueStatus.i_value = stDigValueStatus.value; stValueStatus.status = stDigValueStatus.status; vecValue.push_back(stValueStatus.i_value); strName = stDigValueStatus.description; } else if ( stValueStatus.point_type == POINT_TYPE_MIX) { SMixValueStatusName stMixValueStatus; nRetCode = m_ptrRdbTableMng->getRecordSelColumnByKey(RT_MIX_TBL, strKeyTagName.c_str(),vecSelColumn,stMixValueStatus); if (nRetCode == false) { LOGWARN("GetValueStatus::getRecordByKey,tag = %s error,ret=%d",strTagName.c_str(), nRetCode); return -1; } stValueStatus.i_value = stMixValueStatus.value; stValueStatus.status = stMixValueStatus.status; vecValue.push_back(stValueStatus.i_value); strName = stMixValueStatus.description; } else if (stValueStatus.point_type == POINT_TYPE_ANA) { SAnaValueStatusName stAnaValueStatus; nRetCode = m_ptrRdbTableMng->getRecordSelColumnByKey(RT_ANA_TBL, strKeyTagName.c_str(),vecSelColumn,stAnaValueStatus); if (nRetCode == false) { LOGWARN("GetValueStatus::getRecordByKey,tag = %s error,ret=%d",strTagName.c_str(), nRetCode); return -1; } stValueStatus.f_value = stAnaValueStatus.value; stValueStatus.status = stAnaValueStatus.status; vecValue.push_back(stValueStatus.f_value); strName = stAnaValueStatus.description; } else if(stValueStatus.point_type == POINT_TYPE_ACC) { SAccValueStatusName stAccValueStatus; nRetCode = m_ptrRdbTableMng->getRecordSelColumnByKey(RT_ACC_TBL, strKeyTagName.c_str(),vecSelColumn,stAccValueStatus); if (nRetCode == false) { LOGWARN("GetValueStatus::getRecordByKey,tag = %s error,ret=%d",strTagName.c_str(), nRetCode); return -1; } stValueStatus.f_value = stAccValueStatus.value; stValueStatus.status = stAccValueStatus.status; vecValue.push_back(stValueStatus.f_value); strName = stAccValueStatus.description; } else { LOGWARN("point_type = %d, error!", stValueStatus.point_type); return -1; } return 1; } /** @brief 拆分标签点为 DOMIN,APPNO APPNAME,TABLENAME.TAGNAME,COLUMNNAME; locaton.pacada.ana.tag.column @return 返回DOMINID,APPNO APPNAME,TABLENAME.TAGNAME,COLUMNNAME */ int CInterLockImpl::SplitDmAppKeyidTag(const std::string &strDmAppKeyIdTag, int &nDomainId, int &nAppNo, \ std::string &strTableName, std::string &strTagName, std::string &strColumnName) { strTableName.clear(); strTagName.clear(); strColumnName.clear(); vector vecStr; char strTmpTag[100]; strcpy(strTmpTag, strDmAppKeyIdTag.c_str()); int nRetCode = SplitTagName(strTmpTag, ".", vecStr); if (nRetCode < 0) { LOGWARN("SplitDmAppKeyidTag, nRetCode = %d, key_id_tag = %s, SplitTagName error!", nRetCode, strDmAppKeyIdTag.c_str()); return -1; } vector::size_type vec_size = vecStr.size(); //通过车站名称获取域ID string strLocationName = vecStr[0]; SLocationInfo stLocationInfo; m_ptrSysInfoPtr->getLocationInfoByName(strLocationName,stLocationInfo); if (nRetCode < 0) { LOGWARN("SplitDmAppKeyidTag, nRetCode(%d), LocationName(%s), getLocationInfoByName error!", nRetCode, strLocationName.c_str()); return -1; } nDomainId = stLocationInfo.nDomainId ; //通过专业名称获取应用ID string strSubSystemName = vecStr[1]; SSubsystemInfo stSubsystemInfo; nRetCode = m_ptrSysInfoPtr->getSubsystemInfoByName(strSubSystemName,stSubsystemInfo); if (nRetCode == kbdFailed) { LOGWARN("SplitDmAppKeyidTag, nRetCode(%d), SubSystemName(%s), getSubsystemInfoByName error!", nRetCode, strSubSystemName.c_str()); return -1; } nAppNo = stSubsystemInfo.nAppId; strTableName = vecStr[2]; strColumnName = vecStr[vec_size - 1]; for (vector::size_type i = 3; i != vec_size - 1; ++i) { strTagName += vecStr[i]; if (i != (vec_size - 2)) { strTagName += "."; } } return 0; } int CInterLockImpl::SplitTagName(char *strTagName , const char *strDelimit,std::vector &vecStr) { char *token; int num = 0; std::string str_token; char temp[1024]; strcpy(temp, strTagName); token = strtok( temp, strDelimit ); while ( token != NULL ) { /* While there are tokens in "string" */ //printf( " %s\n", token ); str_token = token; vecStr.push_back(str_token); num++; /* Get next token: */ token = strtok( NULL, strDelimit ); } if (num == 0) { return -1; } else { return 1; } return 1; } /** @brief 通过表名称获得表的类型 @return 成功返回kbdSucces,失败返回相应错误码 */ int CInterLockImpl::GetPointTypeByTableName(const string &strTableName) { if (strTableName == RT_DIG_TBL) { return POINT_TYPE_DIG; } else if (strTableName == RT_ANA_TBL) { return POINT_TYPE_ANA; } else if (strTableName == RT_MIX_TBL) { return POINT_TYPE_MIX; } else if (strTableName == RT_ACC_TBL) { return POINT_TYPE_ACC; } LOGWARN("GetPointTypeByTableName, strTableName = %s, not point table!", strTableName.c_str()); return -1; }