2370 lines
90 KiB
C++
Raw Normal View History

2025-03-12 11:08:50 +08:00
/**
@file DiProcess.cpp
@brief
@author
*/
#include "DigProcess.h"
#include "pub_utility_api/I18N.h"
#include "pub_utility_api/TimeUtil.h"
#include "common/Common.h"
#include "pub_utility_api/CommonConfigParse.h"
using namespace std;
using namespace kbd_service;
using namespace kbd_idlfile;
using namespace kbd_public;
using namespace kbd_dbms;
CDigProcess::CDigProcess(kbd_public::SRunAppInfo stRunAppInfo,
CDataProcessApiPtr ptrDataProcApi,\
CSrvDataPublishPtr ptrDataPublish):CPointBase()
{
m_stRunAppInfo = stRunAppInfo;
m_ptrDataProcApi = ptrDataProcApi;
m_ptrDataPublish = ptrDataPublish;
m_nChgAlarmCount = 0 ;
m_nSoeAlarmCount = 0 ;
m_nChangeCount = 0 ;
}
bool CDigProcess::initialize()
{
if(false == CPointBase::initialize())
{
LOGERROR("CDigProcess::initialize() fail!\n");
return false;
}
if(readConfig())
{
LOGWARN("initialize::readConfig() 读取配置文件设备 .\n");
}
m_nStartupTimes = getUTCTimeSec();
m_nMenuStateDiGkOff = m_mapDiState["MENU_STATE_DI_GK_OFF"];
m_nMenuStateDiSetData = m_mapDiState["MENU_STATE_DI_SET_DATA"];
m_nMenuStateDiInvalid = m_mapDiState["MENU_STATE_DI_INVALID"];
m_nMenuStateDiAbnormal = m_mapDiState["MENU_STATE_DI_ABNORMAL"];
m_nMenuStateDiAlmNotAck = m_mapDiState["MENU_STATE_DI_ALM_NOT_ACK"];
return true;
}
CDigProcess::~CDigProcess()
{
}
bool CDigProcess::readConfig()
{
kbd_public::CCommonConfigParse objCfgParse;
if(objCfgParse.load( kbd_public::CFileUtil::getPathOfCfgFile("dataprocess_cfg.xml") ) == kbdFailed)
{
LOGDEBUG("CDigProcess::readConfig() dataprocess_cfg.xml load fail .\n");
return false;
}
m_nStartAlarmDelay = objCfgParse.getIntWithDefault("fulldata","alarmDelay",60); //默认60秒
return true;
}
bool CDigProcess::getDigAlarmStatus(int &nAlmStatus,int nPointType,int nPointSort)
{
int nRetCode = -1;
SAlarmStatusDigSet stAlmStatusDigSet;
int Key[2] ;
Key[0] = nPointType ;
Key[1] = nPointSort ;
if(nPointSort <= 0)
{
LOGDEBUG("getDigAlarmStatus,nPointSort=[%d] <=0 return.",nPointSort);
return true;
}
nRetCode = m_ptrRdbTableMng->getRecordAllColumnByKey(RT_ALARM_STATUS_DIG_SET,&Key,stAlmStatusDigSet);
if(nRetCode <0 ) //reach fail
{
LOGERROR("getDigAlarmStatus::get table[%s] record Fail ,nPointSort=%d",RT_ALARM_STATUS_DIG_SET,nPointSort);
return false;
}
else if(nRetCode == 0)
{
LOGDEBUG("getDigAlarmStatus::get table[%s] nPointSort=%d not find ",RT_ALARM_STATUS_DIG_SET,nPointSort);
return true;
}
if(nAlmStatus == ALM_STAT_SOE)
{
nAlmStatus = stAlmStatusDigSet.alm_status_soe ;
}
else if(nAlmStatus == ALM_STAT_DI_CHANGE)
{
nAlmStatus = stAlmStatusDigSet.alm_status_change ;
}
else
{
LOGERROR("getDigAlarmStatus:: input nAlmStatus[%d] Error!",nAlmStatus);
return false;
}
return true;
}
/**
@brief
@param stDigPoint nIndex nValue nStatus
@return
@retval
*/
bool CDigProcess::getValuexStatusx(const SDigPointAll &stDigPoint,const int nIndex,int &nValue,int &nStatus)
{
if (nIndex > stDigPoint.value_num || nIndex < 1 )
{
LOGERROR( "getValueStatus 分量nIndex:%d > nValueNum:%d OR <1,ERROR. ",nIndex,stDigPoint.value_num );
return false;
}
switch(nIndex)
{
case 1:
nValue = stDigPoint.value1;
nStatus = stDigPoint.status1;
break;
case 2:
nValue = stDigPoint.value2;
nStatus = stDigPoint.status2;
break;
case 3:
nValue = stDigPoint.value3;
nStatus = stDigPoint.status3;
break;
case 4:
nValue = stDigPoint.value4;
nStatus = stDigPoint.status4;
break;
case 5:
nValue = stDigPoint.value5;
nStatus = stDigPoint.status5;
break;
default:
return false;
};
return true;
}
/**
@brief /statue到实时库
@param strTagName测点标签 nValue nStatus ,nUpdTimes
@return TRUE; FALSE
@retval
*/
bool CDigProcess::updateDigValStatus(const string &strTagName,int nValue,int nStatus,int64 nUpdTimes)
{
bool bRetCode = 0 ;
std::vector<RSQL_UPD_COLUMN> vecUpdColumn ;
CRdbPublic::addUpColumnInfo(vecUpdColumn ,"value", nValue );
CRdbPublic::addUpColumnInfo(vecUpdColumn ,"status",nStatus);
CRdbPublic::addUpColumnInfo(vecUpdColumn ,"last_update_time",nUpdTimes);
string strKeyTagName = strTagName ;
strKeyTagName.resize(64);
bRetCode = m_ptrRdbTableMng->updateRecordMultiValueByKey(RT_DIG_TBL,(const void*)strKeyTagName.c_str(),vecUpdColumn);
if (bRetCode == false)
{
LOGERROR("updateDigValStatus::tag_name = %s, updateRecordMultiValueByKey error!",strKeyTagName.c_str());
return false;
}
return true;
}
/**
@brief statue到实时库
@param strTagName测点标签 nStatus ,nUpdTimes
@return TRUE; FALSE
@retval
*/
bool CDigProcess::updateDigStatus(const string &strTagName,int nStatus1,int nStatus,int64 nUpdTimes)
{
bool bRetCode = 0 ;
std::vector<RSQL_UPD_COLUMN> vecUpdColumn ;
CRdbPublic::addUpColumnInfo(vecUpdColumn ,"status1", nStatus1 );
CRdbPublic::addUpColumnInfo(vecUpdColumn ,"status", nStatus);
CRdbPublic::addUpColumnInfo(vecUpdColumn ,"last_change_time1",nUpdTimes);
string strKeyTagName =strTagName ;
strKeyTagName.resize(64);
bRetCode = m_ptrRdbTableMng->updateRecordMultiValueByKey(RT_DIG_TBL,(const void*)strKeyTagName.c_str(),vecUpdColumn);
if (bRetCode == false)
{
LOGERROR("updateDigStatus::tag_name = %s, updateRecordMultiValueByKey error!",strKeyTagName.c_str());
return false;
}
return true;
}
/**
@brief
@param stChgDiInfo FES nIndex nLastValue nLastStatus
@return TRUE; FALSE
@retval
*/
bool CDigProcess::updateDigitalPart(const SChangeDiInfo &stChgDiInfo,int nIndex)
{
std::vector<RSQL_UPD_COLUMN> vecUpdColumn ;
string strValueColName ="value" + to_string(nIndex);
string strStatusColName ="status"+ to_string(nIndex);
string strChTimeColName ="last_change_time"+ to_string(nIndex);
//LOGDEBUG("updateDigitalPart: tag_name = %s, %s = %d,%s = %d",
// stUpdateDiInfo.tag_name, strValueColName.c_str(), stUpdateDiInfo.value,strStatusColName.c_str(), stUpdateDiInfo.status);
// 更新全数据分量的值
//============================================================================================
vecUpdColumn.clear();
CRdbPublic::addUpColumnInfo(vecUpdColumn ,strValueColName, stChgDiInfo.nValue);
CRdbPublic::addUpColumnInfo(vecUpdColumn ,strStatusColName, stChgDiInfo.nStatus);
CRdbPublic::addUpColumnInfo(vecUpdColumn ,strChTimeColName, stChgDiInfo.lTimes); //更新变化时间
bool nRetCode = m_ptrRdbTableMng->updateRecordMultiValueByKey(RT_DIG_TBL,(const void*)stChgDiInfo.tag_name,vecUpdColumn);
if (nRetCode == false)
{
LOGERROR("updateDigitalPart::nRetCode = %d, tagName = %s, updateRecordByKey() error!", nRetCode, stChgDiInfo.tag_name);
return false;
}
return true;
}
/**
@brief
@param stUpdateDiInfo FES nIndex nLastValue nLastStatus
@return TRUE; FALSE
@retval
*/
bool CDigProcess::updateDigitalPart(const SUpdateDiInfo &stUpdateDiInfo,int nIndex,int64 nUpdateTime,int nLastValue,int nLastStatus)
{
std::vector<RSQL_UPD_COLUMN> vecUpdColumn ;
string strValueColName ="value" + to_string(nIndex);
string strStatusColName ="status"+ to_string(nIndex);
string strChTimeColName ="last_change_time"+ to_string(nIndex);
//LOGDEBUG("updateDigitalPart: tag_name = %s, %s = %d,%s = %d",
// stUpdateDiInfo.tag_name, strValueColName.c_str(), stUpdateDiInfo.value,strStatusColName.c_str(), stUpdateDiInfo.status);
// 更新全数据分量的值
//============================================================================================
vecUpdColumn.clear();
if(nLastValue != stUpdateDiInfo.value )//应该比较分量的值
{
CRdbPublic::addUpColumnInfo(vecUpdColumn ,strValueColName, stUpdateDiInfo.value);
}
if(nLastStatus != stUpdateDiInfo.status)//应该比较分量的状态
{
CRdbPublic::addUpColumnInfo(vecUpdColumn ,strStatusColName, stUpdateDiInfo.status);
}
if(vecUpdColumn.size()>0) // 全数据,测点值有变化->放入队列
{
CRdbPublic::addUpColumnInfo(vecUpdColumn ,strChTimeColName, nUpdateTime); //更新变化时间
bool nRetCode = m_ptrRdbTableMng->updateRecordMultiValueByKey(RT_DIG_TBL,(const void*)stUpdateDiInfo.tag_name,vecUpdColumn);
if (nRetCode == false)
{
LOGERROR("updateDigitalPart::nRetCode = %d, tagName = %s, updateRecordByKey() error!", nRetCode, stUpdateDiInfo.tag_name);
return false;
}
return true;
}
return false; //没有变化
}
/**
@brief
@param const SUpdateDiInfo &stUpdateDiInfo: FES nValueNum
@return
@retval
*/
int CDigProcess::getDigPartIndex(const SUpdateDiInfo &stUpdateDiInfo,const int nValueNum)
{
//判读 DI 分量数是否合法
//============================================================================================
if (nValueNum > MAX_DI_BIT_NUM || nValueNum < 1)
{
LOGERROR("getDigValueIndex::invalid nValueNum:%d, tag_name = %s", nValueNum,stUpdateDiInfo.tag_name);
return -1;
}
//得到分量号索引
//============================================================================================
int nIndex = (int)(stUpdateDiInfo.column_name[5] - 48);//ascii '0'=48
if (nIndex > nValueNum || nIndex < 1)
{
LOGERROR( "getDigValueIndex::invalid nIndex:%d, nValueNum:%d, tag_name = %s, column_name = %s",
nIndex, nValueNum, stUpdateDiInfo.tag_name, stUpdateDiInfo.column_name);
return -1;
}
return nIndex;
}
/**
@brief
@param const SChangeDiInfo &stChangeDiInfo: FES nValueNum
@return
@retval
*/
int CDigProcess::getDigPartIndex(const SChangeDiInfo &stChangeDiInfo,const int nValueNum)
{
//判读 DI 分量数是否合法
//============================================================================================
if (nValueNum > MAX_DI_BIT_NUM || nValueNum < 1)
{
LOGERROR("getDigValueIndex::invalid nValueNum:%d, tag_name = %s", nValueNum,stChangeDiInfo.tag_name);
return -1;
}
//得到分量号索引
//============================================================================================
int nIndex = (int)(stChangeDiInfo.column_name[5] - 48);//ascii '0'=48
if (nIndex > nValueNum || nIndex < 1)
{
LOGERROR( "getDigValueIndex::invalid nIndex:%d, nValueNum:%d, tag_name = %s, column_name = %s",
nIndex, nValueNum, stChangeDiInfo.tag_name, stChangeDiInfo.column_name);
return -1;
}
return nIndex;
}
/**
@brief
@param const nLastStatus: stUpdateDiInfo
@return TURE FLASE
@retval
*/
bool CDigProcess::isUpdatedByValidData(const int nLastStatus,const SUpdateDiInfo &stUpdateDiInfo )
{
map <string, int>::iterator pos;
string strTagName = stUpdateDiInfo.tag_name;
if( (nLastStatus & (1 << m_nMenuStateDiInvalid)) ) //上次无效=4未初始化
{
return false;
}
int64 lCurTimes = getUTCTimeSec();
if((lCurTimes - m_nStartupTimes) <= m_nStartAlarmDelay) return false; //大于启动延时如果全数据有变化才会产生告警用于FES 启动比较慢的情况)
pos = m_mapUpdatePackRecord.find(stUpdateDiInfo.tag_name);
if (pos == m_mapUpdatePackRecord.end()) //没找到
{
//实时库点状态不是工况退出且全数据状态不是工况退出
if ( !(nLastStatus & (1 << m_nMenuStateDiInvalid)) //上次状态没有异常
&& !(stUpdateDiInfo.status & (1 << m_nMenuStateDiInvalid )) ) //当前状态没有异常
{
m_mapUpdatePackRecord[strTagName] = 0;
}
return false;
}
else
{
return true;
}
return true;
}
/**
@brief
@param const SFesUpdateDiPkg &stUpdateDiPkg: FES
@return
@retval
*/
int CDigProcess::processDiUpdate(const SFesUpdateDiPkg &stUpdateDiPkg)
{
int nLoop=0;
int nRetCode;
int nIndex; //记录INDEX
int nUpdateNum;
map<string, int> mapUpdatePoint;
SDigPointAll stDigPointAll;
nUpdateNum = stUpdateDiPkg.stdidata_size();
if (nUpdateNum == 0)
{
LOGWARN( "ProcessDiUpdate:nUpdateNum =0,return!");
return -1;
}
bool bUpdatedByValidDataFlag = (true);//在本进程重启后在本包全数据之前点表中的值已被全数据更新
if (stUpdateDiPkg.ultime() == 0)
{
LOGWARN( "ProcessDiUpdate:ultime = %ld", stUpdateDiPkg.ultime());
}
LOGDEBUG( "ProcessDiUpdate:收到全数据报文,数目[%d],时间[%" PRId64 "]", nUpdateNum,(int64)stUpdateDiPkg.ultime());
for (nLoop = 0; nLoop < nUpdateNum; ++nLoop)
{
SUpdateDiInfo stUpdateDiInfo;
SFesDiDataWithoutTm stDiData = stUpdateDiPkg.stdidata(nLoop);
strcpy(stUpdateDiInfo.table_name, (const char *)stDiData.strapptablename().c_str());
strcpy(stUpdateDiInfo.tag_name, (const char *)stDiData.strapptagname().c_str());
strcpy(stUpdateDiInfo.column_name, (const char *)stDiData.strappcolumnname().c_str());
stUpdateDiInfo.value = 0x01 & stDiData.nvalue();
stUpdateDiInfo.status = 0xffff & stDiData.ustatus();
//LOGDEBUG("raw stUpdateDiInfo: tag_name = %s, column_name = %s, value = %d,status = %d",
// stUpdateDiInfo.tag_name, stUpdateDiInfo.column_name, stUpdateDiInfo.value, stUpdateDiInfo.status);
m_ptrDataProcApi->changeDigStatusRawToRipe(stUpdateDiInfo.status, stUpdateDiInfo.status);
//从实时库获取记录信息到结构体stDigPointAll
//============================================================================================
nIndex = m_ptrRdbTableMng->searchRecordByKey(RT_DIG_TBL,(const void*)stUpdateDiInfo.tag_name);
if (nIndex <0)
{
LOGERROR( "nIndex = %d, tag_name = %s, searchRecordByKey error!",
nIndex, stUpdateDiInfo.tag_name);
continue;
}
nRetCode = m_ptrRdbTableMng->getRecordAllColumnByIndex(RT_DIG_TBL, nIndex,stDigPointAll) ;
if (nRetCode == false)
{
LOGERROR( "nRetCode = %d, tag_name = %s, m_rdbDigTable.getRecordByKey error!",
nRetCode, stUpdateDiInfo.tag_name);
continue;
}
//判断是否本进程重启后在本包全数据之前是否点表中的值已被全数据更新;
//前提:工况退出会出现在本包中所有记录中
//============================================================================================
//if (nLoop == 0) //用第一个记录代表本包全数据
{
bUpdatedByValidDataFlag = isUpdatedByValidData(stDigPointAll.status,stUpdateDiInfo);
}
//获取数字量分量号
//============================================================================================
int nDigPartIndex = getDigPartIndex(stUpdateDiInfo,stDigPointAll.value_num) ;
if( nDigPartIndex <1)
{
LOGERROR( "invalid nDigPartIndex nValueNum:%d, tag_name = %s, column_name = %s",
stDigPointAll.value_num,stUpdateDiInfo.tag_name,stUpdateDiInfo.column_name);
continue;
}
// 从实时库RDB 得到全数据分量的值和状态(上次的值和状态)
//============================================================================================
int nLastValue = 0,nLastStatus = 0;
if(false == getValuexStatusx(stDigPointAll,nDigPartIndex,nLastValue,nLastStatus))
{
LOGERROR("getValuexStatusx: tagName = %s, 获取分量值得错误!", stUpdateDiInfo.tag_name);
continue;
}
// 分量值和状态有变化->更新全数据分量的值和状态
// 修改 value1~5status1~5 last_update_time 不管是否修改设备表(点表)中值域的值
//============================================================================================
int64 nUpdateTime = stUpdateDiPkg.ultime();
if(updateDigitalPart(stUpdateDiInfo,nDigPartIndex,nUpdateTime,nLastValue,nLastStatus)) //分量有变化
{
mapUpdatePoint[string(stUpdateDiInfo.tag_name)] = nIndex;
}
}
//处理更新点MAP中的数据
//============================================================================================
updateDigValueStatus(mapUpdatePoint, bUpdatedByValidDataFlag,(int64)stUpdateDiPkg.ultime());
return 1;
}
/**
@brief
@param SDigAlarmPara stDigAlmParaMAP
int nNewStatus
@return
@retval
*/
void CDigProcess::setAbnormalStatus(const SDigPointAll & stDigPoint,const SDigAlarmPara &stDigAlmPara,int &nNewStatus)
{
int nOldStatus = nNewStatus;
int nLastStatus = stDigPoint.status;
//新值=未复归,老状态已经复归 ==>状态字增加未复归
if ( stDigAlmPara.is_abnormal && !(nLastStatus & (1 << m_nMenuStateDiAbnormal)) )
{
m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, nNewStatus, nOldStatus,1 << m_nMenuStateDiAbnormal,0,
STATUS_ORI_RECV); //add DiAbnormal flag
}
else if ( !stDigAlmPara.is_abnormal && (nLastStatus & (1 << m_nMenuStateDiAbnormal)) )
{
m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, nNewStatus, nOldStatus,0,1 << m_nMenuStateDiAbnormal,
STATUS_ORI_RECV); //del DiAbnormal flag
}
//LOGDEBUG("setAbnormalStatus 标签点[%s] 未复归=[%d],旧状态=[%d],新状态=[%d].",stDigPoint.tag_name,
// stDigAlmPara.is_abnormal,nOldStatus,nNewStatus);
return;
}
/**
@brief VALUE1~5 VALUE ,status
@param map<string, int> &mapUpdatePointMAP
bool bValidChange
int second int msecond
@return
@retval
*/
void CDigProcess::updateDigValueStatus(map<string, int> &mapUpdatePoint,
bool bValidChange, int64 lUpdateTimes)
{
int nRetCode;
int nNewStatus;
int nNewValue;
map <string, int>::iterator pos;
SDigPointAll stDigPointAll;
string strKeyIdTag;
for (pos = mapUpdatePoint.begin(); pos != mapUpdatePoint.end(); ++pos)
{
strKeyIdTag = RT_DIG_TBL;
strKeyIdTag += ".";
strKeyIdTag += pos->first.c_str();
strKeyIdTag += ".value";
nRetCode = m_ptrRdbTableMng->getRecordAllColumnByIndex(RT_DIG_TBL,pos->second,stDigPointAll);
if (nRetCode == false)
{
LOGERROR( "UpdateDigValueStatusnRetCode = %d, tag_name = %s, getRecordByIndex error!",
nRetCode, pos->first.c_str());
continue;
}
//计算点不刷新fes实时值
//===========================================================================================
if((stDigPointAll.point_property & (1<<0)) == 1) //计算点
{
LOGDEBUG("UpdateDigValueStatus, 计算点[%s]不刷新fes实时值.",stDigPointAll.tag_name);
continue ;
}
//下面开始通过status1...status5得到status状态OK后同时删除通信状态和无效状态
//==========================================================================================
getStatusByStatusx(stDigPointAll,nNewStatus) ; //通过单分量状态或者总状态 备注:双分量一个状态不对总体就不对
//LOGDEBUG("UpdateDigValueStatus: getStatusByStatusx tag_name = %s, nNewStatus = %d",
// stDigPointAll.tag_name, nNewStatus);
//下面开始通过 value1...value5 得到value
//==========================================================================================
int valuex[MAX_DI_BIT_NUM];
int statusx[MAX_DI_BIT_NUM];
initValuexStatusx(stDigPointAll,&valuex[0],&statusx[0]);//初始化分量值到valuexstatusx
nNewValue = getValueByValuex(stDigPointAll.value_num,&valuex[0],&statusx[0]); //得到合成值
if (nNewValue < 0)
{
LOGINFO("UpdateDigValueStatusgetValueByValuex Error");
continue ;
}
//通过状态文本获取报警方式,报警显示文本;
SDigAlarmPara stDigAlmPara;
getDigAlarmPara(stDigPointAll,nNewValue ,stDigAlmPara);
//老状态报警未复归;新状态已经复归 ==>状态字增加报警未复归
setAbnormalStatus(stDigPointAll,stDigAlmPara,nNewStatus);
//实时值发生改变-修改实时值-rdb
if (stDigPointAll.value != nNewValue)
{
//在本进程重启后在本包全数据之前点表中的值是否已被全数据更新,是:发送报警 否:不发送报警
LOGDEBUG("UpdateDigValueStatus::tagname = %s, value = %d,nNewStatus = %d, times = %ld",
stDigPointAll.tag_name, stDigPointAll.value,nNewStatus, lUpdateTimes);
nRetCode = processValueChange(stDigPointAll,stDigAlmPara,nNewValue,nNewStatus,lUpdateTimes,bValidChange);
if (nRetCode < 0)
{
LOGERROR( " ProcessValueChange error tag_name = %s", stDigPointAll.tag_name);
}
}
else if (stDigPointAll.status != nNewStatus) //状态发生改变
{
nRetCode = m_ptrRdbTableMng->updateRecordOneValueByIndex(RT_DIG_TBL, pos->second, "status", nNewStatus);
if (nRetCode == false)
{
LOGERROR( "nRetCode = %d, tag_name = %s, updateRecordByIndex error!", nRetCode,
pos->first.c_str());
continue;
}
//增加变位告警信息
m_ptrDataPublish->addOneChangeInt(stDigPointAll.location_id,stDigPointAll.sub_system, RT_DIG_TBL, \
stDigPointAll.tag_name, "value", nNewValue,nNewStatus);
}
else
{
//LOGDEBUG("UpdateDigValueStatus: 标签[%s]值和状态未发送改变, nNewValue = %d,nNewStatus = %d .",
// stDigPointAll.tag_name, nNewValue, nNewStatus);
}
}
return;
}
/**
@brief
@param stDigPointAll: INT
nNewStatus: out
@return
@retval
*/
void CDigProcess::getStatusByStatusx(const SDigPointAll&stDigPointAll,int &nNewStatus )
{
//下面开始通过status1...status5得到status
//===================================================================================================
bool bIsTxOff = false;
bool bIsInvalid = false;
//如果存在工况退出、非实测值这两种情况则status域必须加上此标志
//===================================================================================================
if (getDigSpelStatus(bIsTxOff, bIsInvalid, stDigPointAll) < 0)
{
LOGERROR("getStatusByStatusxGetDiStatusSpelFlag error!tag_name = %s", stDigPointAll.tag_name);
return;
}
nNewStatus = stDigPointAll.status; //新状态赋值
//处理工况退出状态
//===================================================================================================
if ( bIsTxOff ) //增加通讯异常状态
{
m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, nNewStatus, nNewStatus, 1 << m_nMenuStateDiGkOff, 0,
STATUS_ORI_RECV); //add m_nMenuStateDiGkOff flag
}
else //删除通讯异常状态
{
m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, nNewStatus, nNewStatus, 0, 1 << m_nMenuStateDiGkOff,
STATUS_ORI_RECV); //del m_nMenuStateDiGkOff flag
}
//处理无效状态
//===================================================================================================
if ( bIsInvalid ) //添加无效
{
m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, nNewStatus, nNewStatus, 1 << m_nMenuStateDiInvalid, 0,
STATUS_ORI_RECV); //add MENU_STATE_DI_INVALID flag
}
else //删除无效
{
m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, nNewStatus, nNewStatus, 0, 1 << m_nMenuStateDiInvalid,
STATUS_ORI_RECV); //del MENU_STATE_DI_INVALID flag
}
//如果没有不正常,增加状态正常位置。
m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, nNewStatus, nNewStatus, 0, 0,
STATUS_ORI_RECV); //for initialize ,主要用于判是否正常状态
//LOGDEBUG("getStatusByStatusx: getNewStatus tag_name = %s, value = %d,status = %d",
// stDigPointAll.tag_name, stDigPointAll.value, nNewStatus);
return ;
}
/**
@brief DI变化MAP缓冲区
@param
@return
@retval
*/
void CDigProcess::checkDiChgBuf()
{
int nRetCode;
int nResultValue;
int nValueNum;
int nNewStatus;
int64 nLastChgMescond = 0;
map <string, SDiChange>::iterator pos;
int64 ulCurMsec = (int64)getMonotonicMsec();
for (pos = m_mapDiChgBuf.begin(); pos != m_mapDiChgBuf.end(); )
{
if(ulCurMsec - pos->second.first_chg_time > (pos->second.input_delay_time*1000) )
{
SDigPointAll stDigPointAll;
string strTagName = pos->first.c_str();
strTagName.resize(64);
nRetCode = m_ptrRdbTableMng->getRecordAllColumnByKey(RT_DIG_TBL,strTagName.c_str(), stDigPointAll);
if (nRetCode <=0 )
{
LOGERROR("CheckDiChgBuf::nRetCode = %d, tag_name = %s, 获取测点参数错误!", nRetCode, strTagName.c_str());
m_mapDiChgBuf.erase(pos++);
continue;
}
nValueNum = stDigPointAll.value_num;
if (nValueNum > MAX_DI_BIT_NUM || nValueNum <= 0 )
{
LOGINFO( "CheckDiChgBuf::nValueNum=%d > MAX_DI_BIT_NUM", nValueNum);
m_mapDiChgBuf.erase(pos++);
continue ;
}
int valuex[MAX_DI_BIT_NUM]={0};
int statusx[MAX_DI_BIT_NUM]={0};
initValuexStatusx(stDigPointAll,&valuex[0],&statusx[0]);//初始化分量值到valuexstatusx
//获得最新报警时间
int nLoop;
nLastChgMescond = 0;
for (nLoop = 0 ; nLoop < nValueNum; nLoop++)
{
if (pos->second.di_bit_chg_array[nLoop].use_flag == SHARE_BUF_USE)
{
valuex[nLoop] = pos->second.di_bit_chg_array[nLoop].value;
statusx[nLoop] = pos->second.di_bit_chg_array[nLoop].status;
if (nLastChgMescond < pos->second.di_bit_chg_array[nLoop].times) //目前未处理msecond
{
nLastChgMescond = pos->second.di_bit_chg_array[nLoop].times;
}
}
}
nResultValue = getValueByValuex(stDigPointAll.value_num,&valuex[0],&statusx[0]);//通过DI分量得到DI值
if (nResultValue < 0)
{
LOGERROR("CheckDiChgBuf::getValueByValuex return Error,nValueNum= %d", nValueNum);
m_mapDiChgBuf.erase(pos++);
continue ;
}
//下面开始通过status1...status5得到status状态OK后同时删除通信状态和无效状态
//==========================================================================================
getStatusByStatusx(stDigPointAll,nNewStatus) ; //通过单分量状态或者总状态 备注:双分量一个状态不对总体就不对
//for (nLoop = 0; nLoop < nValueNum; ++nLoop)//通过状态分量得到状态这里合并但是没有取消状态Off->off
//{
// m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, nNewStatus, nNewStatus, statusx[nLoop], 0, STATUS_ORI_RECV,1);
//}
SDigAlarmPara stDigAlmPara;
getDigAlarmPara(stDigPointAll,nResultValue ,stDigAlmPara);
setAbnormalStatus(stDigPointAll,stDigAlmPara,nNewStatus); //设置复归状态
if (stDigPointAll.value != nResultValue || stDigPointAll.status != nNewStatus) //状态变化或者值变化
{
if (stDigPointAll.value != nResultValue) //值变化
{
nRetCode = processValueChange(stDigPointAll,stDigAlmPara,nResultValue,nNewStatus,nLastChgMescond,true);
if (nRetCode < 0)
{
LOGERROR("CheckDiChgBuf::ProcessValueChange error tag_name = %s", stDigPointAll.tag_name);
m_mapDiChgBuf.erase(pos++);
continue;
}
}
else
{
std::vector<RSQL_UPD_COLUMN> vecUpdColumn ;
CRdbPublic::addUpColumnInfo(vecUpdColumn ,"value", nResultValue);
CRdbPublic::addUpColumnInfo(vecUpdColumn ,"status", nNewStatus);
int nRetCode = m_ptrRdbTableMng->updateRecordMultiValueByKey(RT_DIG_TBL,(const void*)stDigPointAll.tag_name,vecUpdColumn);
if (nRetCode == false)
{
LOGERROR("CheckDiChgBuf::nRetCode = %d, tag_name = %s, updateRecordMultiValueByKey error!", nRetCode,
pos->first.c_str());
m_mapDiChgBuf.erase(pos++);
continue;
}
m_ptrDataPublish->addOneChangeInt(stDigPointAll.location_id,stDigPointAll.sub_system, RT_DIG_TBL, stDigPointAll.tag_name,
"value", nResultValue,nNewStatus);
}
}
else
{
LOGDEBUG("CheckDiChgBuf::tag_name=%s, value=%d, status=%d, delay buf not change",
pos->first.c_str(), nResultValue, nNewStatus);
}
m_mapDiChgBuf.erase(pos++);
}
else
{
++pos;
}
}
return;
}
/**
@brief DI SOE MAP缓冲区
@param
@return
@retval
*/
void CDigProcess::checkDiSoeBuf()
{
int nRetCode;
map <string, SDiChange>::iterator pos;
int64 ulCurMsec = (int64)getMonotonicMsec();
for (pos = m_mapDiSoeBuf.begin(); pos != m_mapDiSoeBuf.end(); )
{
if((ulCurMsec - (int64)(pos->second.first_chg_time)) > (int64)(pos->second.input_delay_time*1000))
{
SDigPointAll stDigPointAll;
string strTagName = pos->first.c_str() ;
strTagName.resize(64);
nRetCode = m_ptrRdbTableMng->getRecordAllColumnByKey(RT_DIG_TBL,strTagName.c_str(), stDigPointAll);
if (nRetCode <=0 )
{
LOGERROR("CheckDiSoeBuf::nRetCode = %d, tag_name = %s, 获取实时值 error!", nRetCode, strTagName.c_str());
m_mapDiSoeBuf.erase(pos++);
continue;
}
int nValueNum = stDigPointAll.value_num;
if (nValueNum > MAX_DI_BIT_NUM || nValueNum <= 0 )
{
LOGINFO( "CheckDiSoeBuf::nValueNum=%d > MAX_DI_BIT_NUM", nValueNum);
m_mapDiSoeBuf.erase(pos++);
continue ;
}
int valuex[MAX_DI_BIT_NUM] ={0};
int statusx[MAX_DI_BIT_NUM]={0};
//initValuexStatusx(stDigPointAll,&valuex[0],&statusx[0]);//初始化分量值到valuexstatusx
//获得最新报警时间 报警分量信息初始化到valuex statusx中
//==============================================================================================
int nLoop =0 ;
int64 nLastChgMescond = 0;
for (nLoop = 0 ; nLoop < nValueNum; nLoop++)
{
if (pos->second.di_bit_chg_array[nLoop].use_flag == SHARE_BUF_USE)
{
valuex[nLoop] = pos->second.di_bit_chg_array[nLoop].value;
statusx[nLoop] = pos->second.di_bit_chg_array[nLoop].status;
if (nLastChgMescond < pos->second.di_bit_chg_array[nLoop].times)
{
nLastChgMescond = pos->second.di_bit_chg_array[nLoop].times;
}
}
}
//通过分量获取合成的值
//合成后即使值不对也产生无效告警合成周期超时情况可能产生2条告警
//==============================================================================================
int nRetValue = getValueByValuex(stDigPointAll.value_num,&valuex[0],&statusx[0]);
if (nRetValue < 0)// 分量错误
{
LOGERROR("checkDiSoeBuf::getValueByValuex Error,nRetValue=%d, nValueNum= %d",nRetValue, nValueNum);
m_mapDiSoeBuf.erase(pos++);
continue ;
}
//或者报警状态文本
SDigAlarmPara stDigAlmPara;
getDigAlarmPara(stDigPointAll,nRetValue ,stDigAlmPara);
//产生SOE报警
//==============================================================================================
addOneDigAlarm(ALM_TYPE_SOE,stDigPointAll,stDigAlmPara,nLastChgMescond) ;
m_mapDiSoeBuf.erase(pos++);
}
else
{
++pos;
}
}
return;
}
/**
@brief
@param char *strAlarm: OUT
SDiAlarm *stAlarm: INT
@return >0 <=0
@retval
*/
int CDigProcess::getDigAlarmDesc(string &strAlarm,const string &strTagName,\
const string& strDevTagName,const string& strStatusText,const int nDescFlag)//ALARM_DESC_POINT_FLAG
{
int nRetValue = 1;
int nRetCode = 0;
strAlarm = strStatusText ;
return 0 ;
string strName;
string strTempTagName = strTagName;
strTempTagName.resize(64);
string strTempDevTagName = strDevTagName;
strTempDevTagName.resize(64);
if (nDescFlag == ALARM_DESC_POINT_FLAG)
{
nRetCode = m_ptrDataProcApi->getNameStringByTag(RT_DIG_TBL, strTempTagName.c_str(), strName);
if (nRetCode < 0)
{
LOGINFO("nRetCode = %d, m_ptrDataProcApi->getNameStringByTag ERROR,tag_name = %s",
nRetCode, strTagName.c_str());
strName = strTagName;
nRetValue = -1;
}
strAlarm = strName +" "+ strStatusText;
}
else if (nDescFlag == ALARM_DESC_DEV_FLAG)
{
nRetCode = m_ptrDataProcApi->getNameStringByTag(RT_DEV_INFO, strTempDevTagName.c_str(), strName);
if (nRetCode < 0)
{
LOGERROR("nRetCode = %d, m_ptrDataProcApi->getNameStringByTag ERROR,tag_name = %s",
nRetCode, strDevTagName.c_str());
strName = strDevTagName;
nRetValue = -1;
}
strAlarm = strName ;
}
else
{
LOGERROR( "nDescFlag = %d ERROR", nDescFlag);
strName = strTagName;
strAlarm = strName ;
nRetValue = -1;
}
return nRetValue;
}
/**
@brief
@param const SFesChangeDiPkg &stChangeDiPkg: 线
int nSoeFlag: INT SOE标志
@return >0 <=0
@retval
*/
int CDigProcess::processDiChange(const SFesChangeDiPkg &stChangeDiPkg)
{
int nChangeNum;
int nLoop = 0;
nChangeNum = stChangeDiPkg.stdidata_size();
if(nChangeNum>0)
{
m_nChangeCount = m_nChangeCount + nChangeNum;
LOGDEBUG("ProcessDiChange:收到变化数据报文,数目[%d],总计收到数目[%d],时间[%" PRId64 "].",nChangeNum,m_nChangeCount,(int64)stChangeDiPkg.stdidata(0).ultime());
}
for (nLoop = 0; nLoop < nChangeNum; ++nLoop)
{
SChangeDiInfo stChangeInfo;
SFesDiDataWithTm stDiData = stChangeDiPkg.stdidata(nLoop);
strcpy(stChangeInfo.table_name, (const char *)stDiData.strapptablename().c_str());
strcpy(stChangeInfo.tag_name, (const char *)stDiData.strapptagname().c_str());
strcpy(stChangeInfo.column_name, (const char *)stDiData.strappcolumnname().c_str());
stChangeInfo.nValue = 0x01 & stDiData.nvalue();
stChangeInfo.nStatus = 0xffff & stDiData.ustatus();
stChangeInfo.lTimes = stDiData.ultime();
if (stChangeInfo.lTimes < 0)
{
LOGERROR("CDigProcess::ProcessDiChange(),strKeyIdTag = %s.%s.%s, value = %d,status = %d, times = [%" PRId64 "] < 0 error!",
stChangeInfo.table_name, stChangeInfo.tag_name, stChangeInfo.column_name, stChangeInfo.nValue,
stChangeInfo.nStatus, stChangeInfo.lTimes);
continue;
}
//LOGDEBUG("CDigProcess::ProcessDiChange(),strKeyIdTag = %s.%s.%s, value = %d,status = %d, times = %d",
// stChangeInfo.table_name, stChangeInfo.tag_name, stChangeInfo.column_name, stChangeInfo.nValue,
// stChangeInfo.nStatus, stChangeInfo.lTimes);
processOneDiChange(stChangeInfo);
}
return 1;
}
/**
@brief SOE事件
@param
@return
@retval
*/
int CDigProcess::processSoeEvent(kbd_idlfile::SFesSoeEventPkg objFesSoeEventPkg) //处理soe事件
{
int nLoop=0;
int nSoeNum;
int nRetCode;
nSoeNum = objFesSoeEventPkg.stsoeevent_size();
//m_nFesSoeSum += nSoeNum;
LOGDEBUG("CDigProcess::ProcessSoeEvent(), recv SoeNum = %d",nSoeNum);
for (nLoop = 0; nLoop < nSoeNum; ++nLoop)
{
SChangeDiInfo stChangeInfo;
SFesSoeEventInfo stOneSoeEvent = objFesSoeEventPkg.stsoeevent(nLoop);
strcpy(stChangeInfo.table_name, (const char *)stOneSoeEvent.strapptablename().c_str());
strcpy(stChangeInfo.tag_name, (const char *)stOneSoeEvent.strapptagname().c_str());
strcpy(stChangeInfo.column_name, (const char *)stOneSoeEvent.strappcolumnname().c_str());
stChangeInfo.nValue = 0x01 & stOneSoeEvent.nvalue();
stChangeInfo.nStatus = 0xffff & stOneSoeEvent.ustatus();
stChangeInfo.lTimes = stOneSoeEvent.ultime();
string strFaultDesc = stOneSoeEvent.strfaultdesc();
if (stChangeInfo.lTimes < 0)
{
LOGERROR("CDigProcess::ProcessSoeEvent(),strKeyIdTag = %s.%s.%s, value = %d,status = %d, times = [%" PRId64 "] < 0 error!",
stChangeInfo.table_name, stChangeInfo.tag_name, stChangeInfo.column_name, stChangeInfo.nValue,
stChangeInfo.nStatus, stChangeInfo.lTimes);
continue;
}
//LOGINFO("CDigProcess::ProcessSoeEvent(), strKeyIdTag = %s.%s.%s, value = %d,status = %d, times = %ld,strFaultDesc=%s",
// stChangeInfo.table_name, stChangeInfo.tag_name, stChangeInfo.column_name, stChangeInfo.nValue,
// stChangeInfo.nStatus, stChangeInfo.lTimes,strFaultDesc.c_str());
nRetCode = processOneSoeEvent(stChangeInfo,strFaultDesc);
if (nRetCode < 0)
{
LOGERROR("ProcessOnePscadaSoe Error");
continue;
}
//stSoeDataPkg.add_seq_soe()->CopyFrom(stSoeDataMsg);
}
return 1;
}
/**
@brief DI点的变位ProcessValueChange进行值变化处理
@param SChangeDiInfo stChangeInfo: IN DI点信息结构
@return >0 <=0
@retval
*/
int CDigProcess::processOneDiChange(SChangeDiInfo &stChangeInfo)
{
string strKeyIdTag = "";
strKeyIdTag = RT_DIG_TBL;
strKeyIdTag += ".";
strKeyIdTag += stChangeInfo.tag_name;
strKeyIdTag += ".value";
//在此之前记住那些应该处理的状态(不出现在状态菜单中的状态)
//将前置发过来的状态转换成数字量状态菜单对应的值,删掉不处理的状态
m_ptrDataProcApi->changeDigStatusRawToRipe(stChangeInfo.nStatus, stChangeInfo.nStatus); //获取新状态
if ( stChangeInfo.nStatus & (1 << m_nMenuStateDiGkOff) )
{
LOGDEBUG("stChangeInfo.status = %d, include m_nMenuStateDiGkOff bit",
stChangeInfo.nStatus);
}
LOGDEBUG("ProcessOneDiChange::strKeyIdTag = %s.%s.%s, value = %d,status = %d, times=[%" PRId64 "].",
stChangeInfo.table_name, stChangeInfo.tag_name, stChangeInfo.column_name, stChangeInfo.nValue,
stChangeInfo.nStatus, stChangeInfo.lTimes);
SDigPointAll stDigPointAll;
//得到指定标签点的实时库记录
//=================================================================================
int nRetCode = m_ptrRdbTableMng->getRecordAllColumnByKey(RT_DIG_TBL,stChangeInfo.tag_name,stDigPointAll);
if (nRetCode <=0 )
{
LOGERROR("nRetCode = %d, tag_name = %s, getRecordAllColumnByKey error!",
nRetCode, stChangeInfo.tag_name);
return -1;
}
//计算点不刷新fes实时值
//===========================================================================================
if((stDigPointAll.point_property & (1<<0)) == 1) //计算点
{
LOGDEBUG("ProcessOneDiChange, 计算点[%s]不刷新fes实时值.",stDigPointAll.tag_name);
return 1;
}
//首先更新分量实时值和状态(不管的单点还是双点)
//============================================================================================
//获取数字量分量号
int nDigPartIndex = getDigPartIndex(stChangeInfo,stDigPointAll.value_num) ;
if( nDigPartIndex <1)
{
LOGERROR( "invalid nDigPartIndex nValueNum:%d, tag_name = %s, column_name = %s",
stDigPointAll.value_num,stChangeInfo.tag_name,stChangeInfo.column_name);
return -1;
}
// 分量值和状态有变化->更新全数据分量的值和状态
// 修改 value1~5status1~5 last_update_time 不管是否修改设备表(点表)中值域的值
//============================================================================================
if(false == updateDigitalPart(stChangeInfo,nDigPartIndex)) //分量有变化,x修改分量值和状态
{
LOGERROR("processOneDiChange::updateDigitalPart TagName=%s error!", stChangeInfo.tag_name);
return -1;
}
int nNewStatus(0);
if (stDigPointAll.value_num == 1)
{
//下面开始通过status1...status5得到status状态OK后同时删除通信状态和无效状态
//==========================================================================================
stDigPointAll.value1 = stChangeInfo.nValue;
stDigPointAll.status1 = stChangeInfo.nStatus;
getStatusByStatusx(stDigPointAll,nNewStatus) ; //通过单分量状态或者总状态 备注:双分量一个状态不对总体就不对
//LOGDEBUG("ProcessDiChange,getNewStatus strKeyIdTag = %s.%s.%s, value = %d,status = %d, times = [%" PRId64 "] ",
// stChangeInfo.table_name, stChangeInfo.tag_name, stChangeInfo.column_name, stChangeInfo.nValue,
// nNewStatus, stChangeInfo.lTimes);
SDigAlarmPara stDigAlmPara;
getDigAlarmPara(stDigPointAll,stChangeInfo.nValue ,stDigAlmPara);
setAbnormalStatus(stDigPointAll,stDigAlmPara,nNewStatus);
if ((stDigPointAll.value != stChangeInfo.nValue) || (stDigPointAll.status != nNewStatus)) //当变化的值和实时库中的值不同时
{
nRetCode = processValueChange(stDigPointAll,stDigAlmPara,stChangeInfo.nValue,nNewStatus,stChangeInfo.lTimes,true);
if (nRetCode < 0)
{
LOGERROR("ProcessValueChange error tag_name = %s", stChangeInfo.tag_name);
}
}
}
else //多分量处理
{
if( stDigPointAll.input_delay_time <= 0) stDigPointAll.input_delay_time = 1 ;//多分量延时时间=0
if (stDigPointAll.input_delay_time > 0) //数据量报警延时处理
{
addDigPartToBuff(m_mapDiChgBuf, strKeyIdTag, nDigPartIndex,stDigPointAll,stChangeInfo);
}
}
return 1;
//============================================================================================
/*
int nNewStatus(0);
if (nValueNum == 1)
{
m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, nNewStatus, stDigPointAll.status, stChangeInfo.nStatus, 0,
STATUS_ORI_RECV, 1);
//LOGDEBUG("ProcessDiChange,getNewStatus strKeyIdTag = %s.%s.%s, value = %d,status = %d, times = [%" PRId64 "] ",
// stChangeInfo.table_name, stChangeInfo.tag_name, stChangeInfo.column_name, stChangeInfo.nValue,
// nNewStatus, stChangeInfo.lTimes);
SDigAlarmPara stDigAlmPara;
getDigAlarmPara(stDigPointAll,stChangeInfo.nValue ,stDigAlmPara);
setAbnormalStatus(stDigPointAll,stDigAlmPara,nNewStatus);
if (stDigPointAll.value != stChangeInfo.nValue) //当变化的值和实时库中的值不同时
{
// 更新分量到实时库的值/状态/时间
//============================================================================================
if(false == updateDigitalPart(stChangeInfo,1)) //更新分量值到实时库
{
LOGERROR("processOneDiChange::updateDigitalPart TagName=%s error!", stChangeInfo.tag_name);
return -1;
}
nRetCode = processValueChange(stDigPointAll,stDigAlmPara,stChangeInfo.nValue,nNewStatus,stChangeInfo.lTimes,true);
if (nRetCode < 0)
{
LOGERROR("ProcessValueChange error tag_name = %s", stChangeInfo.tag_name);
}
}
else //当变化的值和实时库中的值相同时,状态不同
{
if (stDigPointAll.status != nNewStatus)//值相同,状态不同,,需要更新实时库,发变化数据和写全景库
{
if (false == updateDigStatus(stChangeInfo.tag_name,stChangeInfo.nStatus,nNewStatus,stChangeInfo.lTimes))
{
LOGERROR("updateDigStatus tag_name = %s, updateDigStatus error!", stChangeInfo.tag_name);
return -1;
}
m_ptrDataPublish->addOneChangeInt(stDigPointAll.location_id,stDigPointAll.sub_system,\
RT_DIG_TBL, stChangeInfo.tag_name, "value", stChangeInfo.nValue,nNewStatus);//增加变位事件
}
else//值和状态都相同,有可能是在全数据中已经更新过
{
//LOGINFO("CHG SINGLE: tag_name=%s, old_value=nNewValue=%d, old_status=nNewStatus=%d",
// stChangeInfo.tag_name, stChangeInfo.nValue, nNewStatus);
}
}
}
else //多分量处理
{
//获取数字量分量号
//============================================================================================
int nDigPartIndex = getDigPartIndex(stChangeInfo,stDigPointAll.value_num) ;
if( nDigPartIndex <1)
{
LOGERROR( "invalid nDigPartIndex:%d, nValueNum:%d, tag_name = %s, column_name = %s",
nDigPartIndex,stDigPointAll.value_num,stChangeInfo.tag_name,stChangeInfo.column_name);
return -1;
}
// 更新实时库的值/状态/时间
//============================================================================================
if(false == updateDigitalPart(stChangeInfo,nDigPartIndex)) //分量有变化更新到RDB
{
LOGERROR("updateDigitalPart:: TagName=%s index=%d, error!", stChangeInfo.tag_name,nDigPartIndex);
return -1;
}
//多分量延时时间=0
//===============================================================================================================
if( stDigPointAll.input_delay_time <= 0) stDigPointAll.input_delay_time = 1 ;
if (stDigPointAll.input_delay_time <= 0) //
{
int valuex[MAX_DI_BIT_NUM];
int statusx[MAX_DI_BIT_NUM];
//备注:如果原来实时库值=2 10bit0新值=1/0 都无法通过判断,导致不报警 BUG
initValuexStatusx(stDigPointAll,&valuex[0],&statusx[0]);//初始化分量值到valuexstatusx
int nResultValue = GetResultValueByValuex(stDigPointAll,&valuex[0], &statusx[0],&stChangeInfo);
if (nResultValue < 0)
{
LOGINFO("GetResultValueByValuex通过DI分量获取DI值错误分量非法");
return -1;
}
nNewStatus = stDigPointAll.status;
for (int nLoop = 0; nLoop < nValueNum; ++nLoop)
{
m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, nNewStatus, nNewStatus,statusx[nLoop],0,STATUS_ORI_RECV,1);
}
SDigAlarmPara stDigAlmPara;
getDigAlarmPara(stDigPointAll,nResultValue ,stDigAlmPara);
setAbnormalStatus(stDigPointAll,stDigAlmPara,nNewStatus);
if (stDigPointAll.value != nResultValue)
{
nRetCode = ProcessValueChange(stDigPointAll,stDigAlmPara,nResultValue,nNewStatus,stChangeInfo.lTimes,true);
if (nRetCode < 0)
{
LOGERROR( " ProcessValueChange error tag_name = %s", stDigPointAll.tag_name);
}
}
else
{
if (stDigPointAll.status != nNewStatus)
{
nRetCode = m_ptrRdbTableMng->updateRecordOneValueByKey(RT_DIG_TBL,(const void*)stChangeInfo.tag_name,"status",nNewStatus);
if (nRetCode == false)
{
LOGERROR( "nRetCode = %d, updateRecordOneValueByKey error!", nRetCode);
return -1;
}
m_ptrDataPublish->AddOneChangeInt(stDigPointAll.location_id,stDigPointAll.sub_system,\
RT_DIG_TBL, stChangeInfo.tag_name, "value", nResultValue,nNewStatus);
}
else
{
LOGINFO(" CHG MULTI:tag_name=%s, old_value=nNewValue=%d, old_status=nNewStatus=%d ",
stChangeInfo.tag_name, nResultValue, nNewStatus);
}
}
}
//多分量延时时间>=0,加入m_mapDiChgBuf
//==========================================================================================
else //数据量报警延时处理
{
addDigPartToBuff(m_mapDiChgBuf, strKeyIdTag, nDigPartIndex,stDigPointAll,stChangeInfo);
}
}
return 1;*/
}
/**
@brief DI点的变位ProcessValueChange进行值变化处理
@param SChangeDiInfo stChangeInfo: IN DI点信息结构
@return >0 <=0
@retval
*/
void CDigProcess::addOneDigAlarm(int nAlarmType,const SDigPointAll &stDigPointAll,SDigAlarmPara &stDigAlmPara,
const int64 lTimes,const string &strFaultDesc)
{
string strKeyIdTag = "";
strKeyIdTag = RT_DIG_TBL;
strKeyIdTag += ".";
strKeyIdTag += stDigPointAll.tag_name;
strKeyIdTag += ".value";
int nAlarmStatus = ALM_STAT_SOE ;
if(nAlarmType == ALM_TYPE_DI_CHANGE) //遥信变位
{
nAlarmStatus = ALM_STAT_DI_CHANGE ;
m_nChgAlarmCount = m_nChgAlarmCount+1;
LOGDEBUG( "addOneDigAlarm::ChgAlarmCount=%d!",m_nChgAlarmCount);
}
if(nAlarmType == ALM_TYPE_SOE)
{
nAlarmStatus = ALM_STAT_SOE ;
m_nSoeAlarmCount = m_nSoeAlarmCount+1;
LOGDEBUG( "addOneDigAlarm::SoeAlarmCount=%d!",m_nSoeAlarmCount);
}
//初始化报警 故障值文本。。。。
string strAlarmDesc = stDigAlmPara.display_value;
if(strlen(strFaultDesc.c_str())>0)
{
strAlarmDesc +=",";
strAlarmDesc +=strFaultDesc ;
}
if(getDigAlarmStatus(nAlarmStatus,stDigPointAll.point_type,stDigPointAll.point_sort)== false)
{
LOGWARN( "addOneDigAlarm::getDigAlarmStatus error,tag_name=%s!",stDigPointAll.tag_name);
}
m_ptrDataPublish->addOneDigAlarm(stDigPointAll,nAlarmType,nAlarmStatus,stDigAlmPara.alarm_manner,
strKeyIdTag,strAlarmDesc,lTimes);
return ;
}
/**
@brief DI点的变位ProcessValueChange进行值变化处理
@param SChangeDiInfo stChangeInfo: IN DI点信息结构
@return >0 <=0
@retval
*/
int CDigProcess::processOneSoeEvent(SChangeDiInfo &stChangeInfo,const string &strFaultDesc)
{
string strKeyIdTag = "";
strKeyIdTag = RT_DIG_TBL;
strKeyIdTag += ".";
strKeyIdTag += stChangeInfo.tag_name;
strKeyIdTag += ".value";
LOGDEBUG("ProcessOneSoeEvent::strKeyIdTag = %s.%s.%s, value = %d,status = %d, times =[%" PRId64 "].",
stChangeInfo.table_name, stChangeInfo.tag_name, stChangeInfo.column_name, stChangeInfo.nValue,
stChangeInfo.nStatus, stChangeInfo.lTimes);
//得到指定标签点的实时库记录
//==============================================================================================================
SDigPointAll stDigPointAll;
int nRetCode = m_ptrRdbTableMng->getRecordAllColumnByKey(RT_DIG_TBL,stChangeInfo.tag_name,stDigPointAll);
if (nRetCode <=0 )
{
LOGERROR("ProcessOneSoeEvent:: nRetCode = %d, tag_name = %s, getRecordAllColumnByKey error!",
nRetCode, stChangeInfo.tag_name);
return -1;
}
//设备禁止报警等,不报警 , SOE 不判断通讯状态
//=============================================================================================================
if(true == checkAlarmDisable(stDigPointAll.status,POINT_TYPE_DIG))
{
LOGINFO("ProcessOneSoeEvent:: 禁止告警tag_name = %s, return 1 ", stChangeInfo.tag_name);
return 1;
}
//置数、禁止刷新时不写事件,不写实时值
//=============================================================================================================
if (stDigPointAll.value_num == 1)
{
SDigAlarmPara stDigAlmPara;
getDigAlarmPara(stDigPointAll,stChangeInfo.nValue ,stDigAlmPara);
//产生SOE事件
//=========================================================================================================
addOneDigAlarm(ALM_TYPE_SOE,stDigPointAll,stDigAlmPara,stChangeInfo.lTimes,strFaultDesc) ;
}
//多分量情况
//=============================================================================================================
else
{
int nDigPartIndex = getDigPartIndex(stChangeInfo,stDigPointAll.value_num) ;
if (nDigPartIndex < 0)
{
LOGERROR( "ProcessOneSoeEvent::getDigPartIndex index<0 error.");
return -1;
}
//多分量延时时间=0
//=========================================================================================================
if (stDigPointAll.input_delay_time <= 0) //SOE 多位延迟最少1秒
stDigPointAll.input_delay_time = 1 ;
addDigPartToBuff(m_mapDiSoeBuf,strKeyIdTag, nDigPartIndex,stDigPointAll,stChangeInfo); //SOE分量加入队列进行延时判断
/*
if (stDigPointAll.input_delay_time <= 0) //
{
int valuex[MAX_DI_BIT_NUM] ={0};
int statusx[MAX_DI_BIT_NUM]={0};
//多分量的情况保证只有一个分量的值为1如果分量全部为0也不对
//====================================================================================================
initValuexStatusx(stDigPointAll,&valuex[0],&statusx[0]);//初始化分量值到valuexstatusx
int nResultValue = getResultValueByValuex(stDigPointAll,&valuex[0], &statusx[0],&stChangeInfo);
if (nResultValue < 0)
{
LOGINFO("ProcessOneSoeEvent::GetResultValueByValuex通过DI分量获取DI值错误分量非法");
return -1;
}
//增加SOE 事件发送到报警服务器
//====================================================================================================
SDigAlarmPara stDigAlmPara;
nRetCode = getDigAlarmPara(stDigPointAll,nResultValue ,stDigAlmPara); //获取状态文本失败
addOneDigAlarm(ALM_TYPE_SOE,stDigPointAll,stDigAlmPara,stChangeInfo.lTimes,strFaultDesc) ;
}
//多分量延时时间>=0,加入m_mapDiChgBuf
//========================================================================================================
else //数据量报警延时处理
{
addDigPartToBuff(m_mapDiSoeBuf,strKeyIdTag, nDigPartIndex,stDigPointAll,stChangeInfo);
}*/
}
return 1;
}
/**
@brief
@param INT SDigPointAll& stDigPointAllRDB实时信息
INT SDigAlarmPara &stDigAlmPara
@return <0 =0
@retval
*/
int CDigProcess::getDigAlarmPara(const SDigPointAll& stDigPointAll,int nValue,SDigAlarmPara &stDigAlmPara)
{
int nRetCode = -1 ;
SDigAlarmInfo stDigAlmInfo;
strcpy(stDigAlmInfo.state_text_name, stDigPointAll.state_text_name);
stDigAlmInfo.value = nValue;
stDigAlmInfo.alarm_priority = stDigPointAll.alarm_priority;
stDigAlmInfo.is_water_alm = stDigPointAll.is_water_alm;
stDigAlmInfo.is_ack_on_rtn = stDigPointAll.is_ack_on_rtn;
nRetCode = m_ptrDataProcApi->getDigAlarmPara(stDigAlmInfo, stDigAlmPara);
if (nRetCode <0 )
{
LOGDEBUG("getDigAlarmPara::tag_name(%s), getDigAlarmPara error!", stDigPointAll.tag_name);
}
//LOGDEBUG("getDigAlarmPara:测点[%s] 数字量文本=[%s],值=[%d],报警方式=[%d],未复归=[%d]!",stDigPointAll.tag_name,
// stDigPointAll.state_text_name, nValue,stDigAlmPara.alarm_manner,stDigAlmPara.is_abnormal);
return nRetCode;
}
/**
@brief
@param IN string strKeyIdTag KEY
IN const int nIndex
OUT mapDiChgBuf:
INT SDigPointAll& stDigPointAllRDB实时信息
INT SChangeDiInfo &stChangeInfoFES变化信息
@return
@retval
*/
void CDigProcess::addDigPartToBuff(std::map <std::string,SDiChange> &mapDiChgBuf,const string strKeyIdTag,
const int nIndex,const SDigPointAll& stDigPointAll,const SChangeDiInfo stChangeInfo)
{
map <string, SDiChange>::iterator itPos;
string strTagName = stChangeInfo.tag_name;
itPos = mapDiChgBuf.find(strTagName);
if (itPos == mapDiChgBuf.end()) //缓冲区没有找到
{
SDiChange stDiChgInfo;
strcpy(stDiChgInfo.key_id_tag, strKeyIdTag.c_str());
strcpy(stDiChgInfo.state_text_name, stDigPointAll.state_text_name);
stDiChgInfo.first_chg_time = (int64)getMonotonicMsec(); //初次变位时间
stDiChgInfo.location_id = stDigPointAll.location_id;
stDiChgInfo.region_id = stDigPointAll.region_id;
stDiChgInfo.input_delay_time = stDigPointAll.input_delay_time;
stDiChgInfo.value_num = stDigPointAll.value_num;
stDiChgInfo.di_bit_chg_array[nIndex - 1].use_flag = SHARE_BUF_USE;
stDiChgInfo.di_bit_chg_array[nIndex - 1].value = stChangeInfo.nValue;
stDiChgInfo.di_bit_chg_array[nIndex - 1].status = stChangeInfo.nStatus;
stDiChgInfo.di_bit_chg_array[nIndex - 1].times = stChangeInfo.lTimes;
mapDiChgBuf.insert(make_pair(strTagName, stDiChgInfo));
}
else
{
itPos->second.di_bit_chg_array[nIndex - 1].use_flag = SHARE_BUF_USE;
itPos->second.di_bit_chg_array[nIndex - 1].value = stChangeInfo.nValue; ;
itPos->second.di_bit_chg_array[nIndex - 1].status = stChangeInfo.nStatus;
itPos->second.di_bit_chg_array[nIndex - 1].times = stChangeInfo.lTimes;
}
return;
}
/**
@brief valuexstatusx
@param IN SDigPointAll stDigPoint:RDB实时值
OUT value[MAX_DI_BIT_NUM]: DI分量数据
OUT statusx[MAX_DI_BIT_NUM]:DI分量状态
@return
@retval
*/
void CDigProcess::initValuexStatusx(const SDigPointAll &stDigPoint,int *valuex,int *statusx)
{
if(valuex == NULL|| statusx == NULL)
return;
valuex[0] = stDigPoint.value1;
valuex[1] = stDigPoint.value2;
valuex[2] = stDigPoint.value3;
valuex[3] = stDigPoint.value4;
valuex[4] = stDigPoint.value5;
statusx[0] = stDigPoint.status1;
statusx[1] = stDigPoint.status2;
statusx[2] = stDigPoint.status3;
statusx[3] = stDigPoint.status4;
statusx[4] = stDigPoint.status5;
return;
}
/**
@brief DI DI值是
@param IN SDigPointAll stDigPoint:RDB实时值
IN SChangeDiInfo stChangeInfo:
OUT value[MAX_DI_BIT_NUM]: DI分量数据
OUT statusx[MAX_DI_BIT_NUM]:DI分量状态
@return DI值
@retval
*/
int CDigProcess::getValueByValuex(const int nValueNum,int *valuex,int */*statusx*/)
{
int nLoop;
int nRetValue = 0;
//分量数最大值判断
//==========================================================================================================
if ((nValueNum > MAX_DI_BIT_NUM) )
{
LOGERROR( "getValueByValuex分量数[%d]>MAX_DI_BIT_NUM Error", nValueNum);
return -1;
}
//分量值按位合并,从低到高[bit0~bt4]对应分量1~5
//==========================================================================================================
int nCount = 0; //分量值=1数量统计
for (nLoop = 0; nLoop < nValueNum; ++nLoop)
{
if (valuex[nLoop]) //分量=1
{
nCount++;
nRetValue += (1 << nLoop) ;
}
}
return nRetValue;
//分量有效判断
//==========================================================================================================
/*
if(nValueNum>1)
{
if((nRetValue ==0) || (nRetValue == ((1<<nValueNum) -1)) ) //全0||全1
{
LOGALARM( "getValueByValuexValue=%d,Num=%d Error!", nRetValue,nValueNum);
return -1;
}
}
return nRetValue;
*/
}
/**
@brief BUFFER
@param
@return
@retval
*/
void CDigProcess::checkBuffInfo()
{
checkDiSoeBuf();
checkDiChgBuf();
//CheckAlarmTimeBuf();
//CheckAlarmFreqBuf();
//CheckAlarmDelayBuf();
}
/**
@brief
@param
@return
@retval
*/
void CDigProcess::getTimeString(char *cTimeBuf, const int nSec, short sMsec, bool bMsecFlag)
{
struct tm *pCurTime;
time_t tTimes =(time_t)nSec;
pCurTime = localtime(&tTimes);
if (pCurTime == NULL)
{
LOGERROR("CDigProcess::GetTimeString(),localtime(&tTimes) return error !");
return;
}
if (bMsecFlag)
{
sprintf(cTimeBuf, "%04d年%02d月%02d日%02d时%02d分%02d秒%03d",
pCurTime->tm_year + 1900,
pCurTime->tm_mon + 1,
pCurTime->tm_mday,
pCurTime->tm_hour,
pCurTime->tm_min,
pCurTime->tm_sec,
sMsec);
}
else
{
sprintf(cTimeBuf, "%04d年%02d月%02d日%02d时%02d分%02d秒",
pCurTime->tm_year + 1900,
pCurTime->tm_mon + 1,
pCurTime->tm_mday,
pCurTime->tm_hour,
pCurTime->tm_min,
pCurTime->tm_sec);
strcat(cTimeBuf, " ");
}
return;
}
/*---------------------------------------------------------------------------------
- : StripWhiteSpace
- : Returns a string that has whitespace removed from the start and the end of the string
Whitespace means any character for which QChar::isSpace() returns TRUE. This includes
UNICODE characters with decimal values 9 (TAB), 10 (LF), 11 (VT),12 (FF), 13 (CR), and 32 (Space).
- : source_str
- : des_str
-------------------------------------------------------------------------------------*/
void CDigProcess::stripWhiteSpace(char *des_str, const char *source_str)
{
int nLoop;
int start_pos, end_pos;
int source_str_len;
source_str_len = strlen(source_str);
start_pos = 0;
for (nLoop = 0; nLoop < source_str_len; ++nLoop )
{
if ( (source_str[nLoop] != 9) && (source_str[nLoop] != 10)
&& (source_str[nLoop] != 11) && (source_str[nLoop] != 12)
&& (source_str[nLoop] != 13) && (source_str[nLoop] != 32) )
{
//start_pos = nLoop;
break;
}
else
{
++start_pos;
}
}
end_pos = source_str_len - 1;
for (nLoop = source_str_len - 1; nLoop >= 0; nLoop-- )
{
if ( (source_str[nLoop] != 9) && (source_str[nLoop] != 10)
&& (source_str[nLoop] != 11) && (source_str[nLoop] != 12)
&& (source_str[nLoop] != 13) && (source_str[nLoop] != 32) )
{
break;
}
else
{
end_pos--;
}
}
if (start_pos > end_pos)
{
des_str[0] = 0;
}
else
{
int des_str_len = end_pos - start_pos + 1;
memcpy(des_str, source_str + start_pos, des_str_len);
des_str[des_str_len] = 0;
}
}
/**
@brief //,
@param const char *strTagName
int flagSET_DATA_FLAG,1; UN_SET_DATA_FLAG,2;UN_INHABIT_REF_FLAG,3
@return
@retval
*/
int CDigProcess::processSetData(SDigPointAll &stDigPoint,const int nNewValue,const int nNewStatus ,const bool bNotAlarm )
{
int nRetCode = -1;
string strKeyTagName = stDigPoint.tag_name;
int nValueNum = stDigPoint.value_num;
if ( (nValueNum < 1) || (nValueNum > MAX_DI_BIT_NUM))
{
LOGWARN("ProcessSetData: nValueNum = %d is invalid (tag_name = %s)",stDigPoint.value_num, stDigPoint.tag_name);
return -1;
}
strKeyTagName.resize(64);
nRetCode = m_ptrRdbTableMng->updateRecordTwoValueByKey(RT_DIG_TBL, strKeyTagName.c_str(),"value", nNewValue,"status",nNewStatus);
if (nRetCode == false)
{
LOGWARN( "ProcessSetData, nRetCode = %d, strTableName = %s, strTagName = %s, value = %d, status = %d, updateRecordByKey error!",
nRetCode,RT_DIG_TBL, stDigPoint.tag_name, nNewValue, nNewStatus);
return -1;
}
//不是人工设置 || 值没有发生改变
if( stDigPoint.value == nNewValue )
{
LOGINFO("ProcessSetData,OldValue[%d]=NewValue[%d],return 1",stDigPoint.value,nNewValue);
return 1; //value not change return;
}
stDigPoint.value = nNewValue ; //更新值 用于报警
stDigPoint.status = nNewStatus ; //更新值 用于报警
SDigAlarmPara stDigAlmPara;
getDigAlarmPara(stDigPoint,stDigPoint.value ,stDigAlmPara);
bool bAlarmDisable = checkAlarmDisable(nNewStatus,POINT_TYPE_DIG) ;
if (stDigAlmPara.is_send_alarm &&(bNotAlarm == false) && (bAlarmDisable == false)) //状态变化
{
addOneDigAlarm(ALM_TYPE_DI_CHANGE,stDigPoint,stDigAlmPara) ;
}
return 1;
}
/**
@brief ,
@param const SLockDataPkg &stTransDataPkg
@return
@retval
*/
int CDigProcess::processOperate(const SOptSetDataPkg &stOptSetDataPkg,const int nOperateType)
{
int nNum = 0;
int nRetCode = 0;
nNum = stOptSetDataPkg.seq_set_data_info_size();
bool bInit = stOptSetDataPkg.package_head().b_not_alarm() ;
for (int nLoop = 0; nLoop < nNum; nLoop++)
{
int nNewStatus;
SOptSetDataMsg stOptSetData = stOptSetDataPkg.seq_set_data_info(nLoop);
string strTableName = RT_DIG_TBL;
string strTagName = stOptSetData.str_tag_name();
int nNewValue = stOptSetData.var_value().nvalue() ;
int nAddStatus = stOptSetData.u_add_status();
int nDelStatus = stOptSetData.u_del_status();
SDigPointAll stDigPoint;
string strKeyTagName = strTagName;
strKeyTagName.resize(64);
//得到指定标签点的实时库记录
//=============================================================================================================
nRetCode = m_ptrRdbTableMng->getRecordAllColumnByKey(RT_DIG_TBL,strKeyTagName.c_str(),stDigPoint);
if (nRetCode <=0 )
{
LOGERROR("nRetCode = %d, tag_name = %s, getRecordAllColumnByKey error!",nRetCode, strKeyTagName.c_str());
continue;
}
//状态字处理,如果计算点过来的值没有增加删除状态,保证计算点状态有效
//=============================================================================================================
if(nAddStatus == 0 && nDelStatus == 0)
{
nDelStatus = (1<<m_nMenuStateDiInvalid); //删除无效状态
}
nRetCode = m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, nNewStatus,stDigPoint.status,nAddStatus,nDelStatus,STATUS_ORI_OPT);
if(nRetCode < 0)
{
LOGWARN( "processOperate:getNewStatus Error, strTagName = %s error!",stDigPoint.tag_name);
continue;
}
if(stDigPoint.status == nNewStatus && nNewValue == stDigPoint.value)
{
LOGDEBUG( "processOperate:status=NewStatus && nNewValue=value ,strTagName = %s!",stDigPoint.tag_name);
m_ptrDataPublish->addOneChangeInt(stDigPoint.location_id,stDigPoint.sub_system,strTableName, strTagName, "value", nNewValue, nNewStatus);
continue;
}
//初始化缓存队列字段信息
STagStatusValue stTagInfo ;
stTagInfo.strTagName = stDigPoint.tag_name;
stTagInfo.lTimes = stDigPoint.last_update_time;
stTagInfo.unValue.nValue = stDigPoint.value ;
stTagInfo.nStatus = stDigPoint.status;
UTagValue unSetValue;
unSetValue.nValue = nNewValue ;
LOGDEBUG( "processOperate:strTagName = %s ,NewStatus=%d nNewValue=%d !",stDigPoint.tag_name,nNewStatus,nNewValue);
//< 计算服务计算点处理,fbd_server 如果:测点已经人工置数|静止刷新->更新缓冲再直接返回
//=============================================================================================================
if(OPT_TYPE_CAL_SET == nOperateType)
{
if((stDigPoint.point_property & (1<<0)) == 0) //采集点
{
LOGDEBUG("processOperate::操作错误,对采集点[%s]人工置数,请检查配置!",stDigPoint.tag_name);
return 1;
}
nRetCode = checkTagStatus(stDigPoint.tag_name,stDigPoint.status,
unSetValue,stDigPoint.last_update_time, POINT_TYPE_DIG);//禁止刷新 保存旧的值
if (nRetCode == false)
{
LOGDEBUG("processOperate::checkTagStatus() tag_name = %s, newValue = %d, status = %d NewStatus = %d ! ",
stDigPoint.tag_name, nNewValue, stDigPoint.status, nNewStatus);
return 1;
}
}
//如果禁止刷新,保存标签数据 ;否则,还原标签数据
//=============================================================================================================
else if(nOperateType == OPERATE_TYPE)
{
if(procTagOperate(nAddStatus,nDelStatus,unSetValue,stTagInfo,POINT_TYPE_DIG)== false) //针对人工置数等OPT操作
{
LOGERROR("CAnaProcess::procOneAnaChange,procTagOperate Error tagname=%s ",stDigPoint.tag_name);
}
nNewValue = stTagInfo.unValue.nValue ; //取消操作,值来自保存的队列,添加状态为人工置数<-设置值unSetValue
}
//处理人工置数/取消人工置数/取消禁止刷新等,生成报警结构体,调用函数产生报警
//=============================================================================================================
if(processSetData(stDigPoint, nNewValue, nNewStatus,bInit) <0)
{
LOGWARN( "ProcessSetData, strTableName = %s, strTagName = %s, nNewValue = %d, nNewValue = %d, error!",
RT_DIG_TBL, strTagName.c_str(), nNewStatus,nNewStatus);
continue;
}
m_ptrDataPublish->addOneChangeInt(stDigPoint.location_id,stDigPoint.sub_system,strTableName, strTagName, "value", nNewValue, nNewStatus);
}
return 1;
}
/**
@brief
@param bool &bIsTxOff OUT
bool &bIsInvalid OUT
const SDigPointAll &stDigPoint: INT DI RTB结构
@return 1: <0
@retval
*/
int CDigProcess::getDigSpelStatus(bool &bIsTxOff, bool &bIsInvalid,const SDigPointAll &stDigPoint)
{
bIsTxOff = false;
bIsInvalid = false;
if ( (stDigPoint.value_num < 1) || (stDigPoint.value_num > MAX_DI_BIT_NUM))
{
LOGINFO( "nValueNum = %d is invalid (tag_name = %s)", stDigPoint.value_num,
stDigPoint.tag_name);
return -1;
}
for (int j = 0; j != stDigPoint.value_num; ++j)
{
if ((bIsTxOff) && (bIsInvalid) )
{
break;
}
if (j == 0)
{
if (stDigPoint.status1 & (1 << m_nMenuStateDiGkOff))
{
bIsTxOff = true;
}
if (stDigPoint.status1 & (1 << m_nMenuStateDiInvalid))
{
bIsInvalid = true;
}
}
else if (j == 1 )
{
if (stDigPoint.status2 & (1 << m_nMenuStateDiGkOff))
{
bIsTxOff = true;
}
if (stDigPoint.status2 & (1 << m_nMenuStateDiInvalid))
{
bIsInvalid = true;
}
}
else if (j == 2)
{
if (stDigPoint.status3 & (1 << m_nMenuStateDiGkOff))
{
bIsTxOff = true;
}
if (stDigPoint.status3 & (1 << m_nMenuStateDiInvalid))
{
bIsInvalid = true;
}
}
else if (j == 3)
{
if (stDigPoint.status4 & (1 << m_nMenuStateDiGkOff))
{
bIsTxOff = true;
}
if (stDigPoint.status4 & (1 << m_nMenuStateDiInvalid))
{
bIsInvalid = true;
}
}
else if (j == 4)
{
if (stDigPoint.status5 & (1 << m_nMenuStateDiGkOff))
{
bIsTxOff = true;
}
if (stDigPoint.status5 & (1 << m_nMenuStateDiInvalid))
{
bIsInvalid = true;
}
}
}
return 1;
}
/**
@brief Di量变化处理/
@param nTypeFlag: DI_UPDATE_TYPE: ; DI_CHANGE_TYPE:
bIsActualChg:0
1
@return 1: 0
@retval
*/
int CDigProcess::processValueChange(const SDigPointAll &stDigPointAll,SDigAlarmPara &stDigAlmPara,
int nChgValue,int nNewStatus,int64 lUpdateTime,bool bIsActualChg)
{
bool bAlarmDisable = checkAlarmDisable(nNewStatus,POINT_TYPE_DIG,false) ;
//置数、禁止刷新时不写事件,不写实时值
//====================================================================================================
UTagValue utValue ;
utValue.nValue = nChgValue;
if(false == checkTagStatus(stDigPointAll.tag_name,stDigPointAll.status,
utValue,stDigPointAll.last_update_time, POINT_TYPE_DIG))//禁止刷新 保存旧的值
{
LOGDEBUG("测点[%s],状态[%d] 人工置数/禁止刷新!", stDigPointAll.tag_name, stDigPointAll.status);
return 0;
}
LOGDEBUG("ProcessValueChange tag_name[%s], is_send_alarm=%d, bIsNeedAlarm=%d,Status=%d bIsActualChg=%d",
stDigPointAll.tag_name,stDigAlmPara.is_send_alarm,bAlarmDisable,nNewStatus,bIsActualChg);
if ( stDigAlmPara.is_send_alarm && bIsActualChg && (bAlarmDisable == false))
{
if (stDigAlmPara.is_alm_not_ack)
{
m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, nNewStatus, nNewStatus, 1 << m_nMenuStateDiAlmNotAck, 0,
STATUS_ORI_RECV); //add m_nMenuStateDiAlmNotAck
}
else
{
m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, nNewStatus, nNewStatus, 0, 1 << m_nMenuStateDiAlmNotAck,
STATUS_ORI_RECV); //del m_nMenuStateDiAlmNotAck
}
if(stDigPointAll.value != nChgValue) //值发送变化,产生告警
{
addOneDigAlarm(ALM_TYPE_DI_CHANGE,stDigPointAll,stDigAlmPara,lUpdateTime) ;
}
}
//LOGDEBUG("ProcessValueChange:updateRecordMultiValueByKey tag_name = %s, value = %d, nNewStatus = %d ",
// stDigPointAll.tag_name, nResultValue,nNewStatus);
if(false == updateDigValStatus(stDigPointAll.tag_name, nChgValue,nNewStatus,lUpdateTime))
{
LOGERROR("ProcessValueChange,tag_name = %s,updateDigValStatus error!",stDigPointAll.tag_name);
}
//发生状态变位实时值到消息总线HMI...
m_ptrDataPublish->addOneChangeInt(stDigPointAll.location_id,stDigPointAll.sub_system,\
RT_DIG_TBL, stDigPointAll.tag_name, "value", nChgValue,nNewStatus);
return 1;
}
/**
@brief map
@param int nAlarmStyle :
SDiAlarm *stDiAlarmStru:DI报警信息结构
@return
@retval
*/
void CDigProcess::processAlarmTime(int nAlarmStyle, SDiAlarm *stDiAlarm) //处理报警计时
{
map <string, SDiAlarm>::iterator pos;
string strTagName = stDiAlarm->tag_name;
if (nAlarmStyle == m_mapAlarmStyle["MENU_RTNALARM_AND_EVENT"])//报警返回删除
{
pos = m_mapDiAlarmTimeBuf.find(strTagName);
if (pos != m_mapDiAlarmTimeBuf.end())//MAP找到该点
{
m_mapDiAlarmTimeBuf.erase(pos);
}
}
else if (nAlarmStyle == m_mapAlarmStyle["MENU_ALARM_AND_EVENT"])//新报警增加到map
{
m_mapDiAlarmTimeBuf[strTagName] = *stDiAlarm;
}
else if (nAlarmStyle == m_mapAlarmStyle["MENU_EVENT_ONLY"])
{
LOGINFO("tag_name = %s, if_alarm_time = 1,nAlarmStyle = MENU_EVENT_ONLY",
stDiAlarm->tag_name);
}
else if (nAlarmStyle == m_mapAlarmStyle["MENU_DO_NOTHING"])
{
LOGINFO( "tag_name = %s, if_alarm_time = 1,nAlarmStyle = MENU_DO_NOTHING",
stDiAlarm->tag_name);
}
LOGINFO("ProcessAlarmTime m_mapDiAlarmTimeBuf.size() = %d",(int)m_mapDiAlarmTimeBuf.size());
return;
}
/**
@brief m_mapDiAlarmTimeBuf DI变位发送实时数据
@param
@return
@retval
*/
void CDigProcess::checkAlarmTimeBuf()
{
int nRetCode;
LOGINFO("CheckAlarmTimeBuf m_mapDiAlarmTimeBuf.size() = %d",(int)m_mapDiAlarmTimeBuf.size());
int64 ulCurMsec = (int64)getMonotonicMsec();
map <string, SDiAlarm>::iterator pos;
for (pos = m_mapDiAlarmTimeBuf.begin(); pos != m_mapDiAlarmTimeBuf.end(); )
{
if ((ulCurMsec - pos->second.occur_time) > pos->second.alarm_time*1000)
{
SDigPointAll stDigPointAll;
//AddOneDigAlarm((SDiAlarm *)(&(pos->second)), "CheckAlarmTimeBuf", ALARM_TIME_FLAG);
//RDB找不到这个点
nRetCode = m_ptrRdbTableMng->getRecordAllColumnByKey(RT_DIG_TBL,pos->second.tag_name,stDigPointAll);
if (nRetCode <=0 )
{
LOGERROR("nRetCode = %d, tag_name = %s, Read error!", nRetCode,
pos->second.tag_name);
m_mapDiAlarmTimeBuf.erase(pos++);
continue;
}
//实际上只需要修改status
if (pos->second.is_alm_not_ack)
{
m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, stDigPointAll.status, stDigPointAll.status,
1 << m_nMenuStateDiAlmNotAck, 0, STATUS_ORI_RECV); //add m_nMenuStateDiAlmNotAck
}
else
{
m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, stDigPointAll.status, stDigPointAll.status,
0, 1 << m_nMenuStateDiAlmNotAck, STATUS_ORI_RECV); //del m_nMenuStateDiAlmNotAck
}
nRetCode = m_ptrRdbTableMng->updateRecordOneValueByKey(RT_DIG_TBL, pos->second.tag_name,"status",stDigPointAll.status);
if (nRetCode == false)
{
LOGERROR("nRetCode = %d, tag_name = %s, TableModifyByKey error!", nRetCode,
pos->second.tag_name);
m_mapDiAlarmTimeBuf.erase(pos++);
continue;
}
m_ptrDataPublish->addOneChangeInt(stDigPointAll.location_id,stDigPointAll.sub_system, \
RT_DIG_TBL, pos->second.tag_name, "value",\
stDigPointAll.value, stDigPointAll.status);
m_mapDiAlarmTimeBuf.erase(pos++);
}
else
{
++pos;
}
}
return;
}
/**
@brief m_mapDiAlarmFreqBuf>DI报警信息
@param int nAlarmStyle:
SDiAlarm *stDiAlarmStru:
bool &bIsCreateAlarm:OUT
@return
@retval
*/
void CDigProcess::processAlarmFreq(int nAlarmStyle, SDiAlarm *stDiAlarmStru, bool &bIsCreateAlarm)
{
bIsCreateAlarm = false;
map <string, SAlarmFreq>::iterator pos;
SAlarmFreq stFreqInfo;
string strTagName = stDiAlarmStru->tag_name;
if (nAlarmStyle == m_mapAlarmStyle["MENU_ALARM_AND_EVENT"]) //报警和事件
{
pos = m_mapDiAlarmFreqBuf.find(strTagName);
if (pos != m_mapDiAlarmFreqBuf.end()) //队列存在该测定报警信息
{
stFreqInfo = pos->second ;
++stFreqInfo.now_alarm_freq;
LOGINFO("stFreqInfo.now_alarm_freq = %d, stDiAlarmStru->alarm_freq = %d",\
stFreqInfo.now_alarm_freq, stDiAlarmStru->alarm_freq);
if (stFreqInfo.now_alarm_freq >= stDiAlarmStru->alarm_freq )//报警次数>报警设定计次
{
//AddOneDigAlarm(stDiAlarmStru, "ProcessAlarmFreq", ALARM_FREQ_FLAG);
bIsCreateAlarm = true;
m_mapDiAlarmFreqBuf.erase(pos);
}
else
{
m_mapDiAlarmFreqBuf[strTagName] = stFreqInfo;
}
}
else
{
SAlarmFreq stFreqInfo;
stFreqInfo.now_alarm_freq = 1;
stFreqInfo.alarm_stru = *stDiAlarmStru;
m_mapDiAlarmFreqBuf[strTagName] = stFreqInfo;
}
}
else if (nAlarmStyle == m_mapAlarmStyle["MENU_EVENT_ONLY"])
{
LOGINFO("tag_name = %s, if_alarm_freq = 1,nAlarmStyle = MENU_EVENT_ONLY",strTagName.c_str());
}
else if (nAlarmStyle == m_mapAlarmStyle["MENU_DO_NOTHING"])
{
LOGINFO("tag_name = %s, if_alarm_freq = 1,nAlarmStyle = MENU_EVENT_ONLY",strTagName.c_str());
}
LOGINFO("ProcessAlarmFreq m_mapDiAlarmFreqBuf.size() = %d",(int)m_mapDiAlarmFreqBuf.size());
return;
}
/**
@brief
@param
@return
@retval
*/
void CDigProcess::checkAlarmFreqBuf()
{
LOGINFO("CheckAlarmFreqBuf m_mapDiAlarmFreqBuf.size() = %d", (int)m_mapDiAlarmFreqBuf.size());
int64 ulCurMsec = (int64)getMonotonicMsec() ;
map <string, SAlarmFreq>::iterator pos;
for (pos = m_mapDiAlarmFreqBuf.begin(); pos != m_mapDiAlarmFreqBuf.end(); )
{
if((ulCurMsec - pos->second.alarm_stru.occur_time) > (pos->second.alarm_stru.is_alarm_freq*1000) )
{
m_mapDiAlarmFreqBuf.erase(pos++);
}
else
{
++pos;
}
}
}
/**
@brief DI报警延时
@param SDiAlarm *pDiAlarm IN
@return DI值
@retval
*/
void CDigProcess::processAlarmDelay(SDiAlarm *pDiAlarm)
{
string strTagName = pDiAlarm->tag_name;
m_mapDiAlarmDelayBuf[strTagName] = *pDiAlarm;
LOGINFO("ProcessAlarmDelay m_mapDiAlarmDelayBuf.size() = %d",(int)m_mapDiAlarmDelayBuf.size());
return;
}
/**
@brief DI报警延时
@param SDiAlarm *pDiAlarm IN
@return DI值
@retval
*/
void CDigProcess::checkAlarmDelayBuf()
{
int nRetCode;
map <string, SDiAlarm>::iterator pos;
int64 ulCurMsec = getMonotonicMsec();
//LOGDEBUG("CheckAlarmDelayBuf m_mapDiAlarmDelayBuf.size() = %d", m_mapDiAlarmDelayBuf.size());
for (pos = m_mapDiAlarmDelayBuf.begin(); pos != m_mapDiAlarmDelayBuf.end(); )
{
if((ulCurMsec - pos->second.occur_time) > pos->second.alarm_delay_time*1000 )
{
SDigPointAll stDigPointAll;
//AddOneDigAlarm((SDiAlarm *)(&(pos->second)), "CheckAlarmDelayBuf");
nRetCode = m_ptrRdbTableMng->getRecordAllColumnByKey(RT_DIG_TBL, pos->second.tag_name, stDigPointAll);
if (nRetCode <=0 )
{
LOGINFO("nRetCode = %d, tag_name = %s, TableGetByKey error!", nRetCode,
pos->second.tag_name);
m_mapDiAlarmDelayBuf.erase(pos++);
continue;
}
//只需要修改status
if (pos->second.is_alm_not_ack)
{
m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, stDigPointAll.status, stDigPointAll.status,
1 << m_nMenuStateDiAlmNotAck, 0, STATUS_ORI_RECV); //add m_nMenuStateDiAlmNotAck
}
else
{
m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, stDigPointAll.status, stDigPointAll.status,
0, 1 << m_nMenuStateDiAlmNotAck, STATUS_ORI_RECV); //del m_nMenuStateDiAlmNotAck
}
nRetCode = m_ptrRdbTableMng->updateRecordOneValueByKey(RT_DIG_TBL, pos->second.tag_name,"status", stDigPointAll.status);
if (nRetCode == false)
{
LOGERROR("nRetCode = %d, tag_name = %s, updateRecordOneValueByKey error!", nRetCode, pos->second.tag_name);
m_mapDiAlarmDelayBuf.erase(pos++);
continue;
}
m_ptrDataPublish->addOneChangeInt(stDigPointAll.location_id,stDigPointAll.sub_system, \
RT_DIG_TBL, pos->second.tag_name, "value",
stDigPointAll.value, stDigPointAll.status);
m_mapDiAlarmDelayBuf.erase(pos++);
}
else
{
++pos;
}
}
return;
}
/**
@brief RTU信息
@param
@return
@retval
*/
int CDigProcess::getRtuTag(const int nAlmGrpId, vector<string> &vecRtuTagName, const int nDomainId /*=-1*/)
{
vecRtuTagName.clear();
vector<SFesGroupDevSelect> vecFesGroupDevSelect;
std::vector<std::string> strSelColumn ={"tag_name","nDomainId"} ;
int nRetCode = m_ptrRdbTableMng->selectSelColumnOneCondition("fes_group_dev",strSelColumn,vecFesGroupDevSelect,"alarm_group_id",nAlmGrpId);
if (nRetCode == false)
{
LOGERROR("GetRtuTag, ret = %d, alarm_group_id = %d, table_name = fes_group_dev, m_Rdbmng.ConGet error!",
nRetCode, nAlmGrpId);
return -1;
}
for (vector<SFesGroupDevSelect>::size_type i = 0; i != vecFesGroupDevSelect.size(); ++i)
{
if (nDomainId != -1 && nDomainId != vecFesGroupDevSelect[i].domain_id)
{
continue;
}
vector<string> vecFesRtuDevSelect;
nRetCode = m_ptrRdbTableMng->selectOneColumnOneCondition("fes_rtu_dev","tag_name",vecFesRtuDevSelect ,\
"group_tag",vecFesGroupDevSelect[i].tag_name);
if (nRetCode == false)
{
LOGERROR("GetRtuTag, ret = %d, group_tag = %s, table_name = fes_rtu_dev, m_Rdbmng.ConGet error!",
nRetCode, vecFesGroupDevSelect[i].tag_name);
continue;
}
for (vector<string>::size_type j = 0; j != vecFesRtuDevSelect.size(); ++j)
{
vecRtuTagName.push_back(vecFesRtuDevSelect[j]);
}
}
if (vecRtuTagName.size() < 1)
{
LOGWARN("GetRtuTag, record_app = %d, nAlmGrpId = %d, can't find any rtu!", m_stRunAppInfo.nAppId, nAlmGrpId);
}
return 0;
}