[ref]同步

This commit is contained in:
shi_jq 2025-03-12 18:14:45 +08:00
parent 174de94f65
commit 7b819bc781
93 changed files with 7986 additions and 469 deletions

View File

@ -378,11 +378,15 @@ void CAppMsgProcThread::handleOneMbMsg()
if (iot_idl::AS_DO_NOTHING == objAlmInfoSrc.alm_style()) if (iot_idl::AS_DO_NOTHING == objAlmInfoSrc.alm_style())
{ {
//< 不处理 //< 不处理
if ( objAlmInfoSrc.has_key_id_tag() && !( objAlmInfoSrc.key_id_tag().empty()))
LOGINFO( "alm_style值为AS_DO_NOTHING不做任何处理key_id_tag%s", objAlmInfoSrc.key_id_tag().c_str());
else
{
std::string strPrint; std::string strPrint;
google::protobuf::TextFormat::PrintToString( objAlmInfoSrc, &strPrint ); google::protobuf::TextFormat::PrintToString( objAlmInfoSrc, &strPrint );
LOGINFO( "alm_style值为AS_DO_NOTHING不做任何处理消息内容\n%s", strPrint.c_str()); LOGINFO( "alm_style值为AS_DO_NOTHING不做任何处理消息内容\n%s", strPrint.c_str());
} }
}
else else
{ {
SAlmInfoPtr ptrAlmInfoDst = boost::make_shared<iot_idl::SAlmInfoToAlmClt>(); SAlmInfoPtr ptrAlmInfoDst = boost::make_shared<iot_idl::SAlmInfoToAlmClt>();

View File

@ -95,7 +95,7 @@ int CAccProcess::procAccChange(const SFesChangePiPkg &stChgAccPkg)
stChangeAccData.strTableName = stChgAccPkg.stpidata(nLoop).strapptablename(); //表名 stChangeAccData.strTableName = stChgAccPkg.stpidata(nLoop).strapptablename(); //表名
stChangeAccData.strPointName = stChgAccPkg.stpidata(nLoop).strapptagname(); //点名 stChangeAccData.strPointName = stChgAccPkg.stpidata(nLoop).strapptagname(); //点名
stChangeAccData.strColumnName = stChgAccPkg.stpidata(nLoop).strappcolumnname(); //列名 stChangeAccData.strColumnName = stChgAccPkg.stpidata(nLoop).strappcolumnname(); //列名
stChangeAccData.dValue = stChgAccPkg.stpidata(nLoop).nvalue(); stChangeAccData.dValue = stChgAccPkg.stpidata(nLoop).dvalue();
stChangeAccData.lTime = stChgAccPkg.stpidata(nLoop).ultime(); stChangeAccData.lTime = stChgAccPkg.stpidata(nLoop).ultime();
nTmpStatus = 0xffff & stChgAccPkg.stpidata(nLoop).ustatus(); nTmpStatus = 0xffff & stChgAccPkg.stpidata(nLoop).ustatus();
@ -182,7 +182,6 @@ int CAccProcess::procOneAccChange(SChangeAccData &stChangeAccData,SAccNewValueSt
m_stChangeAccInfo.dValue = stAccOldValueStatus.oldvalue; m_stChangeAccInfo.dValue = stAccOldValueStatus.oldvalue;
m_stChangeAccInfo.uStatus = stAccOldValueStatus.oldstatus; m_stChangeAccInfo.uStatus = stAccOldValueStatus.oldstatus;
stChangeAccData.nLocation = stAccPoint.location_id; stChangeAccData.nLocation = stAccPoint.location_id;
stChangeAccData.nSubSystem = stAccPoint.sub_system; stChangeAccData.nSubSystem = stAccPoint.sub_system;
@ -356,7 +355,7 @@ int CAccProcess::procAccUpdate(const SFesUpdatePiPkg &stUpAccPkg)
stChangeAccData.strTableName = stUpAccPkg.stpidata(nLoop).strapptablename(); //表名 stChangeAccData.strTableName = stUpAccPkg.stpidata(nLoop).strapptablename(); //表名
stChangeAccData.strPointName = stUpAccPkg.stpidata(nLoop).strapptagname(); //点名 stChangeAccData.strPointName = stUpAccPkg.stpidata(nLoop).strapptagname(); //点名
stChangeAccData.strColumnName = stUpAccPkg.stpidata(nLoop).strappcolumnname(); //列名 stChangeAccData.strColumnName = stUpAccPkg.stpidata(nLoop).strappcolumnname(); //列名
stChangeAccData.dValue = stUpAccPkg.stpidata(nLoop).nvalue(); stChangeAccData.dValue = stUpAccPkg.stpidata(nLoop).dvalue();
stChangeAccData.lTime = m_lCurTime; stChangeAccData.lTime = m_lCurTime;
nTmpStatus = 0xffff & stUpAccPkg.stpidata(nLoop).ustatus(); nTmpStatus = 0xffff & stUpAccPkg.stpidata(nLoop).ustatus();
m_ptrDataProcApi->changeAnaStatusRawToRipe(stChangeAccData.uStatus, nTmpStatus); m_ptrDataProcApi->changeAnaStatusRawToRipe(stChangeAccData.uStatus, nTmpStatus);
@ -471,7 +470,7 @@ int CAccProcess::writeAccRdb(const string& strPointName ,
m_stChangeAccInfo.dValue = stAccOldValueStatus.oldvalue; m_stChangeAccInfo.dValue = stAccOldValueStatus.oldvalue;
m_stChangeAccInfo.uStatus = stAccNewValueStatus.newstatus; m_stChangeAccInfo.uStatus = stAccNewValueStatus.newstatus;
m_stChangeAccInfo.bIfLimitChange = false; m_stChangeAccInfo.bIfLimitChange = false;
//LOGDEBUG("writeAccRtdb MENU_STATE_AI_GK_OFF!,tag_name =%s,value =%.2f,status =%d",\ LOGDEBUG("writeAccRtdb MENU_STATE_AI_GK_OFF!,tag_name =%s,value =%.2f,status =%d",
m_stChangeAccInfo.strPointName.c_str(),m_stChangeAccInfo.dValue, m_stChangeAccInfo.uStatus); m_stChangeAccInfo.strPointName.c_str(),m_stChangeAccInfo.dValue, m_stChangeAccInfo.uStatus);
return 2; return 2;
@ -495,6 +494,7 @@ int CAccProcess::writeAccRdb(const string& strPointName ,
return 1; return 1;
} }
/** /**
@brief @brief
@param stOneAiLimit: @param stOneAiLimit:

View File

@ -81,7 +81,6 @@ struct SAccMapToFes
char description[128] ; char description[128] ;
}; };
struct SAccOldValueStatus struct SAccOldValueStatus
{ {
double oldvalue; double oldvalue;

View File

@ -190,7 +190,7 @@ int CAccWorkThread::processOptMessage()
{ {
SOptSetDataPkg &objOptCalSetPkg = *it ; SOptSetDataPkg &objOptCalSetPkg = *it ;
m_ptrAccProcess->processOperate(objOptCalSetPkg,OPT_TYPE_CAL_SET); m_ptrAccProcess->processOperate(objOptCalSetPkg,OPT_TYPE_CAL_SET);
LOGINFO("processOptMessage: 处理计算点操作 num=%d .",objOptCalSetPkg.seq_set_data_info_size()); LOGDEBUG("processOptMessage: 处理计算点操作 num=%d .",objOptCalSetPkg.seq_set_data_info_size());
} }
} }

View File

@ -551,7 +551,7 @@ int CAnaProcess:: writeAnaRtdb(const string &strPointName, SOldValueStatus &stOl
m_stChangeAiInfo.dValue = stOldValueStatus.oldvalue; m_stChangeAiInfo.dValue = stOldValueStatus.oldvalue;
m_stChangeAiInfo.uStatus = stNewValueStatus.newstatus; m_stChangeAiInfo.uStatus = stNewValueStatus.newstatus;
m_stChangeAiInfo.bIfLimitChange = false; m_stChangeAiInfo.bIfLimitChange = false;
LOGINFO("CAnaProcess::writeAnaRtdb MENU_STATE_AI_GK_OFF!,ifprocess =%d,strPointName =%s,value =%f,status =%d,iflimitchange =%d", LOGDEBUG("CAnaProcess::writeAnaRtdb MENU_STATE_AI_GK_OFF!,ifprocess =%d,strPointName =%s,value =%f,status =%d,iflimitchange =%d",
m_stChangeAiInfo.bIfProcess, m_stChangeAiInfo.strPointName.c_str(), m_stChangeAiInfo.dValue, m_stChangeAiInfo.uStatus, m_stChangeAiInfo.bIfProcess, m_stChangeAiInfo.strPointName.c_str(), m_stChangeAiInfo.dValue, m_stChangeAiInfo.uStatus,
m_stChangeAiInfo.bIfLimitChange); m_stChangeAiInfo.bIfLimitChange);
return 2; return 2;
@ -756,6 +756,7 @@ int CAnaProcess::writeRdbAndSendMsg(const SChangeAiData &stOneAiLimit, int /*sty
//<< 实时值写入数据库中同时发布到 HMI //<< 实时值写入数据库中同时发布到 HMI
//============================================================================================ //============================================================================================
strKeyTagName.resize(64); strKeyTagName.resize(64);
nRetCode = m_ptrRdbTableMng->updateRecordTwoValueByKey(stOneAiLimit.strTableName,strKeyTagName.c_str(),\ nRetCode = m_ptrRdbTableMng->updateRecordTwoValueByKey(stOneAiLimit.strTableName,strKeyTagName.c_str(),\
"status",m_stChangeAiInfo.uStatus, "value", m_stChangeAiInfo.dValue); "status",m_stChangeAiInfo.uStatus, "value", m_stChangeAiInfo.dValue);
if (nRetCode == false) if (nRetCode == false)
@ -766,7 +767,7 @@ int CAnaProcess::writeRdbAndSendMsg(const SChangeAiData &stOneAiLimit, int /*sty
} }
m_ptrDataPublish->addOneChangeFloat( stOneAiLimit.nLocation,stOneAiLimit.nSubSystem,stOneAiLimit.strTableName,stOneAiLimit.strPointName,\ m_ptrDataPublish->addOneChangeFloat( stOneAiLimit.nLocation,stOneAiLimit.nSubSystem,stOneAiLimit.strTableName,stOneAiLimit.strPointName,\
stOneAiLimit.strColumnName, m_stChangeAiInfo.dValue, m_stChangeAiInfo.uStatus); stOneAiLimit.strColumnName, static_cast<float>(m_stChangeAiInfo.dValue), m_stChangeAiInfo.uStatus);
//LOGDEBUG( "CAnaProcess::writeRdbAndSendMsg,not optlock" ); //LOGDEBUG( "CAnaProcess::writeRdbAndSendMsg,not optlock" );

View File

@ -219,7 +219,7 @@ void CSrvDataPublish::addOneChangeLong(const int nLocationId,const int nSubSyste
const string strTagName, const string strColumnName, const string strTagName, const string strColumnName,
const int64 lValue, const int nStatus ) const int64 lValue, const int nStatus )
{ {
m_ptrSampleApi->addAccChange(strTableName,strTagName,strColumnName,nStatus,lValue); m_ptrSampleApi->addAccChange(strTableName,strTagName,strColumnName,nStatus,static_cast<double>(lValue));
SPiRealTimeData *stOneRealData = m_stChangeMsg.add_stpirtd(); SPiRealTimeData *stOneRealData = m_stChangeMsg.add_stpirtd();

View File

@ -8,6 +8,7 @@
#include "pub_utility_api/TimeUtil.h" #include "pub_utility_api/TimeUtil.h"
#include "common/Common.h" #include "common/Common.h"
#include "pub_utility_api/CommonConfigParse.h" #include "pub_utility_api/CommonConfigParse.h"
#include <bitset>
using namespace std; using namespace std;
using namespace iot_service; using namespace iot_service;
@ -23,9 +24,7 @@ CDigProcess::CDigProcess(iot_public::SRunAppInfo stRunAppInfo,
m_ptrDataProcApi = ptrDataProcApi; m_ptrDataProcApi = ptrDataProcApi;
m_ptrDataPublish = ptrDataPublish; m_ptrDataPublish = ptrDataPublish;
m_nChgAlarmCount = 0 ;
m_nSoeAlarmCount = 0 ;
m_nChangeCount = 0 ;
} }
bool CDigProcess::initialize() bool CDigProcess::initialize()
@ -351,11 +350,6 @@ bool CDigProcess::isUpdatedByValidData(const int nLastStatus,const SUpdateDiInfo
map <string, int>::iterator pos; map <string, int>::iterator pos;
string strTagName = stUpdateDiInfo.tag_name; string strTagName = stUpdateDiInfo.tag_name;
if( (nLastStatus & (1 << m_nMenuStateDiInvalid)) ) //上次无效=4未初始化
{
return false;
}
int64 lCurTimes = getUTCTimeSec(); int64 lCurTimes = getUTCTimeSec();
if((lCurTimes - m_nStartupTimes) <= m_nStartAlarmDelay) return false; //大于启动延时如果全数据有变化才会产生告警用于FES 启动比较慢的情况) if((lCurTimes - m_nStartupTimes) <= m_nStartAlarmDelay) return false; //大于启动延时如果全数据有变化才会产生告警用于FES 启动比较慢的情况)
@ -364,8 +358,8 @@ bool CDigProcess::isUpdatedByValidData(const int nLastStatus,const SUpdateDiInfo
if (pos == m_mapUpdatePackRecord.end()) //没找到 if (pos == m_mapUpdatePackRecord.end()) //没找到
{ {
//实时库点状态不是工况退出且全数据状态不是工况退出 //实时库点状态不是工况退出且全数据状态不是工况退出
if ( !(nLastStatus & (1 << m_nMenuStateDiInvalid)) //上次状态没有异常 if ( !(nLastStatus & (1 << m_nMenuStateDiGkOff)) //
&& !(stUpdateDiInfo.status & (1 << m_nMenuStateDiInvalid )) ) //当前状态没有异常 && !(stUpdateDiInfo.status & (1 << m_nMenuStateDiGkOff)) )
{ {
m_mapUpdatePackRecord[strTagName] = 0; m_mapUpdatePackRecord[strTagName] = 0;
} }
@ -447,7 +441,7 @@ int CDigProcess::processDiUpdate(const SFesUpdateDiPkg &stUpdateDiPkg)
//判断是否本进程重启后在本包全数据之前是否点表中的值已被全数据更新; //判断是否本进程重启后在本包全数据之前是否点表中的值已被全数据更新;
//前提:工况退出会出现在本包中所有记录中 //前提:工况退出会出现在本包中所有记录中
//============================================================================================ //============================================================================================
//if (nLoop == 0) //用第一个记录代表本包全数据 if (nLoop == 0) //用第一个记录代表本包全数据
{ {
bUpdatedByValidDataFlag = isUpdatedByValidData(stDigPointAll.status,stUpdateDiInfo); bUpdatedByValidDataFlag = isUpdatedByValidData(stDigPointAll.status,stUpdateDiInfo);
} }
@ -495,21 +489,20 @@ int CDigProcess::processDiUpdate(const SFesUpdateDiPkg &stUpdateDiPkg)
@return @return
@retval @retval
*/ */
void CDigProcess::setAbnormalStatus(const SDigPointAll & stDigPoint,const SDigAlarmPara &stDigAlmPara,int &nNewStatus) void CDigProcess::setAbnormalStatus(const SDigPointAll &/*stDigPoint*/,const SDigAlarmPara &stDigAlmPara,int &nNewStatus)
{ {
int nOldStatus = nNewStatus; int nOldStatus = nNewStatus;
int nLastStatus = stDigPoint.status;
//新值=未复归,老状态已经复归 ==>状态字增加未复归 //新值=未复归,老状态已经复归 ==>状态字增加未复归
if ( stDigAlmPara.is_abnormal && !(nLastStatus & (1 << m_nMenuStateDiAbnormal)) ) if ( stDigAlmPara.is_abnormal && !(nOldStatus & (1 << m_nMenuStateDiAbnormal)) )
{ {
m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, nNewStatus, nOldStatus,1 << m_nMenuStateDiAbnormal,0, m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, nNewStatus, nOldStatus,1 << m_nMenuStateDiAbnormal,0,
STATUS_ORI_RECV); //add DiAbnormal flag STATUS_ORI_RECV); //del DiAbnormal flag
} }
else if ( !stDigAlmPara.is_abnormal && (nLastStatus & (1 << m_nMenuStateDiAbnormal)) ) else if ( !stDigAlmPara.is_abnormal && (nOldStatus & (1 << m_nMenuStateDiAbnormal)) )
{ {
m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, nNewStatus, nOldStatus,0,1 << m_nMenuStateDiAbnormal, m_ptrDataProcApi->getNewStatus(TYPE_STATUS_DI, nNewStatus, nOldStatus,0,1 << m_nMenuStateDiAbnormal,
STATUS_ORI_RECV); //del DiAbnormal flag STATUS_ORI_RECV); //add DiAbnormal flag
} }
//LOGDEBUG("setAbnormalStatus 标签点[%s] 未复归=[%d],旧状态=[%d],新状态=[%d].",stDigPoint.tag_name, //LOGDEBUG("setAbnormalStatus 标签点[%s] 未复归=[%d],旧状态=[%d],新状态=[%d].",stDigPoint.tag_name,
@ -691,6 +684,27 @@ void CDigProcess::getStatusByStatusx(const SDigPointAll&stDigPointAll,int &nNewS
@retval @retval
*/ */
void CDigProcess::checkDiChgBuf() void CDigProcess::checkDiChgBuf()
{
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) )
{
processDiWithMultiVal(pos->first,pos->second); //到达防抖时间,从缓存中清理
m_mapDiChgBuf.erase(pos++);
}
else
{
++pos;
}
}
return;
}
void CDigProcess::checkDiChgBuf_bak()
{ {
int nRetCode; int nRetCode;
int nResultValue; int nResultValue;
@ -817,6 +831,26 @@ void CDigProcess::checkDiChgBuf()
@retval @retval
*/ */
void CDigProcess::checkDiSoeBuf() void CDigProcess::checkDiSoeBuf()
{
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))
{
processDiSOEWithMultiVal(pos->first,pos->second); //到达防抖时间,从缓存中清理
m_mapDiSoeBuf.erase(pos++);
}
else
{
++pos;
}
}
return;
}
void CDigProcess::checkDiSoeBuf_bak()
{ {
int nRetCode; int nRetCode;
map <string, SDiChange>::iterator pos; map <string, SDiChange>::iterator pos;
@ -972,8 +1006,7 @@ int CDigProcess::processDiChange(const SFesChangeDiPkg &stChangeDiPkg)
if(nChangeNum>0) if(nChangeNum>0)
{ {
m_nChangeCount = m_nChangeCount + nChangeNum; LOGDEBUG("ProcessDiChange:收到变化数据报文,数目[%d],时间[%" PRId64 "].",nChangeNum,(int64)stChangeDiPkg.stdidata(0).ultime());
LOGDEBUG("ProcessDiChange:收到变化数据报文,数目[%d],总计收到数目[%d],时间[%" PRId64 "].",nChangeNum,m_nChangeCount,(int64)stChangeDiPkg.stdidata(0).ultime());
} }
for (nLoop = 0; nLoop < nChangeNum; ++nLoop) for (nLoop = 0; nLoop < nChangeNum; ++nLoop)
@ -1158,6 +1191,8 @@ int CDigProcess::processOneDiChange(SChangeDiInfo &stChangeInfo)
if (stDigPointAll.input_delay_time > 0) //数据量报警延时处理 if (stDigPointAll.input_delay_time > 0) //数据量报警延时处理
{ {
addDigPartToBuff(m_mapDiChgBuf, strKeyIdTag, nDigPartIndex,stDigPointAll,stChangeInfo); addDigPartToBuff(m_mapDiChgBuf, strKeyIdTag, nDigPartIndex,stDigPointAll,stChangeInfo);
//如果多个分量都已经采集到,并且是合法值就会在处理的同时直接从缓存删除掉
testAndProcessDiWithMultiVal(stDigPointAll);
} }
} }
return 1; return 1;
@ -1320,14 +1355,6 @@ void CDigProcess::addOneDigAlarm(int nAlarmType,const SDigPointAll &stDigPointAl
if(nAlarmType == ALM_TYPE_DI_CHANGE) //遥信变位 if(nAlarmType == ALM_TYPE_DI_CHANGE) //遥信变位
{ {
nAlarmStatus = ALM_STAT_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);
} }
//初始化报警 故障值文本。。。。 //初始化报警 故障值文本。。。。
@ -1416,6 +1443,7 @@ int CDigProcess::processOneSoeEvent(SChangeDiInfo &stChangeInfo,const string &st
stDigPointAll.input_delay_time = 1 ; stDigPointAll.input_delay_time = 1 ;
addDigPartToBuff(m_mapDiSoeBuf,strKeyIdTag, nDigPartIndex,stDigPointAll,stChangeInfo); //SOE分量加入队列进行延时判断 addDigPartToBuff(m_mapDiSoeBuf,strKeyIdTag, nDigPartIndex,stDigPointAll,stChangeInfo); //SOE分量加入队列进行延时判断
testAndProcessDiSOEWithMultiVal(stDigPointAll);
/* /*
if (stDigPointAll.input_delay_time <= 0) // if (stDigPointAll.input_delay_time <= 0) //
{ {
@ -1523,6 +1551,7 @@ void CDigProcess::addDigPartToBuff(std::map <std::string,SDiChange> &mapDiChgBuf
itPos->second.di_bit_chg_array[nIndex - 1].status = stChangeInfo.nStatus; itPos->second.di_bit_chg_array[nIndex - 1].status = stChangeInfo.nStatus;
itPos->second.di_bit_chg_array[nIndex - 1].times = stChangeInfo.lTimes; itPos->second.di_bit_chg_array[nIndex - 1].times = stChangeInfo.lTimes;
} }
return; return;
} }
@ -1563,8 +1592,10 @@ void CDigProcess::initValuexStatusx(const SDigPointAll &stDigPoint,int *valuex,i
@return DI值 @return DI值
@retval @retval
*/ */
int CDigProcess::getValueByValuex(const int nValueNum,int *valuex,int */*statusx*/) int CDigProcess::getValueByValuex(const int nValueNum,int *valuex,int *statusx)
{ {
boost::ignore_unused_variable_warning(statusx);
int nLoop; int nLoop;
int nRetValue = 0; int nRetValue = 0;
@ -1678,8 +1709,7 @@ void CDigProcess::stripWhiteSpace(char *des_str, const char *source_str)
{ {
int nLoop; int nLoop;
int start_pos, end_pos; int start_pos, end_pos;
int source_str_len; int source_str_len = static_cast<int>(strlen(source_str));
source_str_len = strlen(source_str);
start_pos = 0; start_pos = 0;
for (nLoop = 0; nLoop < source_str_len; ++nLoop ) for (nLoop = 0; nLoop < source_str_len; ++nLoop )
@ -1853,16 +1883,18 @@ int CDigProcess::processOperate(const SOptSetDataPkg &stOptSetDataPkg,const int
{ {
if((stDigPoint.point_property & (1<<0)) == 0) //采集点 if((stDigPoint.point_property & (1<<0)) == 0) //采集点
{ {
LOGDEBUG("processOperate::操作错误,对采集点[%s]人工置数,请检查配置!",stDigPoint.tag_name); LOGWARN("processOperate::操作错误,对采集点[%s]人工置数,请检查配置!",stDigPoint.tag_name);
return 1; continue;
// return 1;
} }
nRetCode = checkTagStatus(stDigPoint.tag_name,stDigPoint.status, nRetCode = checkTagStatus(stDigPoint.tag_name,stDigPoint.status,
unSetValue,stDigPoint.last_update_time, POINT_TYPE_DIG);//禁止刷新 保存旧的值 unSetValue,stDigPoint.last_update_time, POINT_TYPE_DIG);//禁止刷新 保存旧的值
if (nRetCode == false) if (nRetCode == false)
{ {
LOGDEBUG("processOperate::checkTagStatus() tag_name = %s, newValue = %d, status = %d NewStatus = %d ! ", LOGWARN("processOperate::checkTagStatus() tag_name = %s, newValue = %d, status = %d NewStatus = %d ! ",
stDigPoint.tag_name, nNewValue, stDigPoint.status, nNewStatus); stDigPoint.tag_name, nNewValue, stDigPoint.status, nNewStatus);
return 1; //return 1;
continue;
} }
} }
@ -2367,3 +2399,226 @@ int CDigProcess::getRtuTag(const int nAlmGrpId, vector<string> &vecRtuTagName, c
return 0; return 0;
} }
bool CDigProcess::processDiWithMultiVal(const std::string &strTagName,const SDiChange &stDiChange)
{
int nNewStatus = 0;
SDigPointAll stDigPointAll;
string strDiTagName = strTagName;
strDiTagName.resize(64);
int nRetCode = m_ptrRdbTableMng->getRecordAllColumnByKey(RT_DIG_TBL,strDiTagName.c_str(), stDigPointAll);
if (nRetCode <=0 )
{
LOGERROR("CheckDiChgBuf::nRetCode = %d, tag_name = %s, 获取测点参数错误!", nRetCode, strDiTagName.c_str());
return true;//出错,可以删除缓存
}
int nValueNum = stDigPointAll.value_num;
if (nValueNum > MAX_DI_BIT_NUM || nValueNum <= 0 )
{
LOGWARN( "CheckDiChgBuf::nValueNum=%d > MAX_DI_BIT_NUM", nValueNum);
return true;//出错,可以删除缓存
}
int valuex[MAX_DI_BIT_NUM]={0};
int statusx[MAX_DI_BIT_NUM]={0};
initValuexStatusx(stDigPointAll,&valuex[0],&statusx[0]);//初始化分量值到valuexstatusx
//获得最新报警时间
int nLoop;
int64 nLastChgMescond = 0;
for (nLoop = 0 ; nLoop < nValueNum; nLoop++)
{
if (stDiChange.di_bit_chg_array[nLoop].use_flag == SHARE_BUF_USE)
{
valuex[nLoop] = stDiChange.di_bit_chg_array[nLoop].value;
statusx[nLoop] = stDiChange.di_bit_chg_array[nLoop].status;
if (nLastChgMescond < stDiChange.di_bit_chg_array[nLoop].times) //目前未处理msecond
{
nLastChgMescond = stDiChange.di_bit_chg_array[nLoop].times;
}
}
}
int nResultValue = getValueByValuex(stDigPointAll.value_num,&valuex[0],&statusx[0]);//通过DI分量得到DI值
if (nResultValue < 0)
{
LOGERROR("CheckDiChgBuf::getValueByValuex return Error,nValueNum= %d", nValueNum);
return true;//出错,可以删除缓存
}
//下面开始通过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);
return true;//出错,可以删除缓存
}
}
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,strDiTagName.c_str());
return true;//出错,可以删除缓存
}
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",
strDiTagName.c_str(), nResultValue, nNewStatus);
}
return true;
}
bool CDigProcess::processDiSOEWithMultiVal(const string &strTagName, const SDiChange &stDiChange)
{
SDigPointAll stDigPointAll;
string strDiSOETagName = strTagName;
strDiSOETagName.resize(64);
int nRetCode = m_ptrRdbTableMng->getRecordAllColumnByKey(RT_DIG_TBL,strDiSOETagName.c_str(), stDigPointAll);
if (nRetCode <=0 )
{
LOGERROR("CheckDiSoeBuf::nRetCode = %d, tag_name = %s, 获取实时值 error!", nRetCode, strDiSOETagName.c_str());
return true;//出错,可以删除缓存
}
int nValueNum = stDigPointAll.value_num;
if (nValueNum > MAX_DI_BIT_NUM || nValueNum <= 0 )
{
LOGINFO( "CheckDiSoeBuf::nValueNum=%d > MAX_DI_BIT_NUM", nValueNum);
return true;//出错,可以删除缓存
}
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 (stDiChange.di_bit_chg_array[nLoop].use_flag == SHARE_BUF_USE)
{
valuex[nLoop] = stDiChange.di_bit_chg_array[nLoop].value;
statusx[nLoop] = stDiChange.di_bit_chg_array[nLoop].status;
if (nLastChgMescond < stDiChange.di_bit_chg_array[nLoop].times)
{
nLastChgMescond = stDiChange.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);
return true;//出错,可以删除缓存
}
//或者报警状态文本
SDigAlarmPara stDigAlmPara;
getDigAlarmPara(stDigPointAll,nRetValue ,stDigAlmPara);
//产生SOE报警
//==============================================================================================
addOneDigAlarm(ALM_TYPE_SOE,stDigPointAll,stDigAlmPara,nLastChgMescond) ;
return true;
}
void CDigProcess::testAndProcessDiWithMultiVal(const SDigPointAll &stDiInfo)
{
//经过前面处理mapDiChgBuf一定会存在strTagName
auto pIter = m_mapDiChgBuf.find(stDiInfo.tag_name);
if(pIter == m_mapDiChgBuf.end())
{
return;
}
SDiChange &stCurDi = pIter->second;
std::bitset<MAX_DI_BIT_NUM> bitDi;
for(int i = 0;i < stDiInfo.value_num;i++)
{
if(stCurDi.di_bit_chg_array[i].use_flag == SHARE_BUF_USE)
{
bitDi.set(i,stCurDi.di_bit_chg_array[i].value != 0);
}
else
{
return; //如果分量数量不满足,意味着可能只有部分分量采集到了,延迟处理
}
}
if(m_ptrDataProcApi->isExistStateText(stDiInfo.state_text_name,static_cast<int>(bitDi.to_ulong()) ) )
{
//在数字量文本中存在,则认为值已经正常,可以直接处理,如果存在可能处于过渡态
processDiWithMultiVal(stDiInfo.tag_name,stCurDi);
m_mapDiChgBuf.erase(pIter);
}
//注意后面pIter已经失效不能使用了
return;
}
void CDigProcess::testAndProcessDiSOEWithMultiVal(const SDigPointAll &stDiInfo)
{
//经过前面处理mapDiChgBuf一定会存在strTagName
auto pIter = m_mapDiSoeBuf.find(stDiInfo.tag_name);
if(pIter == m_mapDiSoeBuf.end())
{
return;
}
SDiChange &stCurDi = pIter->second;
std::bitset<MAX_DI_BIT_NUM> bitDi;
for(int i = 0;i < stDiInfo.value_num;i++)
{
if(stCurDi.di_bit_chg_array[i].use_flag == SHARE_BUF_USE)
{
bitDi.set(i,stCurDi.di_bit_chg_array[i].value != 0);
}
else
{
return; //如果分量数量不满足,意味着可能只有部分分量采集到了,延迟处理
}
}
if(m_ptrDataProcApi->isExistStateText(stDiInfo.state_text_name,static_cast<int>(bitDi.to_ulong()) ) )
{
//在数字量文本中存在,则认为值已经正常,可以直接处理,如果存在可能处于过渡态
processDiSOEWithMultiVal(stDiInfo.tag_name,stCurDi);
m_mapDiSoeBuf.erase(pIter);
}
//注意后面pIter已经失效不能使用了
return;
}

View File

@ -31,10 +31,6 @@ public:
private: private:
//系统启动全数据告警延时 //系统启动全数据告警延时
int m_nChangeCount;//变化次数统计
int m_nChgAlarmCount;//产生的告警统计
int m_nSoeAlarmCount;//产生SOE数量
int64 m_nStartupTimes; //单位秒 int64 m_nStartupTimes; //单位秒
int m_nStartAlarmDelay; int m_nStartAlarmDelay;
//数字量状态 //数字量状态
@ -94,7 +90,9 @@ private:
bool bUpdatedByValidDataFlag, int64 lUpdateTimes) ; bool bUpdatedByValidDataFlag, int64 lUpdateTimes) ;
void checkDiChgBuf(); void checkDiChgBuf();
void checkDiChgBuf_bak();
void checkDiSoeBuf(); void checkDiSoeBuf();
void checkDiSoeBuf_bak();
bool isUpdatedByValidData(const int nLastStatus,const SUpdateDiInfo &stUpdateDiInfo ); bool isUpdatedByValidData(const int nLastStatus,const SUpdateDiInfo &stUpdateDiInfo );
int processValueChange(const SDigPointAll &stDigPointAll, SDigAlarmPara &stDigAlmPara, int processValueChange(const SDigPointAll &stDigPointAll, SDigAlarmPara &stDigAlmPara,
@ -113,6 +111,16 @@ private:
const std::string& strStatusText,const int nDescFlag= ALARM_DESC_POINT_FLAG); const std::string& strStatusText,const int nDescFlag= ALARM_DESC_POINT_FLAG);
void getTimeString(char *strTimeBuf, const int nSec, short sMsec = 0, bool bMsecFlag = false); void getTimeString(char *strTimeBuf, const int nSec, short sMsec = 0, bool bMsecFlag = false);
//多分量测点暂时打了一个补丁解决多分量只能等到防抖时间才会合并,有个不完善的地方是:如果只上传分量间隔长,有可能无法进入快速处理的逻辑中
//比如2个分量初始值都为0分量1上传1分量2不上传这样虽然是个合法值因为缓存中只有一个分量所以进不了快速合并的逻辑
//处理1条m_mapDiChgBuf中多个分量的DI点返回true表示可以从缓存中删除了不一定是正常处理了也可能是异常需要删除
bool processDiWithMultiVal(const std::string &strTagName,const SDiChange &stDiChange);
bool processDiSOEWithMultiVal(const std::string &strTagName,const SDiChange &stDiChange);
//检测一下缓冲区中多个分量是不是已经都有缓存,并且缓存合成值在数字量文本中存在,如果成立则直接处理,如果不存在就等抖动延时再处理
void testAndProcessDiWithMultiVal(const SDigPointAll &stDiInfo);
void testAndProcessDiSOEWithMultiVal(const SDigPointAll &stDiInfo);
}; };
typedef boost::shared_ptr<CDigProcess> CDigProcessPtr; typedef boost::shared_ptr<CDigProcess> CDigProcessPtr;
} }

View File

@ -18,7 +18,7 @@ using namespace iot_service;
using namespace std; using namespace std;
CMsgRecvThread::CMsgRecvThread(iot_public::SRunAppInfo stRunAppInfo,CPacketQueuePtr ptrPacketQueue): CMsgRecvThread::CMsgRecvThread(iot_public::SRunAppInfo stRunAppInfo,CPacketQueuePtr ptrPacketQueue):
CTimerThreadBase("CMsgRecvThread",1) CTimerThreadBase("CMsgRecvThread",0)
{ {
m_ptrPacketQueue = ptrPacketQueue ; m_ptrPacketQueue = ptrPacketQueue ;
m_stRunAppInfo = stRunAppInfo; m_stRunAppInfo = stRunAppInfo;
@ -131,7 +131,7 @@ int CMsgRecvThread::parseOptPackage(const iot_net::CMbMessage &objRecvMsg)
int nMessageType = objRecvMsg.getMsgType(); int nMessageType = objRecvMsg.getMsgType();
SOptSetDataPkg objOptSetDataPkg; SOptSetDataPkg objOptSetDataPkg;
bRetCode = objOptSetDataPkg.ParseFromArray(objRecvMsg.getDataPtr(),objRecvMsg.getDataSize()); bRetCode = objOptSetDataPkg.ParseFromArray(objRecvMsg.getDataPtr(),static_cast<int>(objRecvMsg.getDataSize()));
if(bRetCode == false) if(bRetCode == false)
{ {
LOGWARN("parseOptPackage, objOptSetDataPkg.ParseFromArray fail "); LOGWARN("parseOptPackage, objOptSetDataPkg.ParseFromArray fail ");
@ -175,7 +175,7 @@ int CMsgRecvThread::parseFesPackage(const iot_net::CMbMessage &objRecvMsg)
{ {
SFesChangeDiPkg objFesChanageDiPkg; SFesChangeDiPkg objFesChanageDiPkg;
//t1 = getUTCTimeMsec() ; //t1 = getUTCTimeMsec() ;
bRetCode = objFesChanageDiPkg.ParseFromArray(objRecvMsg.getDataPtr(), objRecvMsg.getDataSize()); bRetCode = objFesChanageDiPkg.ParseFromArray(objRecvMsg.getDataPtr(), static_cast<int>(objRecvMsg.getDataSize()));
//t2 = getUTCTimeMsec() ; //t2 = getUTCTimeMsec() ;
//LOGINFO("parseFesPackage:解析变化数字量 num=%d用时=%d(ms)",objFesChanageDiPkg.stdidata_size(),t2-t1); //LOGINFO("parseFesPackage:解析变化数字量 num=%d用时=%d(ms)",objFesChanageDiPkg.stdidata_size(),t2-t1);
if(!bRetCode) if(!bRetCode)
@ -190,7 +190,7 @@ int CMsgRecvThread::parseFesPackage(const iot_net::CMbMessage &objRecvMsg)
{ {
SFesUpdateDiPkg objFesUpdateDiPkg; SFesUpdateDiPkg objFesUpdateDiPkg;
//t1 = getUTCTimeMsec() ; //t1 = getUTCTimeMsec() ;
bRetCode = objFesUpdateDiPkg.ParseFromArray(objRecvMsg.getDataPtr(), objRecvMsg.getDataSize()); bRetCode = objFesUpdateDiPkg.ParseFromArray(objRecvMsg.getDataPtr(), static_cast<int>(objRecvMsg.getDataSize()));
//t2 = getUTCTimeMsec() ; //t2 = getUTCTimeMsec() ;
//LOGINFO("parseFesPackage:解析数字量全数据 num=%d用时=%d(ms)",objFesUpdateDiPkg.stdidata_size(),t2-t1); //LOGINFO("parseFesPackage:解析数字量全数据 num=%d用时=%d(ms)",objFesUpdateDiPkg.stdidata_size(),t2-t1);
if(!bRetCode) if(!bRetCode)
@ -204,7 +204,7 @@ int CMsgRecvThread::parseFesPackage(const iot_net::CMbMessage &objRecvMsg)
case MT_FES_AI_CHANGE://AI Change Data case MT_FES_AI_CHANGE://AI Change Data
{ {
SFesChangeAiPkg objFesChanageAiPkg; SFesChangeAiPkg objFesChanageAiPkg;
bRetCode = objFesChanageAiPkg.ParseFromArray(objRecvMsg.getDataPtr(), objRecvMsg.getDataSize()); bRetCode = objFesChanageAiPkg.ParseFromArray(objRecvMsg.getDataPtr(), static_cast<int>(objRecvMsg.getDataSize()));
if(!bRetCode) if(!bRetCode)
{ {
LOGWARN("parseFesPackage::objFesChanageAiPkg解析错误"); LOGWARN("parseFesPackage::objFesChanageAiPkg解析错误");
@ -216,7 +216,7 @@ int CMsgRecvThread::parseFesPackage(const iot_net::CMbMessage &objRecvMsg)
case MT_FES_AI_UPDATE://AI UPDATE Data case MT_FES_AI_UPDATE://AI UPDATE Data
{ {
SFesUpdateAiPkg objFesUpdateAiPkg; SFesUpdateAiPkg objFesUpdateAiPkg;
bRetCode = objFesUpdateAiPkg.ParseFromArray(objRecvMsg.getDataPtr(), objRecvMsg.getDataSize()); bRetCode = objFesUpdateAiPkg.ParseFromArray(objRecvMsg.getDataPtr(), static_cast<int>(objRecvMsg.getDataSize()));
if(!bRetCode) if(!bRetCode)
{ {
LOGWARN("parseFesPackage::objFesUpdateAiPkg解析错误"); LOGWARN("parseFesPackage::objFesUpdateAiPkg解析错误");
@ -228,7 +228,7 @@ int CMsgRecvThread::parseFesPackage(const iot_net::CMbMessage &objRecvMsg)
case MT_FES_MI_CHANGE://MI Change Data case MT_FES_MI_CHANGE://MI Change Data
{ {
SFesChangeMiPkg objFesChanageMiPkg; SFesChangeMiPkg objFesChanageMiPkg;
bRetCode = objFesChanageMiPkg.ParseFromArray(objRecvMsg.getDataPtr(), objRecvMsg.getDataSize()); bRetCode = objFesChanageMiPkg.ParseFromArray(objRecvMsg.getDataPtr(), static_cast<int>(objRecvMsg.getDataSize()));
if(!bRetCode) if(!bRetCode)
{ {
LOGWARN("parseFesPackage::objFesChanageMiPkg解析错误"); LOGWARN("parseFesPackage::objFesChanageMiPkg解析错误");
@ -240,7 +240,7 @@ int CMsgRecvThread::parseFesPackage(const iot_net::CMbMessage &objRecvMsg)
case MT_FES_MI_UPDATE://MI UPDATE Data case MT_FES_MI_UPDATE://MI UPDATE Data
{ {
SFesUpdateMiPkg objFesUpdateMiPkg; SFesUpdateMiPkg objFesUpdateMiPkg;
bRetCode = objFesUpdateMiPkg.ParseFromArray(objRecvMsg.getDataPtr(), objRecvMsg.getDataSize()); bRetCode = objFesUpdateMiPkg.ParseFromArray(objRecvMsg.getDataPtr(), static_cast<int>(objRecvMsg.getDataSize()));
if(!bRetCode) if(!bRetCode)
{ {
LOGWARN("parseFesPackage::objFesUpdateMiPkg解析错误"); LOGWARN("parseFesPackage::objFesUpdateMiPkg解析错误");
@ -252,7 +252,7 @@ int CMsgRecvThread::parseFesPackage(const iot_net::CMbMessage &objRecvMsg)
case MT_FES_PI_CHANGE://PI Change Data case MT_FES_PI_CHANGE://PI Change Data
{ {
SFesChangePiPkg objFesChangePiPkg; SFesChangePiPkg objFesChangePiPkg;
bRetCode = objFesChangePiPkg.ParseFromArray(objRecvMsg.getDataPtr(), objRecvMsg.getDataSize()); bRetCode = objFesChangePiPkg.ParseFromArray(objRecvMsg.getDataPtr(), static_cast<int>(objRecvMsg.getDataSize()));
if(!bRetCode) if(!bRetCode)
{ {
LOGWARN("parseFesPackage::objFesChangePiPkg解析错误"); LOGWARN("parseFesPackage::objFesChangePiPkg解析错误");
@ -264,7 +264,7 @@ int CMsgRecvThread::parseFesPackage(const iot_net::CMbMessage &objRecvMsg)
case MT_FES_PI_UPDATE://PI UPDATE Data case MT_FES_PI_UPDATE://PI UPDATE Data
{ {
SFesUpdatePiPkg objFesUpdatePiPkg; SFesUpdatePiPkg objFesUpdatePiPkg;
bRetCode = objFesUpdatePiPkg.ParseFromArray(objRecvMsg.getDataPtr(), objRecvMsg.getDataSize()); bRetCode = objFesUpdatePiPkg.ParseFromArray(objRecvMsg.getDataPtr(), static_cast<int>(objRecvMsg.getDataSize()));
if(!bRetCode) if(!bRetCode)
{ {
LOGWARN("parseFesPackage::objFesUpdatePiPkg解析错误"); LOGWARN("parseFesPackage::objFesUpdatePiPkg解析错误");
@ -276,7 +276,7 @@ int CMsgRecvThread::parseFesPackage(const iot_net::CMbMessage &objRecvMsg)
case MT_FES_SOE_EVENT: //SOE事件信息 case MT_FES_SOE_EVENT: //SOE事件信息
{ {
SFesSoeEventPkg objFesSoeEventPkg ; SFesSoeEventPkg objFesSoeEventPkg ;
bRetCode = objFesSoeEventPkg.ParseFromArray(objRecvMsg.getDataPtr(), objRecvMsg.getDataSize()); bRetCode = objFesSoeEventPkg.ParseFromArray(objRecvMsg.getDataPtr(), static_cast<int>(objRecvMsg.getDataSize()));
if(!bRetCode) if(!bRetCode)
{ {
LOGWARN("parseFesPackage::objFesSoeEventPkg解析错误"); LOGWARN("parseFesPackage::objFesSoeEventPkg解析错误");
@ -285,6 +285,11 @@ int CMsgRecvThread::parseFesPackage(const iot_net::CMbMessage &objRecvMsg)
m_ptrPacketQueue->addFesSoeEventPkg(objFesSoeEventPkg); m_ptrPacketQueue->addFesSoeEventPkg(objFesSoeEventPkg);
break; break;
} }
case MT_FES_CHAN_UPDATE: //通道状态信息,暂不处理
case MT_FES_RTU_UPDATE: //RTU状态信息暂不处理
{
break;
}
default: default:
{ {
LOGWARN("parseFesPackage::MsgType = %d 消息类型不支持!",nMessageType); LOGWARN("parseFesPackage::MsgType = %d 消息类型不支持!",nMessageType);

View File

@ -301,7 +301,7 @@ void CPacketQueue::addOptCalSetPkg(const SOptSetDataPkg &objOptCalSetPkg)//计
deqCalSetPkg.clear(); deqCalSetPkg.clear();
deqCalSetPkg.push_back(objOptCalSetPkg); deqCalSetPkg.push_back(objOptCalSetPkg);
m_mapOptCalSetPkg.insert(pair<int,deque <SOptSetDataPkg>>(nPointType,deqCalSetPkg)); m_mapOptCalSetPkg.insert(pair<int,deque <SOptSetDataPkg>>(nPointType,deqCalSetPkg));
LOGINFO("addOptCalSetPkg::计算点map中未找到数据类型为[%d]的队列,insert",nPointType); LOGDEBUG("addOptCalSetPkg::计算点map中未找到数据类型为[%d]的队列,insert",nPointType);
} }
return; return;
} }
@ -321,7 +321,8 @@ bool CPacketQueue::getOptCalSetPkg(const int nPointType,std::deque <SOptSetDataP
deqOptCalSetPkg = pos->second; deqOptCalSetPkg = pos->second;
pos->second.clear(); pos->second.clear();
m_mapOptCalSetPkg.erase(pos); //map结点删除 m_mapOptCalSetPkg.erase(pos); //map结点删除
LOGINFO("getOptCalSetPkg::数据交换完成队列数量num=%llu",(unsigned long long)deqOptCalSetPkg.size()); //LOGINFO("getOptCalSetPkg::数据交换完成队列数量num=%llu",(unsigned long long)deqOptCalSetPkg.size());
LOGDEBUG("getOptCalSetPkg::数据交换完成队列数量num=%d",static_cast<int>(deqOptCalSetPkg.size()));
} }
else else
{ {

View File

@ -11,11 +11,11 @@
#include "OptDataMessage.pb.h" #include "OptDataMessage.pb.h"
#include <deque> #include <deque>
#define MAX_CHG_ANA_QUEUE_NUM 50 //变化数据最大队列数如果超出丢弃最老数据50*1000 一秒变化数据5万windwo 处理5秒左右linux2秒左右 #define MAX_CHG_ANA_QUEUE_NUM 500 //变化数据最大队列数如果超出丢弃最老数据50*1000 一秒变化数据5万windwo 处理5秒左右linux2秒左右
#define MAX_CHG_DIG_QUEUE_NUM 100 //变化数据最大队列数,最多保证不丢失 15万YX点,10%变化率30秒持续不丢失事件1.5*10000*30 万点的容量) #define MAX_CHG_DIG_QUEUE_NUM 1000 //变化数据最大队列数,最多保证不丢失 15万YX点,10%变化率30秒持续不丢失事件1.5*10000*30 万点的容量)
#define MAX_MAN_SET_QUEUE_NUM 500 //人工置数最大队列数考虑对一个间隔最多200个测点 #define MAX_MAN_SET_QUEUE_NUM 1000 //人工置数最大队列数考虑对一个间隔最多200个测点
#define MAX_CAL_SET_QUEUE_NUM 200 //计算公式最大队列数考虑公式不会超时1000变化率20% #define MAX_CAL_SET_QUEUE_NUM 10000 //计算公式最大队列数考虑公式不会超时1000变化率20%
#define MAX_UPD_QUEUE_NUM 20 //全数据最大队列数,如果超出,丢弃最老数据 每种类型25*10000 20万点的容量 #define MAX_UPD_QUEUE_NUM 50 //全数据最大队列数,如果超出,丢弃最老数据 每种类型25*10000 20万点的容量
#define MAX_EVT_QUEUE_NUM 500000 //变化事件,如果超出,丢弃最老数据(考虑15万YX点,10%变化率30秒持续共45万点不丢失事件) #define MAX_EVT_QUEUE_NUM 500000 //变化事件,如果超出,丢弃最老数据(考虑15万YX点,10%变化率30秒持续共45万点不丢失事件)
namespace iot_service namespace iot_service

View File

@ -62,9 +62,9 @@ bool CPointBase::initialize()
} }
//得到数字量文本报警方式 //得到数字量文本报警方式
//============================================================================================= //=============================================================================================
if (m_ptrDataProcApi->getMenuMacToValMap("数字量文本警方式", m_mapAlarmStyle) < 0) if (m_ptrDataProcApi->getMenuMacToValMap("数字量文本警方式", m_mapAlarmStyle) < 0)
{ {
LOGERROR("CPointBase::initialize(), getMenu 数字量文本警方式 fail!\n"); LOGERROR("CPointBase::initialize(), getMenu 数字量文本警方式 fail!\n");
return false; return false;
} }
//得到模拟量状态字信息 //得到模拟量状态字信息

View File

@ -8,12 +8,15 @@
#include "DataProcessImpl.h" #include "DataProcessImpl.h"
#include "alarm_server_api/AlarmCommonDef.h" #include "alarm_server_api/AlarmCommonDef.h"
#include "public/pub_utility_api/TimeUtil.h" #include "public/pub_utility_api/TimeUtil.h"
#include "public/pub_utility_api/CharUtil.h"
using namespace iot_dbms; using namespace iot_dbms;
using namespace iot_service; using namespace iot_service;
using namespace iot_public; using namespace iot_public;
using namespace std; using namespace std;
const std::string CN_STATETEXT_CACHE_DELIMITER = "_#@#_"; //用于拼接数字量文本标识+分隔符+动作值
CDataProcessImpl::CDataProcessImpl(std::string strAppName) CDataProcessImpl::CDataProcessImpl(std::string strAppName)
{ {
m_IsInit = false; m_IsInit = false;
@ -117,10 +120,10 @@ int CDataProcessImpl::initialize()
//数字量文本报警方式 //数字量文本报警方式
//========================================================================== //==========================================================================
nRetCode = getMenuMacToValMap("数字量文本警方式", menu_map); nRetCode = getMenuMacToValMap("数字量文本警方式", menu_map);
if (nRetCode < 0) if (nRetCode < 0)
{ {
LOGERROR( "CDataProcessImpl::Init(), getMenuMacToValMap(数字量文本警方式) error!"); LOGERROR( "CDataProcessImpl::Init(), getMenuMacToValMap(数字量文本警方式) error!");
return -1; return -1;
} }
MENU_EVENT_ONLY = menu_map["MENU_EVENT_ONLY"]; MENU_EVENT_ONLY = menu_map["MENU_EVENT_ONLY"];
@ -656,6 +659,7 @@ int CDataProcessImpl::readAllStateText(map<string, vector<SStateText> > &mapStat
} }
mapStateText.clear(); mapStateText.clear();
m_setStateTextAndValue.clear();
std::vector<SStateTextSelect> vecStateTextSelect ; std::vector<SStateTextSelect> vecStateTextSelect ;
vecStateTextSelect.clear(); vecStateTextSelect.clear();
@ -691,6 +695,9 @@ int CDataProcessImpl::readAllStateText(map<string, vector<SStateText> > &mapStat
{ {
pos->second.push_back(stOneStateText); pos->second.push_back(stOneStateText);
} }
//缓存数字量文本+值
m_setStateTextAndValue.insert(strStateTextName + CN_STATETEXT_CACHE_DELIMITER + IntToString(stOneStateText.actual_value));
} }
m_LastReadStateText = getUTCTimeSec(); m_LastReadStateText = getUTCTimeSec();
@ -890,3 +897,13 @@ int CDataProcessImpl::getDigAlarmPara(const SDigAlarmInfo &stDigAlmInfo,SDigAla
return 0; return 0;
} }
bool CDataProcessImpl::isExistStateText(const string &strStateText, const int &nValue)
{
if(m_setStateTextAndValue.count(strStateText + CN_STATETEXT_CACHE_DELIMITER + IntToString(nValue)))
{
return true;
}
return false;
}

View File

@ -83,6 +83,7 @@ private:
std::string m_strAppName; std::string m_strAppName;
iot_dbms::CRdbTableMngPtr m_ptrRdbTableMng; iot_dbms::CRdbTableMngPtr m_ptrRdbTableMng;
std::map<std::string, std::vector<SStateText> > m_mapStateText; std::map<std::string, std::vector<SStateText> > m_mapStateText;
std::set<std::string> m_setStateTextAndValue; //用来缓存所有的数字量文本信息,有数字量文本+值组成
public: public:
/** /**
@ -204,6 +205,15 @@ public:
@retval @retval
*/ */
int getDigAlarmPara(const SDigAlarmInfo &stDigAlmInfo,SDigAlarmPara &stDigAlmPara); int getDigAlarmPara(const SDigAlarmInfo &stDigAlmInfo,SDigAlarmPara &stDigAlmPara);
/**
@brief
@param strStateText
@param nValue actual_value
@return bool
@retval true代表存在false代表不存在
*/
bool isExistStateText(const std::string &strStateText,const int &nValue);
}; };
typedef boost::shared_ptr<CDataProcessImpl> CDataProcessImplPtr; typedef boost::shared_ptr<CDataProcessImpl> CDataProcessImplPtr;
} }

View File

@ -552,7 +552,7 @@ void CDpcdaForDpImpl::handle_MT_DPCDA_APP2DP_CHG(iot_net::CMbMessage &objMbMsg)
{ {
//< 反序列化 //< 反序列化
iot_idl::SDpcdaSubPkg objSubPkgChg; iot_idl::SDpcdaSubPkg objSubPkgChg;
if (!objSubPkgChg.ParseFromArray(objMbMsg.getDataPtr(), objMbMsg.getDataSize())) if (!objSubPkgChg.ParseFromArray(objMbMsg.getDataPtr(), static_cast<int>(objMbMsg.getDataSize())))
{ {
LOGWARN("handle_MT_DPCDA_APP2DP_CHG(): 反序列化失败,忽略消息!"); LOGWARN("handle_MT_DPCDA_APP2DP_CHG(): 反序列化失败,忽略消息!");
return; return;
@ -697,7 +697,7 @@ void CDpcdaForDpImpl::handle_MT_DPCDA_APP2DP_ALL(iot_net::CMbMessage &objMbMsg)
{ {
//< 反序列化 //< 反序列化
iot_idl::SDpcdaSubPkg objSubPkgAll; iot_idl::SDpcdaSubPkg objSubPkgAll;
if (!objSubPkgAll.ParseFromArray(objMbMsg.getDataPtr(), objMbMsg.getDataSize())) if (!objSubPkgAll.ParseFromArray(objMbMsg.getDataPtr(), static_cast<int>(objMbMsg.getDataSize())))
{ {
LOGWARN("handle_MT_DPCDA_APP2DP_ALL(): 反序列化失败,忽略消息!"); LOGWARN("handle_MT_DPCDA_APP2DP_ALL(): 反序列化失败,忽略消息!");
return; return;
@ -913,7 +913,7 @@ bool CDpcdaForDpImpl::getAiDataFromRtdb(const std::string &strTagName, iot_idl::
{ {
if (m_pRtdb_AI->getColumnValueByIndex(nRcdIndex, "value", objValue)) if (m_pRtdb_AI->getColumnValueByIndex(nRcdIndex, "value", objValue))
{ {
pRtd->set_fvalue(objValue.toDouble()); pRtd->set_fvalue(static_cast<float>(objValue.toDouble()));
} }
else else
{ {

View File

@ -10,8 +10,19 @@
#include "boost/typeof/typeof.hpp" #include "boost/typeof/typeof.hpp"
#include "boost/lexical_cast.hpp" #include "boost/lexical_cast.hpp"
#include "boost/filesystem.hpp" #include "boost/filesystem.hpp"
//< 屏蔽xml_parser编译告警
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-copy"
#endif
#include "boost/property_tree/xml_parser.hpp" #include "boost/property_tree/xml_parser.hpp"
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#include "pub_logger_api/logger.h" #include "pub_logger_api/logger.h"
#include "pub_utility_api/FileUtil.h" #include "pub_utility_api/FileUtil.h"

View File

@ -3,7 +3,19 @@
#include "pub_logger_api/logger.h" #include "pub_logger_api/logger.h"
#include "CRelativeCallback.h" #include "CRelativeCallback.h"
#include "boost/property_tree/ptree.hpp" #include "boost/property_tree/ptree.hpp"
//< 屏蔽xml_parser编译告警
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-copy"
#endif
#include "boost/property_tree/xml_parser.hpp" #include "boost/property_tree/xml_parser.hpp"
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#include "boost/typeof/typeof.hpp" #include "boost/typeof/typeof.hpp"
#include "pub_utility_api/FileUtil.h" #include "pub_utility_api/FileUtil.h"
#include "pub_utility_api/CommonConfigParse.h" #include "pub_utility_api/CommonConfigParse.h"

View File

@ -2,7 +2,7 @@
# ARM板上资源有限,不会与云平台混用,不编译 # ARM板上资源有限,不会与云平台混用,不编译
message("Compile only in x86 environment") message("Compile only in x86 environment")
# requires(contains(QMAKE_HOST.arch, x86_64)) # requires(contains(QMAKE_HOST.arch, x86_64))
requires(!contains(QMAKE_HOST.arch, aarch64)) requires(!contains(QMAKE_HOST.arch, aarch64) : !linux-aarch64*)
TEMPLATE = app TEMPLATE = app
CONFIG += console c++11 CONFIG += console c++11

View File

@ -6,6 +6,9 @@
#include "OperateServerClass.h" #include "OperateServerClass.h"
#include "pub_logger_api/logger.h" #include "pub_logger_api/logger.h"
#include "pub_utility_api/CharUtil.h"
#include "pub_utility_api/FileUtil.h"
#include "pub_utility_api/CommonConfigParse.h"
#include "MessageChannel.h" #include "MessageChannel.h"
using namespace std; using namespace std;
@ -30,6 +33,12 @@ COperateServerClass::~COperateServerClass()
bool COperateServerClass::initialize() bool COperateServerClass::initialize()
{ {
//读取配置文件
if(!readConfig())
{
return false;
}
//data_process_api 实例 //data_process_api 实例
//======================================================================================== //========================================================================================
m_ptrDataProcApi = getDataProcInstance(m_stRunAppInfo.strAppName); m_ptrDataProcApi = getDataProcInstance(m_stRunAppInfo.strAppName);
@ -313,7 +322,7 @@ int COperateServerClass::getUserAndUserGroup(const int nUserId,const int nUsergI
/** /**
@brief @brief
@return iotSuccess, @return iotSucces,
*/ */
int COperateServerClass::getValueStatus(const std::string &strTagName, SOptValueStatus &stValueStatus,\ int COperateServerClass::getValueStatus(const std::string &strTagName, SOptValueStatus &stValueStatus,\
int nDomainId ,int nAppNo) int nDomainId ,int nAppNo)
@ -1077,6 +1086,17 @@ int COperateServerClass::addOperateEvent(const SOptCtrlInfoAll &stOptCtrlInfo,
stOptCtrlInfo.table_name,stOptCtrlInfo.tag_name); stOptCtrlInfo.table_name,stOptCtrlInfo.tag_name);
return -1; return -1;
} }
//格式化控制值
if(stPoinBase.point_type == POINT_TYPE_DIG || stPoinBase.point_type == POINT_TYPE_MIX || stPoinBase.point_type == POINT_TYPE_DO)
{
strCtrlValue = DoubleToString(stOptCtrlInfo.target_value,0);
}
else if(stPoinBase.point_type == POINT_TYPE_ANA || stPoinBase.point_type == POINT_TYPE_AO || stPoinBase.point_type == POINT_TYPE_ACC)
{
strCtrlValue = DoubleToString(stOptCtrlInfo.target_value,m_nAlarmCtrlPrecision);
}
//得到测点基本信息 //得到测点基本信息
//====================================================================================== //======================================================================================
if(nAlarmStatus <=0) if(nAlarmStatus <=0)
@ -1140,7 +1160,14 @@ int COperateServerClass::addOperateEvent(const SOptCtrlInfoAll &stOptCtrlInfo,
addAlarmKeyword(stAlarmInfo,ALM_KEY_OPT_HOST,stOptCtrlInfo.host_name); //报警内容关键字-操作主机名 addAlarmKeyword(stAlarmInfo,ALM_KEY_OPT_HOST,stOptCtrlInfo.host_name); //报警内容关键字-操作主机名
addAlarmKeyword(stAlarmInfo,ALM_KEY_CTRL_VAL,strCtrlValue); //报警内容关键字-设备控制值 addAlarmKeyword(stAlarmInfo,ALM_KEY_CTRL_VAL,strCtrlValue); //报警内容关键字-设备控制值
addAlarmKeyword(stAlarmInfo,ALM_KEY_DEV_OPT_VAL,strCtrlValue); //报警内容关键字-设备操作值 addAlarmKeyword(stAlarmInfo,ALM_KEY_DEV_OPT_VAL,strCtrlValue); //报警内容关键字-设备操作值
if(strCtrlOptName.empty())
{
addAlarmKeyword(stAlarmInfo,ALM_KEY_DEV_OPT_NAME,strCtrlValue); //报警内容关键字-设备操作名为空时填充控制值
}
else
{
addAlarmKeyword(stAlarmInfo,ALM_KEY_DEV_OPT_NAME,strCtrlOptName); //报警内容关键字-设备操作名 addAlarmKeyword(stAlarmInfo,ALM_KEY_DEV_OPT_NAME,strCtrlOptName); //报警内容关键字-设备操作名
}
addAlarmKeyword(stAlarmInfo,ALM_KEY_RTN_RESULT,strCtrlResult); //报警内容关键字-设备操作结果 addAlarmKeyword(stAlarmInfo,ALM_KEY_RTN_RESULT,strCtrlResult); //报警内容关键字-设备操作结果
getTimeStrBySeconds(stOptCtrlInfo.opt_time/1000, strNameString); getTimeStrBySeconds(stOptCtrlInfo.opt_time/1000, strNameString);
addAlarmKeyword(stAlarmInfo,ALM_KEY_DEV_OPT_TIME,strNameString); //报警内容关键字-设备操作时间 addAlarmKeyword(stAlarmInfo,ALM_KEY_DEV_OPT_TIME,strNameString); //报警内容关键字-设备操作时间
@ -1702,3 +1729,16 @@ void COperateServerClass::sendAlarm()//向报警服务器发送报警信息
m_ptrOptComand->sendAlarm(); m_ptrOptComand->sendAlarm();
} }
} }
bool COperateServerClass::readConfig()
{
iot_public::CCommonConfigParse objCfgParse;
if(objCfgParse.load( iot_public::CFileUtil::getPathOfCfgFile("operate_server_cfg.xml") ) == iotFailed)
{
LOGERROR("COperateServerClass::readConfig() operate_server_cfg.xml load fail");
return false;
}
m_nAlarmCtrlPrecision = objCfgParse.getIntWithDefault("alarm_param","precision",2); //默认2位小数
return true;
}

View File

@ -22,6 +22,7 @@
#include <map> #include <map>
#include "string.h" #include "string.h"
#include "boost/unordered_map.hpp"
namespace iot_service namespace iot_service
{ {
@ -79,6 +80,8 @@ private:
map<string, SOptInternHandover> m_mapHandoverInfo; map<string, SOptInternHandover> m_mapHandoverInfo;
map<string, SOptCtrlResv> m_mapCtrlResvInfo; map<string, SOptCtrlResv> m_mapCtrlResvInfo;
map<string, SOptCtrlResv> m_mapCtrlPrev;//tag_name map<string, SOptCtrlResv> m_mapCtrlPrev;//tag_name
//std::vector<SOptCtrlRequest> m_vecCtrlWithoutResp; //< 主要用于功率控制场景,不等待反馈
boost::unordered_map<std::string,SOptCtrlReqQueue> m_mapCtrlWithoutResp; //< 防止指令挤压,将缓存中指令全部合并,只发送最后一次的指令
//状态字变量 //状态字变量
//====================================================================================================== //======================================================================================================
@ -92,7 +95,7 @@ private:
int m_nAiLockStatus; int m_nAiLockStatus;
int m_nAiInhibitCtlStatus; int m_nAiInhibitCtlStatus;
int m_nAiAlmRstStatus; int m_nAiAlmRstStatus;
int m_nAlarmCtrlPrecision; //告警描述中的精度
public: public:
//初始化相关函数 //初始化相关函数
//====================================================================================================== //======================================================================================================
@ -135,6 +138,8 @@ public:
//====================================================================================================== //======================================================================================================
int optAutoCtrl(const string &strJson);//标志牌同步、外部权限移交 int optAutoCtrl(const string &strJson);//标志牌同步、外部权限移交
int doOptAutoCtrl(); int doOptAutoCtrl();
int optAutoCtrlWithoutResp(const std::string &strJson);
int doOptAutoCtrlWithoutResp();
//挂牌/点标签/屏蔽相关函数 //挂牌/点标签/屏蔽相关函数
//====================================================================================================== //======================================================================================================
@ -154,6 +159,15 @@ public:
//====================================================================================================== //======================================================================================================
void sendChange();//MANSET 发送变化数据信息给HMI void sendChange();//MANSET 发送变化数据信息给HMI
void sendAlarm();//向报警服务器发送报警信息 void sendAlarm();//向报警服务器发送报警信息
private:
//点控/单控相关函数
//======================================================================================================
int optCtrlRequest(const SOptCtrlRequest &stCtrlRequest, string &strResult);//HMI遥控请求处理
int optCtrlSelect(const SOptCtrlRequest &stOptCtrlSelect);//HMI遥控选择处理
int optCtrlExecute(const SOptCtrlRequest &stOptDoCtrlExecute);//HMI遥控执行处理
private: private:
//公共内部接口函数 //公共内部接口函数
//====================================================================================================== //======================================================================================================
@ -236,6 +250,9 @@ private:
const bool bIsCtrlResv,const bool bCheckInterLock,string &strRequest); const bool bIsCtrlResv,const bool bCheckInterLock,string &strRequest);
int getAnaCtrlValue(SOptCtrlInfoAll &stOptCtrlInfoAll ); int getAnaCtrlValue(SOptCtrlInfoAll &stOptCtrlInfoAll );
//< 获取禁止控制的设备列表
int getInhibitCtrlDevList(std::set<std::string> &setDev);
//点标签接口函数 //点标签接口函数
//====================================================================================================== //======================================================================================================
int getTagType(const int nMsgType); int getTagType(const int nMsgType);
@ -254,6 +271,8 @@ private:
int modifyTokenStatus(const int nIsSet,const int nTokenId,const string strDevTag,bool bNotAlarm=false); int modifyTokenStatus(const int nIsSet,const int nTokenId,const string strDevTag,bool bNotAlarm=false);
int getTokenAlmStatus(int &nAlarmStatus, string &strOptDesc); int getTokenAlmStatus(int &nAlarmStatus, string &strOptDesc);
int optTokenAlarm(const STokenInfoAll &stOptTokenInfo, const bool bIsSync = false); int optTokenAlarm(const STokenInfoAll &stOptTokenInfo, const bool bIsSync = false);
//< 获取携带禁止控制属性的设备列表
int getTokenDevWithInhibitCtrl(std::set<std::string> &setDev);
//屏蔽接口函数 //屏蔽接口函数
//====================================================================================================== //======================================================================================================
@ -269,6 +288,8 @@ private:
bool getShieldDevice(SOptShieldObj &stShieldObj,vector<SDeviceTagInfo> &vecDeviceTag); bool getShieldDevice(SOptShieldObj &stShieldObj,vector<SDeviceTagInfo> &vecDeviceTag);
int getShieldAlmStatus(const int &ShieldnMode,int &nAlarmStatus); int getShieldAlmStatus(const int &ShieldnMode,int &nAlarmStatus);
int optShieldAlarm(const SOptShieldInfo &stOptShieldInfo, const SOptShieldObj &stOptShieldObj, const int nIsSet,const int nFlag); int optShieldAlarm(const SOptShieldInfo &stOptShieldInfo, const SOptShieldObj &stOptShieldObj, const int nIsSet,const int nFlag);
//< 获取携带禁止控制属性的设备列表
int getShieldDevWithInhibitCtrl(std::set<std::string> &setDev);
//权限移交内部接口函数 //权限移交内部接口函数
//====================================================================================================== //======================================================================================================
@ -279,6 +300,8 @@ private:
void addOneHandoverChange(const string strTagName, const int location, const int nDomainID); void addOneHandoverChange(const string strTagName, const int location, const int nDomainID);
int getHandoverAlmStatus(const int nOptType,int &nAlarmStatus,string &strOptDesc,const int nType); int getHandoverAlmStatus(const int nOptType,int &nAlarmStatus,string &strOptDesc,const int nType);
int addOneInternHandoverReply(const SOptInternHandover &stOptHandoverInfo, const int nType); int addOneInternHandoverReply(const SOptInternHandover &stOptHandoverInfo, const int nType);
bool readConfig(); //读数据处理配置
}; };
typedef boost::shared_ptr<COperateServerClass> COperateServerClassPtr; typedef boost::shared_ptr<COperateServerClass> COperateServerClassPtr;
} }

View File

@ -460,10 +460,12 @@ struct SPointCtrlInfo
int is_tagt_state; int is_tagt_state;
int ctrl_timeout; int ctrl_timeout;
int resv_timeout; int resv_timeout;
char rtu_tag[64];
char offset_no[48]; char offset_no[48];
SOptCtrlActAll stCtrlActInfo;//控制动作组信息; SOptCtrlActAll stCtrlActInfo;//控制动作组信息;
SPointCtrlInfo() SPointCtrlInfo()
{ {
memset(rtu_tag,0,sizeof(rtu_tag));
memset(offset_no,0,48); memset(offset_no,0,48);
} }
}; };
@ -652,7 +654,7 @@ struct SOptCtrlInfoAll
int64 opt_local_time ; int64 opt_local_time ;
double target_value ; double target_value ;
double ctrl_tolerance ; double ctrl_tolerance ;
int ctrl_act_type ; int ctrl_act_type ; //< DO和MO经过控制动作组转换的对FES的控制值对AO没有用
char ctrl_act_name[64] ; char ctrl_act_name[64] ;
char rtu_tag[64] ; //new char rtu_tag[64] ; //new
char offset_no[48] ; char offset_no[48] ;

View File

@ -8,6 +8,7 @@
#include "pub_utility_api/TimeUtil.h" #include "pub_utility_api/TimeUtil.h"
#include "rdb_api/FuncForNet.h" #include "rdb_api/FuncForNet.h"
#include "MessageChannel.h" #include "MessageChannel.h"
#include "service/common/RdbTableDefine.h"
using namespace iot_service; using namespace iot_service;
using namespace iot_idl; using namespace iot_idl;
@ -120,8 +121,9 @@ int COptCommand::sendDigCtrlToFes(const SOptCtrlInfoAll &stOptCtrlInfoAll, const
stDoCtrlPkg.set_norder(atoi(stOptCtrlInfoAll.offset_no)); stDoCtrlPkg.set_norder(atoi(stOptCtrlInfoAll.offset_no));
stDoCtrlPkg.set_naction(stOptCtrlInfoAll.ctrl_act_type); //动作值 stDoCtrlPkg.set_naction(stOptCtrlInfoAll.ctrl_act_type); //动作值
stDoCtrlPkg.set_niftagtstate(stOptCtrlInfoAll.is_tagt_state);//是否等待目标状态 stDoCtrlPkg.set_niftagtstate(stOptCtrlInfoAll.is_tagt_state);//是否等待目标状态
stDoCtrlPkg.set_nctrltype(stOptCtrlInfoAll.msg_type); //控制类型:选择、执行、取消
if(stDoCtrlPkg.SerializeToString(&strSendMessage) == false) if(!stDoCtrlPkg.SerializeToString(&strSendMessage))
{ {
LOGERROR("SendDoCtrlToFes,stDoCtrlPkg.SerializeToString error! "); LOGERROR("SendDoCtrlToFes,stDoCtrlPkg.SerializeToString error! ");
return -1; return -1;
@ -195,7 +197,7 @@ int COptCommand::sendSetCtrlToFes(const SOptCtrlInfoAll &stOptCtrlInfoAll,
return 0; return 0;
} }
//发送AO控制信息给FES //发送MO控制信息给FES
int COptCommand::sendMixCtrlToFes(const SOptCtrlInfoAll &stOptCtrlInfoAll, const string &strSrcTag) int COptCommand::sendMixCtrlToFes(const SOptCtrlInfoAll &stOptCtrlInfoAll, const string &strSrcTag)
{ {
string strSendMessage ="" ; string strSendMessage ="" ;
@ -207,8 +209,12 @@ int COptCommand::sendMixCtrlToFes(const SOptCtrlInfoAll &stOptCtrlInfoAll, const
stMoCtrlPkg.set_strappcolumnname("value"); stMoCtrlPkg.set_strappcolumnname("value");
stMoCtrlPkg.set_strrtuname(stOptCtrlInfoAll.rtu_tag); stMoCtrlPkg.set_strrtuname(stOptCtrlInfoAll.rtu_tag);
stMoCtrlPkg.set_norder(atoi(stOptCtrlInfoAll.offset_no)); stMoCtrlPkg.set_norder(atoi(stOptCtrlInfoAll.offset_no));
stMoCtrlPkg.set_nvalue(stOptCtrlInfoAll.ctrl_act_type); /* 原来的逻辑nctrltype才是控制动作组转换后的值但是对应FES的逻辑此字段应该对应选择、控制、取消这些类型
stMoCtrlPkg.set_nctrltype(stOptCtrlInfoAll.ctrl_act_type); * set_nvalue设置控制值FES没有使用nctrltype字段set_nctrltype
*/
stMoCtrlPkg.set_nctrltype(stOptCtrlInfoAll.msg_type); //< 控制类型:选择、执行、取消
//stMoCtrlPkg.set_nvalue(static_cast<int>(stOptCtrlInfoAll.target_value)); //<target_value是HMI下发的目标值未经过控制动作组转换
stMoCtrlPkg.set_nvalue(stOptCtrlInfoAll.ctrl_act_type); //<
stMoCtrlPkg.set_niftagtstate(stOptCtrlInfoAll.is_tagt_state);//是否等待目标状态 stMoCtrlPkg.set_niftagtstate(stOptCtrlInfoAll.is_tagt_state);//是否等待目标状态
stMoCtrlPkg.SerializeToString(&strSendMessage); stMoCtrlPkg.SerializeToString(&strSendMessage);
@ -242,8 +248,8 @@ int COptCommand::sendAnaCtrlToFes(const SOptCtrlInfoAll &stOptCtrlInfoAll,const
stAoCtrlPkg.set_strappcolumnname("value"); stAoCtrlPkg.set_strappcolumnname("value");
stAoCtrlPkg.set_strrtuname(stOptCtrlInfoAll.rtu_tag); stAoCtrlPkg.set_strrtuname(stOptCtrlInfoAll.rtu_tag);
stAoCtrlPkg.set_norder(atoi(stOptCtrlInfoAll.offset_no)); stAoCtrlPkg.set_norder(atoi(stOptCtrlInfoAll.offset_no));
stAoCtrlPkg.set_fvalue(stOptCtrlInfoAll.target_value); stAoCtrlPkg.set_fvalue(static_cast<float>(stOptCtrlInfoAll.target_value));
stAoCtrlPkg.set_nctrltype(stOptCtrlInfoAll.ctrl_act_type); stAoCtrlPkg.set_nctrltype(stOptCtrlInfoAll.msg_type); //控制类型:选择、执行、取消
stAoCtrlPkg.set_niftagtstate(stOptCtrlInfoAll.is_tagt_state); stAoCtrlPkg.set_niftagtstate(stOptCtrlInfoAll.is_tagt_state);
stAoCtrlPkg.SerializeToString(&strSendMessage); stAoCtrlPkg.SerializeToString(&strSendMessage);
@ -280,6 +286,7 @@ int COptCommand::sendRequestToFes(
stFesCtrlReqPkg.set_norder(atoi(stOptCtrlInfoAll.offset_no)); stFesCtrlReqPkg.set_norder(atoi(stOptCtrlInfoAll.offset_no));
stFesCtrlReqPkg.set_naction(stOptCtrlInfoAll.ctrl_act_type); //动作值 stFesCtrlReqPkg.set_naction(stOptCtrlInfoAll.ctrl_act_type); //动作值
stFesCtrlReqPkg.set_niftagtstate(stOptCtrlInfoAll.is_tagt_state);//是否等待目标状态 stFesCtrlReqPkg.set_niftagtstate(stOptCtrlInfoAll.is_tagt_state);//是否等待目标状态
stFesCtrlReqPkg.set_nctrltype(stOptCtrlInfoAll.msg_type); //控制类型:选择、执行、取消
stFesCtrlReqPkg.SerializeToString(&strSendMessage); stFesCtrlReqPkg.SerializeToString(&strSendMessage);
int nRetCode = m_ptrNetMsgBus->sendToHost(stOptCtrlInfoAll.msg_type, int nRetCode = m_ptrNetMsgBus->sendToHost(stOptCtrlInfoAll.msg_type,
@ -462,6 +469,51 @@ int COptCommand::sendVirCtrlToApp(const SOptCtrlInfoAll &stOptCtrlInfoAll, const
return 0 ; return 0 ;
} }
int COptCommand::batchSendCtrlToFes(const std::vector<SOptCtrlInfoAll> &vecCtrlInfo, const string &strSrcTag)
{
//< 注意SOptCtrlInfoAll中变量赋值不全仅有FES中使用的
SFesCtrlRequestSeq vecReq;
// vecReq.mutable_do_seq()->Reserve(vecCtrlInfo.size()); //< 预先开辟空间
// vecReq.mutable_mo_seq()->Reserve(vecCtrlInfo.size());
vecReq.mutable_ao_seq()->Reserve( static_cast<int>(vecCtrlInfo.size()) );
for(size_t i = 0; i < vecCtrlInfo.size(); i++)
{
const SOptCtrlInfoAll &stInfo = vecCtrlInfo[i];
if(strcmp(stInfo.table_name,RT_ANA_TBL) == 0)
{
SFesAoRequestPkg *pAO = vecReq.add_ao_seq();
pAO->set_strsourcetag(strSrcTag);
pAO->set_strapptablename(stInfo.table_name);
pAO->set_strapptagname(stInfo.tag_name);
pAO->set_strappcolumnname("value");
pAO->set_strrtuname(stInfo.rtu_tag);
pAO->set_norder(atoi(stInfo.offset_no));
pAO->set_fvalue(static_cast<float>(stInfo.target_value));
pAO->set_nctrltype(stInfo.msg_type); //< 借用了ctrltype字段以使FES能够识别该命令
pAO->set_niftagtstate(stInfo.is_tagt_state);
}
}
string strSendMessage;
if(!vecReq.SerializeToString(&strSendMessage))
{
LOGERROR("batchSendCtrlToFes: SerializeToString error! ");
return -1;
}
int nRetCode = m_ptrNetMsgBus->sendToHost(MT_FES_BATCH_PNT_CMD,CH_OPT_TO_FES_CTRL_DOWN,strSendMessage);
if (nRetCode <= 0)
{
LOGERROR("batchSendCtrlToFes, ret_code(%d),sendToHost error!",nRetCode);
return -1;
}
LOGTRACE( "batchSendCtrlToFes do_size=%d mo_size=%d ao_size=%d success",
vecReq.do_seq_size(),vecReq.mo_seq_size(),vecReq.ao_seq_size());
return 0;
}
//发送报警信息给alarm_server //发送报警信息给alarm_server
int COptCommand::sendAlarm() int COptCommand::sendAlarm()
{ {

View File

@ -56,6 +56,9 @@ public:
int sendRequestToFes(const SOptCtrlInfoAll &stOptCtrlInfo, const string &strSrcTag); //数据请求 int sendRequestToFes(const SOptCtrlInfoAll &stOptCtrlInfo, const string &strSrcTag); //数据请求
int sendVirCtrlToApp(const SOptCtrlInfoAll &stOptCtrlInfoAll, const iot_idl::SVariable &varValue); int sendVirCtrlToApp(const SOptCtrlInfoAll &stOptCtrlInfoAll, const iot_idl::SVariable &varValue);
//< 批量发送控制命令到FES,暂时仅处理了AO
int batchSendCtrlToFes(const std::vector<SOptCtrlInfoAll> &vecCtrlInfo, const string &strSrcTag);
/*发送给HMI控制面板的反馈*/ /*发送给HMI控制面板的反馈*/
void initUpOptPanel(SOptCtrlReply &stOptCtrlReply, const string strSourceTag,int nAppID,int nDomainID,\ void initUpOptPanel(SOptCtrlReply &stOptCtrlReply, const string strSourceTag,int nAppID,int nDomainID,\
const string strHostName,const string strstrInstName,const string strKeyIdTag,\ const string strHostName,const string strstrInstName,const string strKeyIdTag,\

View File

@ -8,6 +8,8 @@
#include "operate_server_api/JsonOptCommand.h" #include "operate_server_api/JsonOptCommand.h"
#include "pub_utility_api/I18N.h" #include "pub_utility_api/I18N.h"
#include <cfloat> #include <cfloat>
#include "boost/unordered_map.hpp"
#include <set>
using namespace iot_service; using namespace iot_service;
using namespace iot_idl; using namespace iot_idl;
@ -460,6 +462,7 @@ int COperateServerClass::getPointCtrlInfo(const std::string &strTableName,const
stCtrlInfo.ctrl_timeout = stDigCtrlAll.ctrl_timeout; stCtrlInfo.ctrl_timeout = stDigCtrlAll.ctrl_timeout;
stCtrlInfo.is_tagt_state = stDigCtrlAll.is_tagt_state; stCtrlInfo.is_tagt_state = stDigCtrlAll.is_tagt_state;
stCtrlInfo.resv_timeout = stDigCtrlAll.resv_timeout; stCtrlInfo.resv_timeout = stDigCtrlAll.resv_timeout;
strncpy(stCtrlInfo.rtu_tag,stDigCtrlAll.rtu_tag, sizeof(stCtrlInfo.rtu_tag)); //获取RTU_TAG
vecCtrlOffsetNo.push_back((stDigCtrlAll.offset_no1)); vecCtrlOffsetNo.push_back((stDigCtrlAll.offset_no1));
vecCtrlOffsetNo.push_back((stDigCtrlAll.offset_no2)); vecCtrlOffsetNo.push_back((stDigCtrlAll.offset_no2));
@ -511,7 +514,9 @@ int COperateServerClass::getPointCtrlInfo(const std::string &strTableName,const
stCtrlInfo.ctrl_timeout = stOptMixCtrlAll.ctrl_timeout; stCtrlInfo.ctrl_timeout = stOptMixCtrlAll.ctrl_timeout;
stCtrlInfo.is_tagt_state = stOptMixCtrlAll.is_tagt_state; stCtrlInfo.is_tagt_state = stOptMixCtrlAll.is_tagt_state;
stCtrlInfo.resv_timeout = stOptMixCtrlAll.resv_timeout; stCtrlInfo.resv_timeout = stOptMixCtrlAll.resv_timeout;
strncpy(stCtrlInfo.rtu_tag,stOptMixCtrlAll.rtu_tag, sizeof(stCtrlInfo.rtu_tag)); //获取RTU_TAG
strncpy(stCtrlInfo.offset_no,stOptMixCtrlAll.offset_no, 48); strncpy(stCtrlInfo.offset_no,stOptMixCtrlAll.offset_no, 48);
for (int i = 0; i <5; ++i) for (int i = 0; i <5; ++i)
{ {
vecCtrlOffsetNo.push_back((stOptMixCtrlAll.offset_no)); vecCtrlOffsetNo.push_back((stOptMixCtrlAll.offset_no));
@ -561,6 +566,7 @@ int COperateServerClass::getPointCtrlInfo(const std::string &strTableName,const
//获得控制动作组参数 //获得控制动作组参数
//================================================================================================ //================================================================================================
stCtrlInfo.stCtrlActInfo.action_allow = true; stCtrlInfo.stCtrlActInfo.action_allow = true;
strncpy(stCtrlInfo.rtu_tag,stOptAnaCtrlAll.rtu_tag, sizeof(stCtrlInfo.rtu_tag)); //获取RTU_TAG
strncpy(stCtrlInfo.offset_no,stOptAnaCtrlAll.offset_no, 48); strncpy(stCtrlInfo.offset_no,stOptAnaCtrlAll.offset_no, 48);
return 1; return 1;
} }
@ -727,23 +733,23 @@ int COperateServerClass::checkCtrlRequest(SOptCtrlInfoAll &stOptCtrlInfo, const
//遥控请求 //遥控请求
int COperateServerClass::optCtrlRequest(const string &strJson, string &strResult) int COperateServerClass::optCtrlRequest(const string &strJson, string &strResult)
{ {
int nRetCode = -1 ;
//JSON解码到结构体 //JSON解码到结构体
//================================================================================================= //=================================================================================================
COptCtrlRequest objCtrlRequest;
SOptCtrlRequest stCtrlRequest; SOptCtrlRequest stCtrlRequest;
SOptCtrlInfoAll stOptCtrlInfo; int nRetCode = COptCtrlRequest::parse(strJson, stCtrlRequest);
nRetCode = objCtrlRequest.parse(strJson, stCtrlRequest);
if ( nRetCode <= 0) if ( nRetCode <= 0)
{ {
LOGWARN("OptCtrlRequest, GetJsonHead() error!"); LOGWARN("OptCtrlRequest, GetJsonHead() error!");
return -1; return -1;
} }
return optCtrlRequest(stCtrlRequest,strResult);
}
int COperateServerClass::optCtrlRequest(const SOptCtrlRequest &stCtrlRequest, string &strResult)
{
//初始化控制请求信息到结构体 //初始化控制请求信息到结构体
//================================================================================================= SOptCtrlInfoAll stOptCtrlInfo;
stOptCtrlInfo.src_domain = stCtrlRequest.stHead.nSrcDomainID; stOptCtrlInfo.src_domain = stCtrlRequest.stHead.nSrcDomainID;
stOptCtrlInfo.domain_id = stCtrlRequest.stHead.nDstDomainID; stOptCtrlInfo.domain_id = stCtrlRequest.stHead.nDstDomainID;
strcpy(stOptCtrlInfo.host_name, stCtrlRequest.stHead.strHostName.c_str()); strcpy(stOptCtrlInfo.host_name, stCtrlRequest.stHead.strHostName.c_str());
@ -753,10 +759,8 @@ int COperateServerClass::optCtrlRequest(const string &strJson, string &strResult
stOptCtrlInfo.opt_time = stCtrlRequest.stHead.nOptTime; stOptCtrlInfo.opt_time = stCtrlRequest.stHead.nOptTime;
string strSrcTag = stCtrlRequest.stHead.strSrcTag; string strSrcTag = stCtrlRequest.stHead.strSrcTag;
for (size_t nLoop = 0; nLoop != stCtrlRequest.vecOptCtrlQueue.size(); ++nLoop) for (size_t nLoop = 0; nLoop < stCtrlRequest.vecOptCtrlQueue.size(); ++nLoop)
{ {
string strRequest="" ;
string strKeyIdTag = stCtrlRequest.vecOptCtrlQueue[nLoop].strKeyIdTag ; string strKeyIdTag = stCtrlRequest.vecOptCtrlQueue[nLoop].strKeyIdTag ;
bool bIsDeviceOccupy = stCtrlRequest.vecOptCtrlQueue[nLoop].bIsDeviceOccupy; //是否设备占用 bool bIsDeviceOccupy = stCtrlRequest.vecOptCtrlQueue[nLoop].bIsDeviceOccupy; //是否设备占用
bool bCheckInterLock = stCtrlRequest.vecOptCtrlQueue[nLoop].bCheckInterLock; //是否检查闭锁 bool bCheckInterLock = stCtrlRequest.vecOptCtrlQueue[nLoop].bCheckInterLock; //是否检查闭锁
@ -766,8 +770,9 @@ int COperateServerClass::optCtrlRequest(const string &strJson, string &strResult
strKeyIdTag.c_str(), bIsDeviceOccupy, bCheckInterLock); strKeyIdTag.c_str(), bIsDeviceOccupy, bCheckInterLock);
//遥控请求;判断闭锁等;设备占用 //遥控请求;判断闭锁等;设备占用
//================================================================================================= //===========================================================
nRetCode = checkCtrlRequest(stOptCtrlInfo, strKeyIdTag,dTargValue, string strRequest="" ;
int nRetCode = checkCtrlRequest(stOptCtrlInfo, strKeyIdTag,dTargValue,
bIsDeviceOccupy,bCheckInterLock,strRequest); bIsDeviceOccupy,bCheckInterLock,strRequest);
if (nRetCode < 0 ) if (nRetCode < 0 )
{ {
@ -799,8 +804,7 @@ int COperateServerClass::optCtrlRequest(const string &strJson, string &strResult
stOptCtrlReply.stHead.strResultStr = strResult ; stOptCtrlReply.stHead.strResultStr = strResult ;
stOptCtrlReply.stHead.nOptTime = stCtrlRequest.stHead.nOptTime ; stOptCtrlReply.stHead.nOptTime = stCtrlRequest.stHead.nOptTime ;
COptCtrlReply objOptCtrlReply; string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
if(strJson.size()<=1) if(strJson.size()<=1)
{ {
LOGWARN("COperateServerClass::OptCtrlRequest(),json 命令编码失败! \n"); LOGWARN("COperateServerClass::OptCtrlRequest(),json 命令编码失败! \n");
@ -812,6 +816,7 @@ int COperateServerClass::optCtrlRequest(const string &strJson, string &strResult
return nRetCode; return nRetCode;
} }
} }
return 0; return 0;
} }
@ -1091,23 +1096,24 @@ int COperateServerClass::sendCancelCtrl (SOptCtrlInfoAll &stOptCtrlInfoAll,cons
//遥控选择 //遥控选择
int COperateServerClass::optCtrlSelect(const string &strJson) int COperateServerClass::optCtrlSelect(const string &strJson)
{ {
string strResult="";
string strCtrlResult="";
COptCtrlRequest objOptCtrlSelect;
SOptCtrlRequest stOptCtrlSelect; SOptCtrlRequest stOptCtrlSelect;
int nRetCode = COptCtrlRequest::parse(strJson,stOptCtrlSelect);
int nRetCode = objOptCtrlSelect.parse(strJson,stOptCtrlSelect);
if ( nRetCode <= 0) if ( nRetCode <= 0)
{ {
LOGWARN("OptCtrlSelect, GetJsonHead() error!"); LOGWARN("OptCtrlSelect, GetJsonHead() error!");
return -1; return -1;
} }
return optCtrlSelect(stOptCtrlSelect);
}
int COperateServerClass::optCtrlSelect(const SOptCtrlRequest &stOptCtrlSelect)
{
string strResult="";
string strCtrlResult="";
string strSourceTagSend = stOptCtrlSelect.stHead.strSrcTag + "#" + m_strSrcTagLocal + ":OptCtrlSelect"; string strSourceTagSend = stOptCtrlSelect.stHead.strSrcTag + "#" + m_strSrcTagLocal + ":OptCtrlSelect";
SOptCtrlInfoAll stOptCtrlInfoAll; SOptCtrlInfoAll stOptCtrlInfoAll;
stOptCtrlInfoAll.src_domain = stOptCtrlSelect.stHead.nSrcDomainID; stOptCtrlInfoAll.src_domain = stOptCtrlSelect.stHead.nSrcDomainID;
stOptCtrlInfoAll.domain_id = stOptCtrlSelect.stHead.nDstDomainID; stOptCtrlInfoAll.domain_id = stOptCtrlSelect.stHead.nDstDomainID;
strcpy(stOptCtrlInfoAll.host_name, stOptCtrlSelect.stHead.strHostName.c_str()); strcpy(stOptCtrlInfoAll.host_name, stOptCtrlSelect.stHead.strHostName.c_str());
@ -1117,7 +1123,7 @@ int COperateServerClass::optCtrlSelect(const string &strJson)
stOptCtrlInfoAll.opt_time = stOptCtrlSelect.stHead.nOptTime; stOptCtrlInfoAll.opt_time = stOptCtrlSelect.stHead.nOptTime;
string strKeyIdTag; string strKeyIdTag;
int nFlag = (0); //1:获取控制参数出错 2:设备控制保留 3:发送给FES失败或者控制信息表中插入记录失败 4工程配置错误 int nFlag = 0; //1:获取控制参数出错 2:设备控制保留 3:发送给FES失败或者控制信息表中插入记录失败 4工程配置错误
bool bIsCalculate = false ;//是否计算量 bool bIsCalculate = false ;//是否计算量
SOptValueStatus stCurValueStatus, stNewValueStatus; SOptValueStatus stCurValueStatus, stNewValueStatus;
@ -1239,8 +1245,7 @@ int COperateServerClass::optCtrlSelect(const string &strJson)
stOptCtrlReply.stHead.nOptTime = stOptCtrlInfoAll.opt_time ; stOptCtrlReply.stHead.nOptTime = stOptCtrlInfoAll.opt_time ;
stOptCtrlReply.stHead.strResultStr = strCtrlResult ; stOptCtrlReply.stHead.strResultStr = strCtrlResult ;
COptCtrlReply objOptCtrlReply; string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
if(strJson.size()<=1) if(strJson.size()<=1)
{ {
LOGWARN("OptCtrlSelect(),json 命令编码失败! \n"); LOGWARN("OptCtrlSelect(),json 命令编码失败! \n");
@ -1384,8 +1389,7 @@ int COperateServerClass::optVirtCtrlExeReply(const iot_idl::SOptVirtCtrlReply st
stOptCtrlReply.stHead.strResultStr = I18N("遥控执行成功"); stOptCtrlReply.stHead.strResultStr = I18N("遥控执行成功");
} }
COptCtrlReply objOptCtrlReply; string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
if(strJson.size()<=1) if(strJson.size()<=1)
{ {
LOGWARN("optVirtCtrlExeReply(),json 命令编码失败! \n"); LOGWARN("optVirtCtrlExeReply(),json 命令编码失败! \n");
@ -1538,8 +1542,7 @@ int COperateServerClass::optVirtCtrlSelReply(const iot_idl::SOptVirtCtrlReply st
stOptCtrlReply.stHead.strResultStr = I18N("遥控执行成功"); stOptCtrlReply.stHead.strResultStr = I18N("遥控执行成功");
} }
COptCtrlReply objOptCtrlReply; string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
if(strJson.size()<=1) if(strJson.size()<=1)
{ {
LOGWARN("optVirtCtrlSelReply(),json 命令编码失败! \n"); LOGWARN("optVirtCtrlSelReply(),json 命令编码失败! \n");
@ -1697,8 +1700,7 @@ int COperateServerClass::optCtrlSelectReply(const SFesCtrlReplyPkg &stReplyPkg)
stOptCtrlReply.stHead.strResultStr = strResult; stOptCtrlReply.stHead.strResultStr = strResult;
COptCtrlReply objOptCtrlReply; string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
if(strJson.size()<=1) if(strJson.size()<=1)
{ {
LOGWARN("COperateServerClass::OptCtrlSelectReply(),json 命令编码失败! \n"); LOGWARN("COperateServerClass::OptCtrlSelectReply(),json 命令编码失败! \n");
@ -1729,10 +1731,8 @@ int COperateServerClass::optCtrlClose(const string &strJson)
int nRetCode =-1; int nRetCode =-1;
string strResult=""; string strResult="";
COptCtrlRequest objOptCtrlClose;
SOptCtrlRequest stOptCtrlClose; SOptCtrlRequest stOptCtrlClose;
nRetCode = COptCtrlRequest::parse(strJson,stOptCtrlClose);
nRetCode = objOptCtrlClose.parse(strJson,stOptCtrlClose);
if ( nRetCode <= 0) if ( nRetCode <= 0)
{ {
LOGWARN("OptCtrlClose, GetJsonHead() error!"); LOGWARN("OptCtrlClose, GetJsonHead() error!");
@ -1801,9 +1801,8 @@ int COperateServerClass::optCtrlCustom(const string &strJson)
string strResultStr =""; string strResultStr ="";
string strResult=""; string strResult="";
COptCustCtrlRequest objOptCustCtrlRequest;
SOptCustCtrlRequest stOptCustCtrlRequest; SOptCustCtrlRequest stOptCustCtrlRequest;
nRetCode = objOptCustCtrlRequest.parse(strJson,stOptCustCtrlRequest); nRetCode = COptCustCtrlRequest::parse(strJson,stOptCustCtrlRequest);
if ( nRetCode <= 0) if ( nRetCode <= 0)
{ {
LOGWARN("OptCtrlCustom, GetJsonHead() error!"); LOGWARN("OptCtrlCustom, GetJsonHead() error!");
@ -1922,8 +1921,7 @@ int COperateServerClass::optCtrlCustom(const string &strJson)
stOptCtrlReply.stHead.nIsSuccess = false ; stOptCtrlReply.stHead.nIsSuccess = false ;
stOptCtrlReply.stHead.strResultStr = strResultStr ; stOptCtrlReply.stHead.strResultStr = strResultStr ;
COptCustCtrlReply objOptCtrlReply; string strReplyJson = COptCustCtrlReply::generate(stOptCtrlReply) ;
string strReplyJson = objOptCtrlReply.generate(stOptCtrlReply) ;
if(strJson.size()<=1) if(strJson.size()<=1)
{ {
LOGWARN("OptCtrlCustom(),json 命令编码失败! \n"); LOGWARN("OptCtrlCustom(),json 命令编码失败! \n");
@ -2034,8 +2032,7 @@ int COperateServerClass::optCtrlCustomReply(const SFesCustCmdReplyPkg &stFesCust
//发送 SendUpOptPanel to Hmi //发送 SendUpOptPanel to Hmi
//================================================================================ //================================================================================
COptCustCtrlReply objOptCtrlReply; string strReplyJson = COptCustCtrlReply::generate(stOptCustCtrlReply) ;
string strReplyJson = objOptCtrlReply.generate(stOptCustCtrlReply) ;
if(strReplyJson.size()<=1) if(strReplyJson.size()<=1)
{ {
LOGWARN("OptCtrlCustCmdReply(),json 命令编码失败! \n"); LOGWARN("OptCtrlCustCmdReply(),json 命令编码失败! \n");
@ -2147,20 +2144,22 @@ int COperateServerClass::addSettingAlarm(const string &strKeyIdTag,const string
//DO遥控执行 //DO遥控执行
int COperateServerClass::optCtrlExecute(const string &strJson) int COperateServerClass::optCtrlExecute(const string &strJson)
{ {
int nRetCode =-1;
string strResult="";
string strCtrlResult ="";
COptCtrlRequest objOptDoCtrlExecute;
SOptCtrlRequest stOptDoCtrlExecute; SOptCtrlRequest stOptDoCtrlExecute;
int nRetCode = COptCtrlRequest::parse(strJson,stOptDoCtrlExecute);
nRetCode = objOptDoCtrlExecute.parse(strJson,stOptDoCtrlExecute);
if ( nRetCode <= 0) if ( nRetCode <= 0)
{ {
LOGWARN("OptCtrlExecute, GetJsonHead() error!"); LOGWARN("OptCtrlExecute, GetJsonHead() error!");
return -1; return -1;
} }
return optCtrlExecute(stOptDoCtrlExecute);
}
int COperateServerClass::optCtrlExecute(const SOptCtrlRequest &stOptDoCtrlExecute)
{
string strResult="";
string strCtrlResult ="";
string strSrcTag = stOptDoCtrlExecute.stHead.strSrcTag; string strSrcTag = stOptDoCtrlExecute.stHead.strSrcTag;
string strSourceTagSend = strSrcTag + "#" + m_strSrcTagLocal + ":OptCtrlExecute"; string strSourceTagSend = strSrcTag + "#" + m_strSrcTagLocal + ":OptCtrlExecute";
@ -2319,8 +2318,7 @@ int COperateServerClass::optCtrlExecute(const string &strJson)
stOptCtrlReply.stHead.strResultStr = I18N("遥控执行成功") ; stOptCtrlReply.stHead.strResultStr = I18N("遥控执行成功") ;
} }
COptCtrlReply objOptCtrlReply; string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
if(strJson.size()<=1) if(strJson.size()<=1)
{ {
LOGWARN("COperateServerClass::OptCtrlExecute(),json 命令编码失败! \n"); LOGWARN("COperateServerClass::OptCtrlExecute(),json 命令编码失败! \n");
@ -2527,8 +2525,7 @@ int COperateServerClass::optCtrlExecuteReply(const SFesCtrlReplyPkg &stReplyPkg)
stOptCtrlReply.stHead.strResultStr = I18N("遥控执行成功"); stOptCtrlReply.stHead.strResultStr = I18N("遥控执行成功");
} }
COptCtrlReply objOptCtrlReply; string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
if(strJson.size()<=1) if(strJson.size()<=1)
{ {
LOGWARN("COperateServerClass::OptCtrlExecuteReply(),json 命令编码失败! \n"); LOGWARN("COperateServerClass::OptCtrlExecuteReply(),json 命令编码失败! \n");
@ -2715,8 +2712,7 @@ int COperateServerClass::optCtrlCheckTargetVal()
m_ptrOptComand->initUpOptPanel(stOptCtrlReply,strSourceTagSend,m_stRunAppInfo.nAppId,stOptCtrlInfoAll.domain_id,\ m_ptrOptComand->initUpOptPanel(stOptCtrlReply,strSourceTagSend,m_stRunAppInfo.nAppId,stOptCtrlInfoAll.domain_id,\
stOptCtrlInfoAll.host_name,stOptCtrlInfoAll.instance_name,strKeyIdTag,strResult,true,stOptCtrlInfoAll.opt_time); stOptCtrlInfoAll.host_name,stOptCtrlInfoAll.instance_name,strKeyIdTag,strResult,true,stOptCtrlInfoAll.opt_time);
COptCtrlReply objOptCtrlReply; string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
if(strJson.size()<=1) if(strJson.size()<=1)
{ {
LOGWARN("COperateServerClass::OptCtrlCheckTargetVal(),json 命令编码失败! \n"); LOGWARN("COperateServerClass::OptCtrlCheckTargetVal(),json 命令编码失败! \n");
@ -2743,10 +2739,9 @@ int COperateServerClass::optCtrlCancel(const string &strJson)
{ {
int nFlag = (0); int nFlag = (0);
bool bIsCalculate = false; bool bIsCalculate = false;
COptCtrlRequest objOptCtrlCancel;
SOptCtrlRequest stOptCtrlCancel;
int nRetCode = objOptCtrlCancel.parse(strJson,stOptCtrlCancel); SOptCtrlRequest stOptCtrlCancel;
int nRetCode = COptCtrlRequest::parse(strJson,stOptCtrlCancel);
if ( nRetCode <= 0) if ( nRetCode <= 0)
{ {
LOGWARN("OptCtrlCancel, GetJsonHead() error!"); LOGWARN("OptCtrlCancel, GetJsonHead() error!");
@ -2844,8 +2839,7 @@ int COperateServerClass::optCtrlCancel(const string &strJson)
stOptCtrlCancel.stHead.strHostName, stOptCtrlCancel.stHead.strInstName,strKeyIdTag, stOptCtrlCancel.stHead.strHostName, stOptCtrlCancel.stHead.strInstName,strKeyIdTag,
strCtrlResult,false,stOptCtrlInfoAll.opt_time); strCtrlResult,false,stOptCtrlInfoAll.opt_time);
COptCtrlReply objOptCtrlReply; string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
if(strJson.size()<=1) if(strJson.size()<=1)
{ {
LOGWARN("OptCtrlCancel(),json 命令编码失败! \n"); LOGWARN("OptCtrlCancel(),json 命令编码失败! \n");
@ -2957,8 +2951,7 @@ int COperateServerClass::optCtrlCancelReply(const SFesCtrlReplyPkg &stReplyPkg)
stOptCtrlReply.stHead.strResultStr=I18N("遥控取消成功"); stOptCtrlReply.stHead.strResultStr=I18N("遥控取消成功");
} }
COptCtrlReply objOptCtrlReply; string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
if(strJson.size()<=1) if(strJson.size()<=1)
{ {
LOGWARN("COperateServerClass::OptCtrlCancelReply(),json 命令编码失败! \n"); LOGWARN("COperateServerClass::OptCtrlCancelReply(),json 命令编码失败! \n");
@ -3129,8 +3122,7 @@ int COperateServerClass::checkTimeOutCtrlRec()
m_ptrOptComand->initUpOptPanel(stOptCtrlReply,strSourceTagSend,m_stRunAppInfo.nAppId,vecOptCtrlInfoAll[i].domain_id,\ m_ptrOptComand->initUpOptPanel(stOptCtrlReply,strSourceTagSend,m_stRunAppInfo.nAppId,vecOptCtrlInfoAll[i].domain_id,\
vecOptCtrlInfoAll[i].host_name, vecOptCtrlInfoAll[i].instance_name,strKeyIdTag,strResult,false,vecOptCtrlInfoAll[i].opt_time); vecOptCtrlInfoAll[i].host_name, vecOptCtrlInfoAll[i].instance_name,strKeyIdTag,strResult,false,vecOptCtrlInfoAll[i].opt_time);
COptCtrlReply objOptCtrlReply; string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
if(strJson.size()<=1) if(strJson.size()<=1)
{ {
LOGWARN("COperateServerClass::CheckTimeOutCtrlRec(),json 命令编码失败! \n"); LOGWARN("COperateServerClass::CheckTimeOutCtrlRec(),json 命令编码失败! \n");
@ -3178,7 +3170,6 @@ int COperateServerClass::doOptAutoCtrl()
return 1; return 1;
} }
string strJson;
string strResult; string strResult;
for (m_itLinkageMapPos = m_mapLinkageInfo.begin(); m_itLinkageMapPos != m_mapLinkageInfo.end();) for (m_itLinkageMapPos = m_mapLinkageInfo.begin(); m_itLinkageMapPos != m_mapLinkageInfo.end();)
@ -3212,7 +3203,7 @@ int COperateServerClass::doOptAutoCtrl()
m_itLinkageMapPos->second.target_value, m_itLinkageMapPos->second.target_value,
m_itLinkageMapPos->second.source_tag.c_str()); m_itLinkageMapPos->second.source_tag.c_str());
} }
COptCtrlRequest objOptAutoCtrl;
SOptCtrlRequest stOptAutoCtrl; SOptCtrlRequest stOptAutoCtrl;
stOptAutoCtrl.stHead.strSrcTag = m_itLinkageMapPos->second.source_tag; //源标签(即发送端进程名) stOptAutoCtrl.stHead.strSrcTag = m_itLinkageMapPos->second.source_tag; //源标签(即发送端进程名)
@ -3240,10 +3231,9 @@ int COperateServerClass::doOptAutoCtrl()
stOptCtrlQueue.bCheckInterLock = m_itLinkageMapPos->second.is_interlock; //闭锁检查 stOptCtrlQueue.bCheckInterLock = m_itLinkageMapPos->second.is_interlock; //闭锁检查
stOptAutoCtrl.vecOptCtrlQueue.push_back(stOptCtrlQueue); stOptAutoCtrl.vecOptCtrlQueue.push_back(stOptCtrlQueue);
strJson = objOptAutoCtrl.generate(stOptAutoCtrl) ;
m_itLinkageMapPos->second.opt_step = LINKAGE_CTRL_REQUEST; m_itLinkageMapPos->second.opt_step = LINKAGE_CTRL_REQUEST;
nRetCode = optCtrlRequest(strJson, strResult); //自动控制遥控请求命令 nRetCode = optCtrlRequest(stOptAutoCtrl, strResult); //自动控制遥控请求命令
if (nRetCode < 0) if (nRetCode < 0)
{ {
bIsSendFeedback = true; bIsSendFeedback = true;
@ -3301,9 +3291,8 @@ int COperateServerClass::doOptAutoCtrl()
stOptCtrlQueue.bIsDeviceOccupy = false ; stOptCtrlQueue.bIsDeviceOccupy = false ;
stOptAutoCtrl.vecOptCtrlQueue.push_back(stOptCtrlQueue); stOptAutoCtrl.vecOptCtrlQueue.push_back(stOptCtrlQueue);
strJson = objOptAutoCtrl.generate(stOptAutoCtrl) ;
nRetCode = optCtrlSelect(strJson); nRetCode = optCtrlSelect(stOptAutoCtrl);
if (nRetCode < 0) if (nRetCode < 0)
{ {
bIsSendFeedback = true; bIsSendFeedback = true;
@ -3355,9 +3344,8 @@ int COperateServerClass::doOptAutoCtrl()
stOptCtrlQueue.bIsDeviceOccupy = false ; stOptCtrlQueue.bIsDeviceOccupy = false ;
stOptAutoCtrl.vecOptCtrlQueue.push_back(stOptCtrlQueue); stOptAutoCtrl.vecOptCtrlQueue.push_back(stOptCtrlQueue);
strJson = objOptAutoCtrl.generate(stOptAutoCtrl) ;
nRetCode = optCtrlExecute(strJson); nRetCode = optCtrlExecute(stOptAutoCtrl);
if (nRetCode == -1) if (nRetCode == -1)
{ {
bIsSendFeedback = true; bIsSendFeedback = true;
@ -3513,8 +3501,7 @@ int COperateServerClass::doOptAutoCtrl()
stOptCtrlReply.stHead.strResultStr+= m_itLinkageMapPos->second.ctrl_result; //FES控制返回结果 stOptCtrlReply.stHead.strResultStr+= m_itLinkageMapPos->second.ctrl_result; //FES控制返回结果
stOptCtrlReply.stHead.nOptTime = m_itLinkageMapPos->second.opt_time ; stOptCtrlReply.stHead.nOptTime = m_itLinkageMapPos->second.opt_time ;
COptCtrlReply objOptCtrlReply; string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
if(strJson.size()<=1) if(strJson.size()<=1)
{ {
LOGWARN("COperateServerClass::OptCtrlSelectReply(),json 命令编码失败! \n"); LOGWARN("COperateServerClass::OptCtrlSelectReply(),json 命令编码失败! \n");
@ -3568,16 +3555,134 @@ int COperateServerClass::doOptAutoCtrl()
return 0; return 0;
} }
int COperateServerClass::optAutoCtrlWithoutResp(const string &strJson)
{
SOptCtrlRequest stReq;
int nRetCode = COptCtrlRequest::parse(strJson,stReq);
if ( nRetCode <= 0)
{
LOGWARN("optAutoCtrlWithoutResp, parse json error!");
return -1;
}
for(size_t nTag = 0; nTag < stReq.vecOptCtrlQueue.size(); nTag++)
{
const SOptCtrlReqQueue &stCtrl = stReq.vecOptCtrlQueue[nTag];
auto iterCtrl = m_mapCtrlWithoutResp.find(stCtrl.strKeyIdTag);
if(iterCtrl != m_mapCtrlWithoutResp.end())
{
LOGINFO("测点[%s]已经存在控制值[%lf],忽略旧值,采用新控制值[%lf]",stCtrl.strKeyIdTag.c_str(),
iterCtrl->second.dTargetValue,stCtrl.dTargetValue);
iterCtrl->second = stCtrl; //< 覆盖掉老控制命令
}
else
{
m_mapCtrlWithoutResp[stCtrl.strKeyIdTag] = stCtrl;
}
}
return 0;
}
/**********************************************
*
* 1
* 2
* 3
* 4AO控制
**********************************************/
int COperateServerClass::doOptAutoCtrlWithoutResp()
{
if(m_mapCtrlWithoutResp.empty())
{
return 0;
}
std::set<string> setInhibitCtrlDev;
getInhibitCtrlDevList(setInhibitCtrlDev); //获取禁止控制的设备列表
std::vector<SOptCtrlInfoAll> vecCtrlInfo;
vecCtrlInfo.reserve(m_mapCtrlWithoutResp.size());
for(auto iter = m_mapCtrlWithoutResp.begin(); iter != m_mapCtrlWithoutResp.end(); iter++)
{
const SOptCtrlReqQueue &stCtrl = iter->second;
string strTableName,strTagName,strColumnName,strDevTag,strPntTag;
if (splitKeyidTag(stCtrl.strKeyIdTag, strTableName, strTagName, strColumnName) < 0)
{
LOGWARN( "doOptAutoCtrlWithoutResp:SplitKeyidTag error! strKeyIdTag = %s",stCtrl.strKeyIdTag.c_str());
continue;
}
if(strTableName != RT_ANA_TBL) //< 暂时仅处理AO控制
{
LOGWARN( "doOptAutoCtrlWithoutResp:仅支持AO控制. strKeyIdTag = %s",stCtrl.strKeyIdTag.c_str());
continue;
}
if(splitTagname(strTagName,strDevTag,strPntTag) < 0)
{
LOGWARN( "doOptAutoCtrlWithoutResp:splitTagname error! strKeyIdTag = %s",stCtrl.strKeyIdTag.c_str());
continue;
}
if(setInhibitCtrlDev.count(strDevTag)) //< 禁止控制,跳过
{
LOGINFO("doOptAutoCtrlWithoutResp: 设备[%s]禁止控制,跳过",strDevTag.c_str());
continue;
}
SPointCtrlInfo stPntCtrlInfo;
string strGetPntCtrlInfoResult;
if(getPointCtrlInfo(strTableName,strTagName,0,stPntCtrlInfo,strGetPntCtrlInfoResult) < 0)
{
LOGWARN("doOptAutoCtrlWithoutResp:获取测点[%s]控制参数失败",stCtrl.strKeyIdTag.c_str());
continue;
}
//< 注意此处暂时只赋值了发送给FES需要的属性其它未赋值!
SOptCtrlInfoAll stCtrlInfo;
strTableName.copy(stCtrlInfo.table_name,sizeof(stCtrlInfo.table_name) - 1); //< 减一的目的是保证最后一个字符为0
strTagName.copy(stCtrlInfo.tag_name,sizeof(stCtrlInfo.tag_name)); //< 减一的目的是保证最后一个字符为0
strncpy(stCtrlInfo.rtu_tag,stPntCtrlInfo.rtu_tag, sizeof(stCtrlInfo.rtu_tag));
strncpy(stCtrlInfo.offset_no,stPntCtrlInfo.offset_no, sizeof(stCtrlInfo.offset_no));
stCtrlInfo.target_value = stCtrl.dTargetValue; //< 没有处理基值和K值与原有的OPT逻辑保持一致
stCtrlInfo.ctrl_act_type = 0; //< DO和MO经过控制动作组转换的对FES的控制值对AO没有用
stCtrlInfo.is_tagt_state = CTRL_TYPE_NWAIT_ACK; //< 不能用测点上配置的本指令因定时发送故不等待反馈0:不等待返信 1:等待返信 2:不等遥控确认
stCtrlInfo.msg_type = MT_FES_AO_EXECUTE; //< 暂时仅支持AO所以直接写死
vecCtrlInfo.push_back(stCtrlInfo);
}
if(vecCtrlInfo.empty())
{
return 0;
}
string strSourceTagSend = m_strSrcTagLocal + ":BatchOptCtrlExec";
int nRetCode = m_ptrOptComand->batchSendCtrlToFes(vecCtrlInfo,strSourceTagSend); //< 内部暂时仅处理的AO
if(nRetCode < 0)
{
LOGWARN("doOptAutoCtrlWithoutResp,批量发送控制命令失败!");
return nRetCode;
}
return 0;
}
//联动/顺控,直控/外部权限移交、标志牌同步等自动控制处理 //联动/顺控,直控/外部权限移交、标志牌同步等自动控制处理
int COperateServerClass::optAutoCtrl(const string &strJson) int COperateServerClass::optAutoCtrl(const string &strJson)
{ {
int nRetCode =-1; int nRetCode =-1;
COptCtrlRequest objOptAutoCtrl;
SOptCtrlRequest stOptAutoCtrl; SOptCtrlRequest stOptAutoCtrl;
nRetCode = COptCtrlRequest::parse(strJson,stOptAutoCtrl);
nRetCode = objOptAutoCtrl.parse(strJson,stOptAutoCtrl);
if ( nRetCode <= 0) if ( nRetCode <= 0)
{ {
LOGWARN("OptAutoCtrl, GetJsonHead() error!"); LOGWARN("OptAutoCtrl, GetJsonHead() error!");
@ -3615,6 +3720,12 @@ int COperateServerClass::optAutoCtrl(const string &strJson)
//得到是否需要遥控选择 //得到是否需要遥控选择
//============================================================================================ //============================================================================================
if(nPointType == POINT_TYPE_ANA)
{
nCtrlType = CTRL_TYPE_DIRECTEXE; //模拟量直接控制
}
else
{
nRetCode = getCtrlTableName(strTableName,strCtrlTableName) ; nRetCode = getCtrlTableName(strTableName,strCtrlTableName) ;
strKeyTagName.resize(64); strKeyTagName.resize(64);
nRetCode = m_ptrRdbTableMng->getRecordOneColumnByKey(strCtrlTableName, strKeyTagName.c_str(), "ctrl_type",nCtrlType); nRetCode = m_ptrRdbTableMng->getRecordOneColumnByKey(strCtrlTableName, strKeyTagName.c_str(), "ctrl_type",nCtrlType);
@ -3623,7 +3734,7 @@ int COperateServerClass::optAutoCtrl(const string &strJson)
LOGWARN("OptAutoCtrl, nRetCode = %d, strTableName = %s, strTagName = %s, getRecordOneColumnByKey(ctrl_type) error! ", LOGWARN("OptAutoCtrl, nRetCode = %d, strTableName = %s, strTagName = %s, getRecordOneColumnByKey(ctrl_type) error! ",
nRetCode, strTableName.c_str(), strTagName.c_str() ); nRetCode, strTableName.c_str(), strTagName.c_str() );
} }
if(nPointType == POINT_TYPE_ANA) nCtrlType = CTRL_TYPE_DIRECTEXE; //模拟量直接控制 }
//初始化自动控结构信息 //初始化自动控结构信息
//============================================================================================ //============================================================================================
@ -3828,6 +3939,16 @@ int COperateServerClass::getAnaCtrlValue(SOptCtrlInfoAll &stOptCtrlInfoAll )
return 1; return 1;
} }
int COperateServerClass::getInhibitCtrlDevList(std::set<string> &setDev)
{
std::set<std::string> setShieldDev;
getTokenDevWithInhibitCtrl(setDev);
getShieldDevWithInhibitCtrl(setShieldDev);
setDev.insert(setShieldDev.begin(),setShieldDev.end());
return 0;
}
//五防校验超时 //五防校验超时
int COperateServerClass::checkTimeOutCtrlPrev() int COperateServerClass::checkTimeOutCtrlPrev()

View File

@ -26,12 +26,11 @@ using namespace std;
int COperateServerClass::optInternHandover(const string &strJson) int COperateServerClass::optInternHandover(const string &strJson)
{ {
int nRetCode = 0; int nRetCode = 0;
CHandoverRequest objHandoverRequest;
SHandoverRequest stHandoverRequest; SHandoverRequest stHandoverRequest;
LOGINFO("OptInternHandover, json =%s !",strJson.c_str()); LOGINFO("OptInternHandover, json =%s !",strJson.c_str());
int bRetCode = objHandoverRequest.parse(strJson,stHandoverRequest) ; int bRetCode = CHandoverRequest::parse(strJson,stHandoverRequest) ;
if ( bRetCode == false) if ( bRetCode == false)
{ {
LOGWARN("OptInternHandover, objHandoverRequest.parse() error!"); LOGWARN("OptInternHandover, objHandoverRequest.parse() error!");
@ -605,8 +604,7 @@ int COperateServerClass::addOneInternHandoverReply(const SOptInternHandover &st
stHandoverReply.stHead.nIsSuccess = bIsSucess ; stHandoverReply.stHead.nIsSuccess = bIsSucess ;
stHandoverReply.stHead.strResultStr = strResultStr ; stHandoverReply.stHead.strResultStr = strResultStr ;
CHandoverReply objHandoverReply ; string strJson = CHandoverReply::generate(stHandoverReply) ;
string strJson = objHandoverReply.generate(stHandoverReply) ;
if(strJson.size()<=1) if(strJson.size()<=1)
{ {
LOGWARN("COperateServerClass::AddOneInternHandoverReply(),json 命令编码失败! \n"); LOGWARN("COperateServerClass::AddOneInternHandoverReply(),json 命令编码失败! \n");

View File

@ -97,7 +97,7 @@ void COptMainThread::processAppMessage(const iot_net::CMbMessage &recvMsg)
case MT_APP2OPT_VIRT_CTRL_MIX_REPLY: case MT_APP2OPT_VIRT_CTRL_MIX_REPLY:
{ {
iot_idl::SOptVirtCtrlReply objAppVirtCtrlReply; iot_idl::SOptVirtCtrlReply objAppVirtCtrlReply;
objAppVirtCtrlReply.ParseFromArray(recvMsg.getDataPtr(),recvMsg.getDataSize()); objAppVirtCtrlReply.ParseFromArray(recvMsg.getDataPtr(),static_cast<int>(recvMsg.getDataSize()) );
LOGDEBUG("processAppMessage, APP控制命令返回: tagName = %s, nResult = %d,strError = %s ", LOGDEBUG("processAppMessage, APP控制命令返回: tagName = %s, nResult = %d,strError = %s ",
objAppVirtCtrlReply.str_tag_name().c_str(),objAppVirtCtrlReply.n_ctrl_result(),objAppVirtCtrlReply.str_err().c_str()); objAppVirtCtrlReply.str_tag_name().c_str(),objAppVirtCtrlReply.n_ctrl_result(),objAppVirtCtrlReply.str_err().c_str());
m_ptrOperateServer->optVirtCtrlExeReply(objAppVirtCtrlReply); m_ptrOperateServer->optVirtCtrlExeReply(objAppVirtCtrlReply);
@ -130,7 +130,7 @@ void COptMainThread::processFesMessage(const iot_net::CMbMessage &recvMsg)
case MT_FES_DO_SELECT_REPLY: // 遥控选择返校 case MT_FES_DO_SELECT_REPLY: // 遥控选择返校
{ {
SFesCtrlReplyPkg objFesCtrlReplyPkg; SFesCtrlReplyPkg objFesCtrlReplyPkg;
objFesCtrlReplyPkg.ParseFromArray(recvMsg.getDataPtr(),recvMsg.getDataSize()); objFesCtrlReplyPkg.ParseFromArray(recvMsg.getDataPtr(),static_cast<int>(recvMsg.getDataSize()) );
LOGDEBUG("processAppMessage, fes遥控选择返回: tagName = %s, nResult = %d,strError = %s ", LOGDEBUG("processAppMessage, fes遥控选择返回: tagName = %s, nResult = %d,strError = %s ",
objFesCtrlReplyPkg.strapptagname().c_str(),objFesCtrlReplyPkg.nresult(),objFesCtrlReplyPkg.strpara().c_str()); objFesCtrlReplyPkg.strapptagname().c_str(),objFesCtrlReplyPkg.nresult(),objFesCtrlReplyPkg.strpara().c_str());
m_ptrOperateServer->optCtrlSelectReply(objFesCtrlReplyPkg); m_ptrOperateServer->optCtrlSelectReply(objFesCtrlReplyPkg);
@ -141,7 +141,7 @@ void COptMainThread::processFesMessage(const iot_net::CMbMessage &recvMsg)
case MT_FES_MO_EXECUTE_REPLY: case MT_FES_MO_EXECUTE_REPLY:
{ {
SFesCtrlReplyPkg objFesCtrlReplyPkg; SFesCtrlReplyPkg objFesCtrlReplyPkg;
objFesCtrlReplyPkg.ParseFromArray(recvMsg.getDataPtr(),recvMsg.getDataSize()); objFesCtrlReplyPkg.ParseFromArray(recvMsg.getDataPtr(),static_cast<int>(recvMsg.getDataSize()));
LOGDEBUG("processAppMessage, fes遥控执行返回: tagName = %s, nResult = %d,strError = %s ", LOGDEBUG("processAppMessage, fes遥控执行返回: tagName = %s, nResult = %d,strError = %s ",
objFesCtrlReplyPkg.strapptagname().c_str(),objFesCtrlReplyPkg.nresult(),objFesCtrlReplyPkg.strpara().c_str()); objFesCtrlReplyPkg.strapptagname().c_str(),objFesCtrlReplyPkg.nresult(),objFesCtrlReplyPkg.strpara().c_str());
m_ptrOperateServer->optCtrlExecuteReply(objFesCtrlReplyPkg); m_ptrOperateServer->optCtrlExecuteReply(objFesCtrlReplyPkg);
@ -150,7 +150,7 @@ void COptMainThread::processFesMessage(const iot_net::CMbMessage &recvMsg)
case MT_FES_DO_CANCEL_REPLY: //遥控撤销返校 case MT_FES_DO_CANCEL_REPLY: //遥控撤销返校
{ {
SFesCtrlReplyPkg objFesCtrlReplyPkg; SFesCtrlReplyPkg objFesCtrlReplyPkg;
objFesCtrlReplyPkg.ParseFromArray(recvMsg.getDataPtr(),recvMsg.getDataSize()); objFesCtrlReplyPkg.ParseFromArray(recvMsg.getDataPtr(),static_cast<int>(recvMsg.getDataSize()));
LOGDEBUG("processAppMessage, fes遥控撤销返回: tagName = %s, nResult = %d,strError = %s ", LOGDEBUG("processAppMessage, fes遥控撤销返回: tagName = %s, nResult = %d,strError = %s ",
objFesCtrlReplyPkg.strapptagname().c_str(),objFesCtrlReplyPkg.nresult(),objFesCtrlReplyPkg.strpara().c_str()); objFesCtrlReplyPkg.strapptagname().c_str(),objFesCtrlReplyPkg.nresult(),objFesCtrlReplyPkg.strpara().c_str());
m_ptrOperateServer->optCtrlCancelReply(objFesCtrlReplyPkg); m_ptrOperateServer->optCtrlCancelReply(objFesCtrlReplyPkg);
@ -159,7 +159,7 @@ void COptMainThread::processFesMessage(const iot_net::CMbMessage &recvMsg)
case MT_FES_DEFINE_CMD_REPLAY://自定义控制命令 case MT_FES_DEFINE_CMD_REPLAY://自定义控制命令
{ {
SFesCustCmdReplyPkg objFesCustCmdReplyPkg; SFesCustCmdReplyPkg objFesCustCmdReplyPkg;
objFesCustCmdReplyPkg.ParseFromArray(recvMsg.getDataPtr(),recvMsg.getDataSize()); objFesCustCmdReplyPkg.ParseFromArray(recvMsg.getDataPtr(),static_cast<int>(recvMsg.getDataSize()));
LOGDEBUG("processAppMessage, fes自定义控制命令返回: tagName = %s, nResult = %d,strError = %s ", LOGDEBUG("processAppMessage, fes自定义控制命令返回: tagName = %s, nResult = %d,strError = %s ",
objFesCustCmdReplyPkg.strapptagname().c_str(),objFesCustCmdReplyPkg.nresult(),objFesCustCmdReplyPkg.strretresult().c_str()); objFesCustCmdReplyPkg.strapptagname().c_str(),objFesCustCmdReplyPkg.nresult(),objFesCustCmdReplyPkg.strretresult().c_str());
m_ptrOperateServer->optCtrlCustomReply(objFesCustCmdReplyPkg); m_ptrOperateServer->optCtrlCustomReply(objFesCustCmdReplyPkg);
@ -168,13 +168,13 @@ void COptMainThread::processFesMessage(const iot_net::CMbMessage &recvMsg)
case MT_FES_VIRTUAL_CTRL: //前置发过来的虚拟控制 case MT_FES_VIRTUAL_CTRL: //前置发过来的虚拟控制
{ {
SFesChangeVirtualDataPkg objFesVirCtrlPkg; SFesChangeVirtualDataPkg objFesVirCtrlPkg;
objFesVirCtrlPkg.ParseFromArray(recvMsg.getDataPtr(),recvMsg.getDataSize()); objFesVirCtrlPkg.ParseFromArray(recvMsg.getDataPtr(),static_cast<int>(recvMsg.getDataSize()));
m_ptrOperateServer->optFesCtrlExecute(objFesVirCtrlPkg); m_ptrOperateServer->optFesCtrlExecute(objFesVirCtrlPkg);
break; break;
} }
default: default:
{ {
LOGINFO("processFesMessage, MsgType = %d, operate_server not support this message",nMessageType); LOGTRACE("processFesMessage, MsgType = %d, operate_server not support this message",nMessageType);
break; break;
} }
}// end switch }// end switch
@ -237,6 +237,11 @@ void COptMainThread::processHmiMessage(const iot_net::CMbMessage &recvMsg)
m_ptrOperateServer->optAutoCtrl(strMessage); m_ptrOperateServer->optAutoCtrl(strMessage);
break; break;
} }
case MT_OPT_AUTO_CTRL_WITHOUT_RESP: //无需等待反馈,主要用于功率控制的场景
{
m_ptrOperateServer->optAutoCtrlWithoutResp(strMessage);
break;
}
case MT_OPT_PINHIBIT_REF: //静止刷新 case MT_OPT_PINHIBIT_REF: //静止刷新
case MT_OPT_PINHIBIT_ALARM://静止报警 case MT_OPT_PINHIBIT_ALARM://静止报警
case MT_OPT_PINHIBIT_CTRL: //静止控制 case MT_OPT_PINHIBIT_CTRL: //静止控制
@ -354,6 +359,7 @@ void COptMainThread::execute()
//=============================================================================================== //===============================================================================================
//if (lCurTime - m_lLastAutoCtrlTime >= 10) //if (lCurTime - m_lLastAutoCtrlTime >= 10)
{ {
m_ptrOperateServer->doOptAutoCtrlWithoutResp(); //< 处理无需等待的缓存的控制命令
m_ptrOperateServer->doOptAutoCtrl(); //读自动控制Map 并执行 m_ptrOperateServer->doOptAutoCtrl(); //读自动控制Map 并执行
m_lLastAutoCtrlTime = lCurTime; m_lLastAutoCtrlTime = lCurTime;
} }

View File

@ -157,9 +157,8 @@ int COperateServerClass::optShieldSet(const string &strJson)
{ {
int nIsSet = 0 ; int nIsSet = 0 ;
SOptShieldSet stOptShieldSet; SOptShieldSet stOptShieldSet;
COptShieldSet objOptShieldSet;
bool bRetCode = objOptShieldSet.parse(strJson,stOptShieldSet) ; bool bRetCode = COptShieldSet::parse(strJson,stOptShieldSet) ;
if ( bRetCode == false) if ( bRetCode == false)
{ {
LOGWARN("OptShieldSet, GetJsonHead() error!"); LOGWARN("OptShieldSet, GetJsonHead() error!");
@ -330,8 +329,7 @@ int COperateServerClass::setShieldObjInfo(SOptShieldCfgInfo stShieldCfgInfo,SOpt
m_ptrOptComand->initUpOptPanel(stOptCtrlReply, stHead.strSrcTag, m_stRunAppInfo.nAppId, stHead.nSrcDomainID, \ m_ptrOptComand->initUpOptPanel(stOptCtrlReply, stHead.strSrcTag, m_stRunAppInfo.nAppId, stHead.nSrcDomainID, \
stHead.strHostName, stHead.strInstName, iterObj->key_id_tag, "屏蔽操作成功", true); stHead.strHostName, stHead.strInstName, iterObj->key_id_tag, "屏蔽操作成功", true);
COptCtrlReply objOptCtrlReply; string strJson = COptCtrlReply::generate(stOptCtrlReply);
string strJson = objOptCtrlReply.generate(stOptCtrlReply);
if (strJson.size() <= 1) if (strJson.size() <= 1)
{ {
LOGWARN("COperateServerClass::OptToken(),json 命令编码失败! \n"); LOGWARN("COperateServerClass::OptToken(),json 命令编码失败! \n");
@ -821,3 +819,10 @@ int COperateServerClass::initShieldStatus()
} }
return 1; return 1;
} }
int COperateServerClass::getShieldDevWithInhibitCtrl(std::set<string> &setDev)
{
boost::ignore_unused_variable_warning(setDev);
//LOGINFO("暂未实现获取禁止控制的设备屏蔽列表");
return 0;
}

View File

@ -59,9 +59,8 @@ bool COperateServerClass::checkIsOptTag(int &nIsSet,const string &strKeyIdTag,co
int COperateServerClass::optPointTag(const string &strJson) int COperateServerClass::optPointTag(const string &strJson)
{ {
SOptTagSet stOptTagSet; SOptTagSet stOptTagSet;
COptTagSet objOptTagSet;
int bRetCode = objOptTagSet.parse(strJson,stOptTagSet) ; int bRetCode = COptTagSet::parse(strJson,stOptTagSet) ;
if ( bRetCode == false) if ( bRetCode == false)
{ {
LOGWARN("OptPointTag, GetJsonHead() error!"); LOGWARN("OptPointTag, GetJsonHead() error!");
@ -229,8 +228,7 @@ int COperateServerClass::optPointTag(const string &strJson)
m_ptrOptComand->initUpOptPanel(stOptCtrlReply,strSrcTag,m_stRunAppInfo.nAppId,stOptTagSet.stHead.nSrcDomainID,\ m_ptrOptComand->initUpOptPanel(stOptCtrlReply,strSrcTag,m_stRunAppInfo.nAppId,stOptTagSet.stHead.nSrcDomainID,\
stOptTagSet.stHead.strHostName,stOptTagSet.stHead.strInstName ,stOptCtrlInfo.key_id_tag,I18N("点标签操作成功"),true); stOptTagSet.stHead.strHostName,stOptTagSet.stHead.strInstName ,stOptCtrlInfo.key_id_tag,I18N("点标签操作成功"),true);
COptCtrlReply objOptCtrlReply; string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
if(strJson.size()<=1) if(strJson.size()<=1)
{ {
LOGWARN("COperateServerClass::OptToken(),json 命令编码失败! \n"); LOGWARN("COperateServerClass::OptToken(),json 命令编码失败! \n");
@ -413,7 +411,6 @@ int COperateServerClass::updateTagInfo(const SOptCtrlInfoAll &stOptTagInfo,const
// update rdb // update rdb
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
/*
vector<iot_dbms::CONDINFO> vecCondInfo; vector<iot_dbms::CONDINFO> vecCondInfo;
CRdbPublic::addCondInfo(vecCondInfo,"tag_type", nTagType); CRdbPublic::addCondInfo(vecCondInfo,"tag_type", nTagType);
CRdbPublic::addCondInfo(vecCondInfo,"key_id_tag",stOptTagInfo.key_id_tag); CRdbPublic::addCondInfo(vecCondInfo,"key_id_tag",stOptTagInfo.key_id_tag);
@ -421,7 +418,7 @@ int COperateServerClass::updateTagInfo(const SOptCtrlInfoAll &stOptTagInfo,const
{ {
LOGERROR("UpdateTagInfo, table_name = %s, tag_type=%d,key_id_tag=%s,removeMultiCondition error!", LOGERROR("UpdateTagInfo, table_name = %s, tag_type=%d,key_id_tag=%s,removeMultiCondition error!",
RT_OPT_TAG_INFO,nTagType,stOptTagInfo.key_id_tag); RT_OPT_TAG_INFO,nTagType,stOptTagInfo.key_id_tag);
}*/ }
} }
else else
{ {
@ -446,7 +443,6 @@ int COperateServerClass::updateTagInfo(const SOptCtrlInfoAll &stOptTagInfo,const
// update rdb // update rdb
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
SOptTagInfoAll stTagInfo ; SOptTagInfoAll stTagInfo ;
strcpy(stTagInfo.key_id_tag,stOptTagInfo.key_id_tag) ; strcpy(stTagInfo.key_id_tag,stOptTagInfo.key_id_tag) ;
stTagInfo.tag_type =nTagType; stTagInfo.tag_type =nTagType;
@ -538,10 +534,9 @@ int COperateServerClass::optAiLimitSet(const string &strJson)
//JSON解码到结构体 //JSON解码到结构体
//=========================================================================================================== //===========================================================================================================
CAiLimitSet objAiLimitSet;
SAiLimitSet stAiLimitSet; SAiLimitSet stAiLimitSet;
bRetCode = objAiLimitSet.parse(strJson, stAiLimitSet); bRetCode = CAiLimitSet::parse(strJson, stAiLimitSet);
if ( bRetCode == false) if ( bRetCode == false)
{ {
LOGWARN("OptAiLimitSet, parse() error!"); LOGWARN("OptAiLimitSet, parse() error!");
@ -621,8 +616,7 @@ int COperateServerClass::optAiLimitSet(const string &strJson)
m_ptrOptComand->initUpOptPanel(stOptCtrlReply,strSourceTagSend,m_stRunAppInfo.nAppId,stOptCtrlInfo.domain_id,\ m_ptrOptComand->initUpOptPanel(stOptCtrlReply,strSourceTagSend,m_stRunAppInfo.nAppId,stOptCtrlInfo.domain_id,\
stAiLimitSet.stHead.strHostName,stAiLimitSet.stHead.strInstName,strkeyIdTag,strResult,nIsSucess); stAiLimitSet.stHead.strHostName,stAiLimitSet.stHead.strInstName,strkeyIdTag,strResult,nIsSucess);
COptCtrlReply objOptCtrlReply; string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
if(strJson.size()<=1) if(strJson.size()<=1)
{ {
LOGWARN("COperateServerClass::OptAiLimitSet(),json 命令编码失败! \n"); LOGWARN("COperateServerClass::OptAiLimitSet(),json 命令编码失败! \n");

View File

@ -322,10 +322,9 @@ int COperateServerClass::optToken(const string &strJson, const bool bIsSync /*=
int nRetCode =0 ; int nRetCode =0 ;
int nIsSet = OPT_TOKEN_SET; //默认挂牌操作 int nIsSet = OPT_TOKEN_SET; //默认挂牌操作
CTokenSet objOptTkokenSet;
STokenSet stOptTokenSet; STokenSet stOptTokenSet;
int bRetCode = objOptTkokenSet.parse(strJson,stOptTokenSet) ; int bRetCode = CTokenSet::parse(strJson,stOptTokenSet) ;
if ( bRetCode == false) if ( bRetCode == false)
{ {
LOGWARN("OptToken, objOptTkokenSet.parse() error!"); LOGWARN("OptToken, objOptTkokenSet.parse() error!");
@ -469,8 +468,7 @@ int COperateServerClass::optToken(const string &strJson, const bool bIsSync /*=
m_ptrOptComand->initUpOptPanel(stOptCtrlReply,strSourceTag,m_stRunAppInfo.nAppId,stOptTokenSet.stHead.nSrcDomainID,\ m_ptrOptComand->initUpOptPanel(stOptCtrlReply,strSourceTag,m_stRunAppInfo.nAppId,stOptTokenSet.stHead.nSrcDomainID,\
stOptTokenSet.stHead.strHostName,stOptTokenSet.stHead.strInstName ,stOptTokenInfo.key_id_tag,strResult,true); stOptTokenSet.stHead.strHostName,stOptTokenSet.stHead.strInstName ,stOptTokenInfo.key_id_tag,strResult,true);
COptCtrlReply objOptCtrlReply; string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
if(strJson.size()<=1) if(strJson.size()<=1)
{ {
LOGWARN("COperateServerClass::OptToken(),json 命令编码失败! \n"); LOGWARN("COperateServerClass::OptToken(),json 命令编码失败! \n");
@ -606,3 +604,55 @@ int COperateServerClass::optTokenAlarm(const STokenInfoAll &stOptTokenInfo, cons
return 0; return 0;
} }
int COperateServerClass::getTokenDevWithInhibitCtrl(std::set<string> &setDev)
{
//< 因为挂牌一般都比较少,所以直接遍历
int nTokenInfoCount = m_ptrRdbTableMng->getTableRecordCount(RT_OPT_TOKEN_INFO);
if(nTokenInfoCount <= 0)
{
return iotSuccess;
}
int nTokenDefCount = m_ptrRdbTableMng->getTableRecordCount(RT_OPT_TOKEN_DEF);
if(nTokenDefCount <= 0)
{
return iotSuccess;
}
//< 获取被设置禁止控制的挂牌ID
int nMask = 1 << STATE_DI_TOKEN_PROHIBIT;
set<int> setTokenID;
for(int nDefIndex = 0; nDefIndex < nTokenDefCount; nDefIndex++)
{
STokenDefine *pDef = (STokenDefine*)m_ptrRdbTableMng->getRecordAllColumnByIndex(RT_OPT_TOKEN_DEF,nDefIndex);
if(pDef == NULL)
{
LOGWARN("获取挂牌定义表记录失败");
continue;
}
if(pDef->token_prop & nMask)
{
setTokenID.insert(pDef->token_id);
}
}
//< 判断设备是否被禁止控制
for(int nInfo = 0; nInfo < nTokenInfoCount; nInfo++)
{
STokenInfoAll *pInfo = (STokenInfoAll*)m_ptrRdbTableMng->getRecordAllColumnByIndex(RT_OPT_TOKEN_INFO,nInfo);
if(pInfo == NULL)
{
LOGWARN("获取挂牌信息表记录失败");
continue;
}
if(setTokenID.count(pInfo->token_id)) //< 禁止控制
{
setDev.insert(pInfo->device);
}
}
return iotSuccess;
}

View File

@ -1607,11 +1607,48 @@ int CPermMngImpl::getAllUsergID(std::vector <SUsergIdName> &vecUsergID)
return PERM_NORMAL; return PERM_NORMAL;
} }
int CPermMngImpl::GetAllowDurationByUserId(const int &nPermId, int &nAllowDuration)
{
int ret = 0;
int permId;
permId = nPermId;
nAllowDuration = 0;
std::vector<SUserDef> mVecUserInfo;
ret = m_ptrRdbTableMng->selectAllColumnOneCondition(RT_RM_USER_DEF,mVecUserInfo,"perm_id",permId);
if (ret == false)
{
LOGERROR("CPermMngImpl::GetAllowDurationByUserId, ret = %d, m_RdbTable.ConGet(PERM_USER_DEF) error! userId = %d",
ret, permId);
return PERM_ERROR;
}
if (mVecUserInfo.size() == 0)
{
LOGERROR("CPermMngImpl::GetAllowDurationByUserId, 用户名id不存在!userId = %d",
permId);
return PERM_NO_NAME;
}
if (mVecUserInfo.size() > 1)
{
LOGERROR("CPermMngImpl::GetAllowDurationByUserId, 用户名id有重复!userId = %d",
permId);
return PERM_REDUP_NAME;
}
nAllowDuration = mVecUserInfo[0].allow_duration;
return PERM_NORMAL;
}
//以下为私有函数 //以下为私有函数
//写共享内存 //写共享内存
int CPermMngImpl::WritePermShm(const int nUserId, const int userg_id, const int64 os_uptime, int CPermMngImpl::WritePermShm(const int nUserId, const int userg_id, const int64 os_uptime,
const int64 login_time, const int login_sec, const char *instance_name) const int64 login_time, const int login_sec, const char *instance_name)
{ {
boost::ignore_unused_variable_warning(os_uptime);
m_spUserInfo->user_id = nUserId; m_spUserInfo->user_id = nUserId;
m_spUserInfo->userg_id = userg_id; m_spUserInfo->userg_id = userg_id;
//m_spUserInfo->os_uptime = os_uptime; //m_spUserInfo->os_uptime = os_uptime;
@ -1625,6 +1662,8 @@ int CPermMngImpl::WritePermShm(const int nUserId, const int userg_id, const int6
int CPermMngImpl::GetCurUserInfo(int &nUserId, int &userg_id, int64 &os_uptime, int64 &login_time, int CPermMngImpl::GetCurUserInfo(int &nUserId, int &userg_id, int64 &os_uptime, int64 &login_time,
int &login_sec, string &instance_name) int &login_sec, string &instance_name)
{ {
boost::ignore_unused_variable_warning(os_uptime);
nUserId = m_spUserInfo->user_id; nUserId = m_spUserInfo->user_id;
userg_id = m_spUserInfo->userg_id; userg_id = m_spUserInfo->userg_id;
//os_uptime = m_spUserInfo->os_uptime; //os_uptime = m_spUserInfo->os_uptime;

View File

@ -306,6 +306,12 @@ public:
*/ */
int getAllUsergID(std::vector <SUsergIdName> &vecUsergID) override; int getAllUsergID(std::vector <SUsergIdName> &vecUsergID) override;
/**
@brief ID号得到允许持续时间
@param [in/out] int & nPermId ID号
@param [in/out] int & nAllowDuration
*/
int GetAllowDurationByUserId(const int &nPermId,int &nAllowDuration) override;
private: private:
class CBioIdentify class CBioIdentify
{ {

View File

@ -61,6 +61,7 @@ void CSampleThreadImpl::execute()
//1.所有点存盘周期为固定5分钟 //1.所有点存盘周期为固定5分钟
//================================================================================================= //=================================================================================================
/* 暂时禁用掉
int mMin = m_lCurTime/(60000) ;//转换为分钟 int mMin = m_lCurTime/(60000) ;//转换为分钟
if ( (mMin % (SAMPLE_CYC_MIN) == 0) && (m_lCurTime/60000 - m_lLastTime/60000) >0 )//每5 min判一次 if ( (mMin % (SAMPLE_CYC_MIN) == 0) && (m_lCurTime/60000 - m_lLastTime/60000) >0 )//每5 min判一次
{ {
@ -68,6 +69,7 @@ void CSampleThreadImpl::execute()
saveAllPoint() ; saveAllPoint() ;
LOGDEBUG("CSampleThreadImpl::execute, saveAllPoint() Time=[%" PRId64 "] ", m_lCurTime); LOGDEBUG("CSampleThreadImpl::execute, saveAllPoint() Time=[%" PRId64 "] ", m_lCurTime);
} }
*/
//2.从消息缓存队列读取消息并处理 //2.从消息缓存队列读取消息并处理
//================================================================================================= //=================================================================================================
@ -498,7 +500,7 @@ void CSampleThreadImpl::saveAllCfgPoint()
int64 nTimeStamp = (getUTCTimeMsec()/(60*1000)) * 60000; //得到固定的分钟 int64 nTimeStamp = (getUTCTimeMsec()/(60*1000)) * 60000; //得到固定的分钟
if(nPeriod<=0) nPeriod = 1;// if(nPeriod<=0) nPeriod = 1;//
int mMin = m_lCurTime/(60*1000) ;//转换为分钟 int64 mMin = m_lCurTime/(60*1000) ;//转换为分钟
if( (mMin % nPeriod == 0)) if( (mMin % nPeriod == 0))
{ {
if(POINT_TYPE_ANA == nPointType) if(POINT_TYPE_ANA == nPointType)
@ -531,8 +533,9 @@ void CSampleThreadImpl::saveAllCfgPoint()
void CSampleThreadImpl::saveAllPoint() void CSampleThreadImpl::saveAllPoint()
{ {
int64 nTimeStamp = (getUTCTimeMsec()/(60*1000)) * 60000; //得到固定的分钟 int64 nTimeStamp = (getUTCTimeMsec()/(60*1000)) * 60000; //得到固定的分钟
LOCALTIME localTime = convertUTCMsecToLocalTime(nTimeStamp);
saveAllAnaPoint(nTimeStamp); saveAllAnaPoint(nTimeStamp,localTime.wMinute);
saveAllDigPoint(nTimeStamp); saveAllDigPoint(nTimeStamp);
@ -544,7 +547,7 @@ void CSampleThreadImpl::saveAllPoint()
} }
//模拟量周期存盘 //模拟量周期存盘
void CSampleThreadImpl::saveAllAnaPoint(const int64 nTimeStamp) void CSampleThreadImpl::saveAllAnaPoint(const int64 nTimeStamp,const int &minOfHour)
{ {
STssInsert stTsdbData; STssInsert stTsdbData;
stTsdbData.Clear(); stTsdbData.Clear();
@ -556,6 +559,13 @@ void CSampleThreadImpl::saveAllAnaPoint(const int64 nTimeStamp)
pAnaPoint = (SAnaPointAll*)m_ptrRdbTableMng->getRecordAllColumnByIndex(RT_ANA_TBL,nIndex); pAnaPoint = (SAnaPointAll*)m_ptrRdbTableMng->getRecordAllColumnByIndex(RT_ANA_TBL,nIndex);
if(NULL != pAnaPoint) if(NULL != pAnaPoint)
{ {
//caodingfa存盘周期不等于SAMPLE_CYC_MIN时按存盘周期定时存储可以是一个小时内的一个分钟数比如0、15、30、45
if((pAnaPoint->sample_period != SAMPLE_CYC_MIN) &&
(pAnaPoint->sample_period == 0 || minOfHour % pAnaPoint->sample_period != 0))
{
continue;
}
addOneTsdbData(stTsdbData, pAnaPoint->tag_name,pAnaPoint->status,pAnaPoint->value,nTimeStamp); addOneTsdbData(stTsdbData, pAnaPoint->tag_name,pAnaPoint->status,pAnaPoint->value,nTimeStamp);
} }
else else

View File

@ -50,7 +50,7 @@ private:
//全数据存盘 //全数据存盘
void saveAllCfgPoint(); //保存所有配置的点全数据 void saveAllCfgPoint(); //保存所有配置的点全数据
void saveAllPoint(); //存盘全数据 void saveAllPoint(); //存盘全数据
void saveAllAnaPoint(const int64 uTimeStamp); void saveAllAnaPoint(const int64 uTimeStamp,const int &minOfHour);
void saveAllDigPoint(const int64 uTimeStamp); void saveAllDigPoint(const int64 uTimeStamp);
void saveAllAccPoint(const int64 uTimeStamp); void saveAllAccPoint(const int64 uTimeStamp);
void saveAllMixPoint(const int64 uTimeStamp); void saveAllMixPoint(const int64 uTimeStamp);

View File

@ -35,7 +35,8 @@ LIBS += \
-lprotobuf \ -lprotobuf \
-ltsdb_save_api \ -ltsdb_save_api \
-llog4cplus\ -llog4cplus\
-lboost_chrono -lboost_chrono \
-lboost_date_time
include($$PWD/../../idl_files/idl_files.pri) include($$PWD/../../idl_files/idl_files.pri)

View File

@ -11,9 +11,9 @@ SUBDIRS+= interlock_api \
operate_server \ operate_server \
alarm_server \ alarm_server \
web_server \ web_server \
web_server_bi \ # web_server_bi \
alarm_system \ alarm_system \
iscs_wise_mnp \ # iscs_wise_mnp \
alarm_resource \ alarm_resource \
operate_server.depends = interlock_api perm_mng_api data_process_api operate_server.depends = interlock_api perm_mng_api data_process_api

View File

@ -47,6 +47,8 @@ oatpp::async::CoroutineStarter CAlmCntWsLsnr::onPing
oatpp::async::CoroutineStarter CAlmCntWsLsnr::onPong oatpp::async::CoroutineStarter CAlmCntWsLsnr::onPong
( const std::shared_ptr<AsyncWebSocket> &spSocket, const oatpp::String &strMsg ) ( const std::shared_ptr<AsyncWebSocket> &spSocket, const oatpp::String &strMsg )
{ {
boost::ignore_unused_variable_warning(spSocket);
LOGINFO( "onPong(): message='%s'", strMsg->c_str()); LOGINFO( "onPong(): message='%s'", strMsg->c_str());
assert( spSocket == m_spHolder->m_spSocket ); assert( spSocket == m_spHolder->m_spSocket );
@ -56,6 +58,8 @@ oatpp::async::CoroutineStarter CAlmCntWsLsnr::onPong
oatpp::async::CoroutineStarter CAlmCntWsLsnr::onClose oatpp::async::CoroutineStarter CAlmCntWsLsnr::onClose
( const std::shared_ptr<AsyncWebSocket> &spSocket, v_uint16 nCode, const oatpp::String &strMsg ) ( const std::shared_ptr<AsyncWebSocket> &spSocket, v_uint16 nCode, const oatpp::String &strMsg )
{ {
boost::ignore_unused_variable_warning(spSocket);
LOGINFO( "onClose(): code=%d message='%s'", nCode, strMsg->c_str()); LOGINFO( "onClose(): code=%d message='%s'", nCode, strMsg->c_str());
assert( spSocket == m_spHolder->m_spSocket ); assert( spSocket == m_spHolder->m_spSocket );
@ -68,6 +72,8 @@ oatpp::async::CoroutineStarter CAlmCntWsLsnr::onClose
oatpp::async::CoroutineStarter CAlmCntWsLsnr::readMessage oatpp::async::CoroutineStarter CAlmCntWsLsnr::readMessage
( const std::shared_ptr<AsyncWebSocket> &spSocket, v_uint8 nOpCode, p_char8 pData, oatpp::v_io_size nSize ) ( const std::shared_ptr<AsyncWebSocket> &spSocket, v_uint8 nOpCode, p_char8 pData, oatpp::v_io_size nSize )
{ {
boost::ignore_unused_variable_warning(spSocket);
assert( spSocket == m_spHolder->m_spSocket ); assert( spSocket == m_spHolder->m_spSocket );
if ( nSize > 0 ) if ( nSize > 0 )
@ -77,8 +83,7 @@ oatpp::async::CoroutineStarter CAlmCntWsLsnr::readMessage
else if ( nSize == 0 ) else if ( nSize == 0 )
{ //< size为0表示消息传送完毕 { //< size为0表示消息传送完毕
if ( (oatpp::websocket::Frame::OPCODE_TEXT != nOpCode) if ( oatpp::websocket::Frame::OPCODE_TEXT != nOpCode )
&& (oatpp::websocket::Frame::OPCODE_CONTINUATION != nOpCode) )
{ {
LOGERROR( "onMessage(): opcode=%d, not Text, 非预期!", nOpCode ); LOGERROR( "onMessage(): opcode=%d, not Text, 非预期!", nOpCode );
m_buffMsgRcv.reset(); m_buffMsgRcv.reset();
@ -197,7 +202,7 @@ void CAlmCntWsLsnr::sendMessage()
//< 预分配,提升性能 //< 预分配,提升性能
{ {
size_t nReserve = 1.6 * ( vecSpAllAlm.size() > 10000 ? vecSpAllAlm.size() : 10000 ); size_t nReserve = static_cast<size_t>(1.6 * ( vecSpAllAlm.size() > 10000 ? vecSpAllAlm.size() : 10000 ) );
m_objAlmTable.get<LiveAlm_Uuid>().reserve( nReserve ); m_objAlmTable.get<LiveAlm_Uuid>().reserve( nReserve );
} }

View File

@ -61,6 +61,8 @@ oatpp::async::CoroutineStarter CAlmWsLsnr::onPing
oatpp::async::CoroutineStarter CAlmWsLsnr::onPong oatpp::async::CoroutineStarter CAlmWsLsnr::onPong
( const std::shared_ptr<AsyncWebSocket> &spSocket, const oatpp::String &strMsg ) ( const std::shared_ptr<AsyncWebSocket> &spSocket, const oatpp::String &strMsg )
{ {
boost::ignore_unused_variable_warning(spSocket);
LOGINFO( "onPong(): message='%s'", strMsg->c_str()); LOGINFO( "onPong(): message='%s'", strMsg->c_str());
assert( spSocket == m_spHolder->m_spSocket ); assert( spSocket == m_spHolder->m_spSocket );
@ -70,6 +72,8 @@ oatpp::async::CoroutineStarter CAlmWsLsnr::onPong
oatpp::async::CoroutineStarter CAlmWsLsnr::onClose oatpp::async::CoroutineStarter CAlmWsLsnr::onClose
( const std::shared_ptr<AsyncWebSocket> &spSocket, v_uint16 nCode, const oatpp::String &strMsg ) ( const std::shared_ptr<AsyncWebSocket> &spSocket, v_uint16 nCode, const oatpp::String &strMsg )
{ {
boost::ignore_unused_variable_warning(spSocket);
LOGINFO( "onClose(): code=%d message='%s'", nCode, strMsg->c_str()); LOGINFO( "onClose(): code=%d message='%s'", nCode, strMsg->c_str());
assert( spSocket == m_spHolder->m_spSocket ); assert( spSocket == m_spHolder->m_spSocket );
@ -82,6 +86,8 @@ oatpp::async::CoroutineStarter CAlmWsLsnr::onClose
oatpp::async::CoroutineStarter CAlmWsLsnr::readMessage oatpp::async::CoroutineStarter CAlmWsLsnr::readMessage
( const std::shared_ptr<AsyncWebSocket> &spSocket, v_uint8 nOpCode, p_char8 pData, oatpp::v_io_size nSize ) ( const std::shared_ptr<AsyncWebSocket> &spSocket, v_uint8 nOpCode, p_char8 pData, oatpp::v_io_size nSize )
{ {
boost::ignore_unused_variable_warning(spSocket);
assert( spSocket == m_spHolder->m_spSocket ); assert( spSocket == m_spHolder->m_spSocket );
if ( nSize > 0 ) if ( nSize > 0 )
@ -91,8 +97,7 @@ oatpp::async::CoroutineStarter CAlmWsLsnr::readMessage
else if ( nSize == 0 ) else if ( nSize == 0 )
{ //< size为0表示消息传送完毕 { //< size为0表示消息传送完毕
if ( (oatpp::websocket::Frame::OPCODE_TEXT != nOpCode) if ( oatpp::websocket::Frame::OPCODE_TEXT != nOpCode )
&& (oatpp::websocket::Frame::OPCODE_CONTINUATION != nOpCode) )
{ {
LOGERROR( "onMessage(): opcode=%d, not Text, 非预期!", nOpCode ); LOGERROR( "onMessage(): opcode=%d, not Text, 非预期!", nOpCode );
m_buffMsgRcv.reset(); m_buffMsgRcv.reset();
@ -289,6 +294,28 @@ oatpp::async::CoroutineStarter CAlmWsLsnr::readMessage
} }
} }
//< keyIdTag
m_spHolder->m_setKeyIdTag.clear();
if ( spReq->keyIdTag != nullptr && !spReq->keyIdTag->empty())
{
strTemp = spReq->keyIdTag->c_str();
auto list = strTemp.split( ";" );
for ( auto &it:list )
{
// 转化后台测点格式
auto listTemp = it.split( "." );
if(listTemp.size() == 7)
{
listTemp.removeAt(0);
listTemp.removeAt(0);
it = listTemp.join(".");
}
if ( !it.isEmpty())
m_spHolder->m_setKeyIdTag.emplace( std::move( it.toStdString()));
}
}
//< type //< type
m_spHolder->m_setAlmType.clear(); m_spHolder->m_setAlmType.clear();
if ( !spReq->type->empty()) if ( !spReq->type->empty())
@ -507,10 +534,12 @@ void CAlmWsLsnr::sendMessage()
spRep->total = std::ceil( static_cast<double> ( spRep->records ) / spRep->pageSize ); spRep->total = std::ceil( static_cast<double> ( spRep->records ) / spRep->pageSize );
if ( spRep->total <= 0 ) spRep->total = 1; if ( spRep->total <= 0 ) spRep->total = 1;
//< 前流程已保证 m_spHolder->m_nPageNo 大于 0 //< 前流程已保证 m_spHolder->m_nPageNo 大于 0
spRep->data = oatpp::Vector<oatpp::Object<dto::CAlmRepData>>::createShared();
if(m_spHolder->m_nPageNo <= spRep->total)
{
spRep->pageNo = m_spHolder->m_nPageNo > spRep->total ? spRep->pageNo = m_spHolder->m_nPageNo > spRep->total ?
spRep->total.getValue( 0 ) : m_spHolder->m_nPageNo; spRep->total.getValue( 0 ) : m_spHolder->m_nPageNo;
spRep->data = oatpp::Vector<oatpp::Object<dto::CAlmRepData>>::createShared();
const int nBeginIdx = ( spRep->pageNo - 1 ) * spRep->pageSize; const int nBeginIdx = ( spRep->pageNo - 1 ) * spRep->pageSize;
//< 使用std::min或者std::max的时候加上括号避免与Windows.h中的min、max宏定义冲突 //< 使用std::min或者std::max的时候加上括号避免与Windows.h中的min、max宏定义冲突
const int nEndIdx = ( std::min )( nBeginIdx + spRep->pageSize, ( int ) m_pAlmTable->size()); const int nEndIdx = ( std::min )( nBeginIdx + spRep->pageSize, ( int ) m_pAlmTable->size());
@ -525,6 +554,7 @@ void CAlmWsLsnr::sendMessage()
auto spRepData = dto::CAlmRepData::createShared(); auto spRepData = dto::CAlmRepData::createShared();
spRepData->content = spAlm->getContent(); spRepData->content = spAlm->getContent();
spRepData->keyIdTag = oatpp::String( spAlm->getKeyIdTag());
spRepData->other = oatpp::Vector<oatpp::Any>::createShared(); spRepData->other = oatpp::Vector<oatpp::Any>::createShared();
const auto &spOther = spRepData->other; const auto &spOther = spRepData->other;
@ -533,7 +563,7 @@ void CAlmWsLsnr::sendMessage()
if ( 0 == m_spHolder->m_nEndPointType ) if ( 0 == m_spHolder->m_nEndPointType )
{//< 告警窗 {//< 告警窗
//< 前端按序号访问other需注意顺序不能乱示例如下 //< 前端按序号访问other需注意顺序不能乱示例如下
//< other: [136, "数字量变位", "状态变位", "未确认", 1643019095930, "EMS监控中心域", "EMS监控中心", "EMS监控", "高", "母线", "默认责任区"] //< other: [136, "数字量变位", "状态变位", "未确认", 1643019095930, "EMS监控中心域", "EMS监控中心", "EMS监控", "高", "母线", "默认责任区","itOTHopke3PTjYn2lUHxkk","digital.station1.G02-YB_jgxh.TX.value",5,1]
spOther->emplace_back( oatpp::String( spAlm->getAlmTypeDesc())); spOther->emplace_back( oatpp::String( spAlm->getAlmTypeDesc()));
spOther->emplace_back( oatpp::String( spAlm->getAlmStatusDesc())); spOther->emplace_back( oatpp::String( spAlm->getAlmStatusDesc()));
const char *szCfm = spAlm->isConfirmed() ? "已确认" : "未确认"; const char *szCfm = spAlm->isConfirmed() ? "已确认" : "未确认";
@ -545,6 +575,10 @@ void CAlmWsLsnr::sendMessage()
spOther->emplace_back( oatpp::String( spAlm->getPriorityDesc())); spOther->emplace_back( oatpp::String( spAlm->getPriorityDesc()));
spOther->emplace_back( oatpp::String( spAlm->getDevTypeDesc())); spOther->emplace_back( oatpp::String( spAlm->getDevTypeDesc()));
spOther->emplace_back( oatpp::String( spAlm->getRegionDesc())); spOther->emplace_back( oatpp::String( spAlm->getRegionDesc()));
spOther->emplace_back( oatpp::String( spAlm->getUuidBase64()));
spOther->emplace_back( oatpp::String( spAlm->getKeyIdTag()));
spOther->emplace_back( oatpp::Int64( spAlm->getAlmType()));
spOther->emplace_back( oatpp::Int64( spAlm->getAppId()));
} }
else else
{//< 事件窗 {//< 事件窗
@ -563,6 +597,8 @@ void CAlmWsLsnr::sendMessage()
spRep->data->emplace_back( std::move( spRepData )); spRep->data->emplace_back( std::move( spRepData ));
} }
}
} }
OATPP_COMPONENT( std::shared_ptr<oatpp::data::mapping::ObjectMapper>, spMapper ); OATPP_COMPONENT( std::shared_ptr<oatpp::data::mapping::ObjectMapper>, spMapper );

View File

@ -1,4 +1,4 @@

/********************************************************************************** /**********************************************************************************
* @file AlmWsLsnr.hpp * @file AlmWsLsnr.hpp
* @brief WebSocket的监听类 * @brief WebSocket的监听类
@ -105,9 +105,8 @@ private:
if ( 0 == m_nEndPointType ) if ( 0 == m_nEndPointType )
{//< 告警窗 {//< 告警窗
if (!m_setDevGroup.empty() && spAlm->hasDevGroupTag() && m_setDevGroup.count( spAlm->getDevGroupTag()) <= 0 ) if ( spAlm->hasDevGroupTag() && !m_setDevGroup.empty()&&m_setDevGroup.count( spAlm->getDevGroupTag()) <= 0 )
return 8; return 8;
} }
else else
{//< 事件窗 {//< 事件窗
@ -115,6 +114,9 @@ private:
return 9; return 9;
} }
if ( !m_setKeyIdTag.empty() && m_setKeyIdTag.count( spAlm->getKeyIdTag()) <= 0 )
return 10;
return 0; return 0;
} }
@ -128,6 +130,7 @@ private:
int64_t m_nStartTime{-1}; //< 小于等于0表示不过滤 int64_t m_nStartTime{-1}; //< 小于等于0表示不过滤
int64_t m_nEndTime{-1}; //< 小于等于0表示不过滤 int64_t m_nEndTime{-1}; //< 小于等于0表示不过滤
std::unordered_set<std::string> m_setDevGroup; std::unordered_set<std::string> m_setDevGroup;
std::unordered_set<std::string> m_setKeyIdTag;
std::unordered_set<int> m_setAlmType; std::unordered_set<int> m_setAlmType;
std::unordered_set<int> m_setLocationID; std::unordered_set<int> m_setLocationID;
std::unordered_set<int> m_setPriority; std::unordered_set<int> m_setPriority;

View File

@ -200,6 +200,7 @@ class CAlmReq : public oatpp::DTO
DTO_FIELD( Any, endTime ); DTO_FIELD( Any, endTime );
//todo 是否已确认 前端传过来的是"almStatus",不符合我们的命名,可以考虑让前端修改 //todo 是否已确认 前端传过来的是"almStatus",不符合我们的命名,可以考虑让前端修改
DTO_FIELD( String, almStatus ); DTO_FIELD( String, almStatus );
DTO_FIELD( String, keyIdTag );
DTO_FIELD( String, type ); DTO_FIELD( String, type );
//< json里有但没用界面就没有按内容过滤的的功能 //< json里有但没用界面就没有按内容过滤的的功能
//DTO_FIELD( String, content ); //DTO_FIELD( String, content );
@ -222,7 +223,7 @@ class CAlmRepData : public oatpp::DTO
DTO_FIELD( String, content ); DTO_FIELD( String, content );
//< 前端并没有使用 //< 前端并没有使用
//DTO_FIELD( String, graphName ); //DTO_FIELD( String, graphName );
//DTO_FIELD( String, keyIdTag ); DTO_FIELD( String, keyIdTag );
//DTO_FIELD( Vector < String > , soundFile ); //DTO_FIELD( Vector < String > , soundFile );
//< 前端按序号访问other需注意顺序不能乱 //< 前端按序号访问other需注意顺序不能乱
@ -252,6 +253,107 @@ class CAlmRep : public oatpp::DTO
DTO_FIELD( Vector < Object < CAlmRepData >>, data ); DTO_FIELD( Vector < Object < CAlmRepData >>, data );
}; };
/////////////////////////////////////////////////////////////////
/**
* @brief
*/
class CAlmLevelRelation : public oatpp::DTO
{
DTO_INIT( CAlmLevelRelation, DTO );
DTO_FIELD( String, address_id ) = "name";
DTO_FIELD( String, alarm_level ) = "level_name";
DTO_FIELD( String, value ) = "value";
};
class CAlmLevelDataUnit : public oatpp::DTO
{
DTO_INIT( CAlmLevelDataUnit, DTO );
DTO_FIELD( String, level_color );
DTO_FIELD( String, level_name );
DTO_FIELD( String, alarm_level );
DTO_FIELD( String, code );
DTO_FIELD( Boolean, hasChildren );
DTO_FIELD( String, address_id );
DTO_FIELD( String, name );
DTO_FIELD( Int32, value );
};
class CAlmLevelData : public oatpp::DTO
{
DTO_INIT( CAlmLevelData, DTO );
DTO_FIELD( String, databaseType );
DTO_FIELD( String, tableName ) = "getAlarmLevelCount";
DTO_FIELD( Object<CAlmLevelRelation>, relationship );
DTO_FIELD( List<Object<CAlmLevelDataUnit>>, data );
};
class CAlmLevelResp : public oatpp::DTO
{
DTO_INIT( CAlmLevelResp, DTO );
DTO_FIELD( Int32, code );
DTO_FIELD( String, message );
DTO_FIELD( Object<CAlmLevelData>, data );
};
/////////////////////////////////////////////////////////////////
// 告警信息获取接口目前用于app部分无用字段为了性能暂时注释
class CAlmData : public oatpp::DTO
{
DTO_INIT( CAlmData, DTO );
DTO_FIELD( Int32, alm_type );
DTO_FIELD( Int32, alm_status );
DTO_FIELD( String, alm_status_desc );
DTO_FIELD( Int32, alm_logic_status );
DTO_FIELD( String, timestamp );
// DTO_FIELD( Int32, domain_id );
// DTO_FIELD( String, domain_desc );
// DTO_FIELD( Int32, location_id );
// DTO_FIELD( Int32, app_id );
DTO_FIELD( Int32, priority );
DTO_FIELD( String, priority_desc );
DTO_FIELD( Int32, priority_order );
// DTO_FIELD( Boolean, is_water_alm );
DTO_FIELD( String, uuid_base64 );
DTO_FIELD( String, content );
// DTO_FIELD( Int32, sub_system );
// DTO_FIELD( String, sub_system_desc );
// DTO_FIELD( Int32, dev_type );
// DTO_FIELD( String, dev_type_desc );
// DTO_FIELD( Int32, region_id );
// DTO_FIELD( Boolean, has_region_id );
// DTO_FIELD( String, region_desc );
DTO_FIELD( String, dev_group_tag );
DTO_FIELD( Boolean, has_dev_group_tag );
DTO_FIELD( String, key_id_tag );
// DTO_FIELD( String, graph_name );
// DTO_FIELD( Boolean, is_visible );
};
class CGetAllAlmResp : public oatpp::DTO
{
DTO_INIT( CGetAllAlmResp, DTO );
DTO_FIELD( Int32, code );
DTO_FIELD( String, message );
DTO_FIELD( Int32, version_no );
DTO_FIELD( Int32, size );
DTO_FIELD( List<Object<CAlmData>>, data );
};
class CGetChgLogAfterResp : public oatpp::DTO
{
DTO_INIT( CGetChgLogAfterResp, DTO );
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD( Int32, version_no ) = 0;
DTO_FIELD( String, message );
DTO_FIELD( List<Object<CAlmData>>, chg_alm_add );
DTO_FIELD( List<Object<CAlmData>>, chg_alm_update );
DTO_FIELD( List<String>, chg_alm_del );
};
/////////////////////////////////////////////////////////////////
} //namespace dto } //namespace dto
} //namespace module_alarm } //namespace module_alarm
} //namespace web_server } //namespace web_server

View File

@ -179,7 +179,7 @@ public:
//< 是否流水账告警 //< 是否流水账告警
inline bool isWaterAlm() const inline bool isWaterAlm() const
{ {
return m_spAlmInfo->if_water_alm(); return (m_spAlmInfo->if_water_alm() != 0);
} }
//< 本条告警信息的唯一标识使用base64编码缩短后的uuid //< 本条告警信息的唯一标识使用base64编码缩短后的uuid

View File

@ -14,11 +14,14 @@
#include "pub_logger_api/logger.h" #include "pub_logger_api/logger.h"
#include "pub_utility_api/TimeUtil.h" #include "pub_utility_api/TimeUtil.h"
#include "pub_utility_api/I18N.h"
#include "db_api_ex/CDbApi.h" #include "db_api_ex/CDbApi.h"
#include "rdb_api/CRdbAccess.h" #include "rdb_api/CRdbAccess.h"
//#include "alarm_server_api/AlarmCommonDef.h" //#include "alarm_server_api/AlarmCommonDef.h"
#include "../include/SessionApi.h" #include "../include/SessionApi.h"
#include "../module_alarm/DataMngThread.hpp"
#include "DTOs.hpp" #include "DTOs.hpp"
#include "SimpleCtrl.hpp" #include "SimpleCtrl.hpp"
@ -265,9 +268,9 @@ std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> CSimpleCtrl::que
nStartTimeMsec = nTemp; nStartTimeMsec = nTemp;
} }
if ( content != "" || regionId != "" ) if ( regionId != "" )
{ {
const char *szMsg = "请求错误:按内容或者按区域搜索未启用"; const char *szMsg = "请求错误:按区域搜索未启用";
LOGERROR( "%s", szMsg ); LOGERROR( "%s", szMsg );
return createResponse( Status::CODE_400, szMsg ); return createResponse( Status::CODE_400, szMsg );
} }
@ -406,6 +409,13 @@ std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> CSimpleCtrl::que
addCondtion( vecDevType, "dev_type" ); addCondtion( vecDevType, "dev_type" );
addCondtion( vecType, "alm_type" ); addCondtion( vecType, "alm_type" );
if( content != "" )
{
strCondition += QString(" content like '%%1%'").arg(urldecode(*content).c_str());
strCondition += " and ";
}
if ( strCondition != "" ) if ( strCondition != "" )
{ {
strCondition = " and " + strCondition; strCondition = " and " + strCondition;
@ -431,7 +441,7 @@ std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> CSimpleCtrl::que
LOGERROR( "queryEventMsFromMySql(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData()); LOGERROR( "queryEventMsFromMySql(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
return createResponse( Status::CODE_500, "数据库查询错误" ); return createResponse( Status::CODE_500, "数据库查询错误" );
} }
LOGDEBUG( "SQL语句如下\n%s", strSql.toUtf8().constData()); //LOGDEBUG( "SQL语句如下\n%s", strSql.toUtf8().constData());
auto spResp = dto::EventMsDto::createShared(); auto spResp = dto::EventMsDto::createShared();
@ -937,6 +947,428 @@ CSimpleCtrl::queryEventConditionMs( /*const oatpp::Int32 &type, const oatpp::Int
return createDtoResponse( Status::CODE_200, spDto ); return createDtoResponse( Status::CODE_200, spDto );
} }
////////////////////////////////////////////////////////////////////////
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
CSimpleCtrl::getAlarmLevelCount(const std::shared_ptr<IncomingRequest> &request)
{
auto spResp = dto::CAlmLevelResp::createShared();
spResp->data = dto::CAlmLevelData::createShared();
spResp->data->relationship = dto::CAlmLevelRelation::createShared();
spResp->data->data = {};
spResp->data->databaseType = std::string(I18N( "接口" ));
// 列出所有参数,不一定用的到,暂时注释不实现
QString strAreaCode,strDimensions;
//,strAlarmLevel,strOrderBy,strLimit;
int nShowSubSet;
//nTop;
// 检查参数
bool bParaOk = true;
QString strTmp = request->getQueryParameter( "showSubSet" ).getValue( "" ).c_str();
nShowSubSet = strTmp.toInt(&bParaOk);
if ( !bParaOk )
{
const std::string strMsg = I18N( "无效的请求参数" );
LOGERROR( "getAlarmLevelCount()%s", strMsg.c_str());
spResp->code = 400;
spResp->message = strMsg;
return createDtoResponse( Status::CODE_200, spResp );
}
strAreaCode = request->getQueryParameter( "areaCode" ).getValue( "" ).c_str();
strDimensions = request->getQueryParameter( "dimensions" ).getValue( "" ).c_str();
QStringList listAreaCode = strAreaCode.split(":",QString::SkipEmptyParts);
// 检查areadCode
if( listAreaCode.size() != 2 || listAreaCode.at(0) != "location")
{
const std::string strMsg = I18N( "无效的请求参数不支持location以外的areaCode" );
LOGERROR( "getAlarmLevelCount()%s", strMsg.c_str());
spResp->code = 400;
spResp->message = strMsg;
return createDtoResponse( Status::CODE_200, spResp );
}
// 打开数据库
CDbApi objDb(DB_CONN_MODEL_READ);
if ( !objDb.open() )
{
const std::string strMsg = I18N( "获取模型可读关系库失败" );
LOGERROR( "getAlarmLevelCount()%s", strMsg.c_str());
spResp->code = 400;
spResp->message = strMsg;
return createDtoResponse( Status::CODE_200, spResp );
}
// 验证location存在
if( listAreaCode.at(0) == "location")
{
// 查找location是否存在
QSqlQuery objQuery;
QString sSql = QString("select tag_name from sys_model_location_info where location_id='%1'").arg(listAreaCode.at(1));
if ( !objDb.execute(sSql,objQuery) )
{
const std::string strMsg = I18N( "查询关系库表 sys_model_location_info 失败" );
LOGERROR( "getAlarmLevelCount()%s", strMsg.c_str());
spResp->code = 400;
spResp->message = strMsg;
return createDtoResponse( Status::CODE_200, spResp );
}
if( !objQuery.next() )
{
const std::string strMsg = I18N( "location不存在" );
LOGERROR( "getAlarmLevelCount()%s", strMsg.c_str());
spResp->code = 400;
spResp->message = strMsg;
return createDtoResponse( Status::CODE_200, spResp );
}
}
// 获取所有的设备组
QMap<QString,QString> subset;
if( listAreaCode.at(0) == "location" )
{
QSqlQuery objQuery;
QString sSql = QString("select tag_name,description from dev_group where location_id='%1'").arg(listAreaCode.at(1));
if ( !objDb.execute(sSql,objQuery) )
{
const std::string strMsg = I18N( "查询关系库表 dev_group 失败" );
LOGERROR( "getAlarmLevelCount()%s", strMsg.c_str());
spResp->code = 400;
spResp->message = strMsg;
return createDtoResponse( Status::CODE_200, spResp );
}
while( objQuery.next() )
{
subset[objQuery.value(0).toString()] = objQuery.value(1).toString();
}
}
//< 查询告警颜色配置
QMap<int, QString> mapCfgColor;
QMap<int, QString> mapCfgDesc;
{
QSqlQuery objQuery;
//< SQL中写明列名代码中无需再判断列是否存在
QString sSql = "SELECT id,color FROM alarm_color ORDER BY id";
if ( objDb.execute( sSql, objQuery ))
{
bool bOk = true;
while ( objQuery.next())
{
const int nId = objQuery.value( 0 ).toInt( &bOk );
if ( !bOk )
{
continue;
}
mapCfgColor[nId] = objQuery.value( 1 ).toString();
}
}
objQuery.clear();
//< SQL中写明列名代码中无需再判断列是否存在
sSql = "SELECT priority_id,priority_name FROM alarm_level_define ORDER BY priority_id";
if ( !objDb.execute( sSql, objQuery ))
{
const std::string strMsg = I18N( "查询关系库表 alarm_level_define 失败" );
LOGERROR( "getAlarmLevelCount()%s", strMsg.c_str());
spResp->code = 400;
spResp->message = strMsg;
return createDtoResponse( Status::CODE_200, spResp );
}
while ( objQuery.next() )
{
const int nId = objQuery.value( 0 ).toInt();
QString desc = objQuery.value( 1 ).toString();
QString color;
auto it = mapCfgColor.find( nId );
if ( it == mapCfgColor.end())
{
//< 没找到
if ( nId >= ( int ) g_vecDefaultAlmColor.size())
color = *g_vecDefaultAlmColor.rbegin()->c_str();
else if ( nId < 0 )
color = *g_vecDefaultAlmColor.begin()->c_str();
else
color = g_vecDefaultAlmColor[nId].c_str();
}
else
{
color = *it;
}
mapCfgDesc[nId] = desc;
mapCfgColor[nId] = color;
}
}
QStringList listDimensions = strDimensions.split(",",QString::SkipEmptyParts);
if( listDimensions.size() != 2 )
{
const std::string strMsg = I18N( "无效的请求参数,dimensions不支持一个参数" );
LOGERROR( "getAlarmLevelCount()%s", strMsg.c_str());
spResp->code = 400;
spResp->message = strMsg;
return createDtoResponse( Status::CODE_200, spResp );
}
QMap<QString,int> mapAlmSize;
for(const auto &almLevelId_keys : mapCfgColor.keys())
{
for(const auto &itSub : subset.keys() )
{
QString key = QString("%1_%2").arg( QString::number( almLevelId_keys ) )
.arg( itSub );
mapAlmSize[key] = 0;
}
}
int nVer = 0;
std::vector<CLiveAlmSp> vecAlm;
CDataMngThread::getInstance()->getAllAlm(nVer,vecAlm);
for ( const auto &it : vecAlm )
{
if(!it->hasDevGroupTag())
{
continue;
}
if(!it->isVisible())
{
continue;
}
QString key = QString("%1_%2").arg( QString::number( it->getPriority() ) )
.arg( it->getDevGroupTag().c_str() );
if(mapAlmSize.find(key) != mapAlmSize.end())
{
mapAlmSize[key] += 1;
}
}
for(const auto &almLevelId_keys : mapCfgColor.keys())
{
for(const auto &itSub : subset.keys() )
{
QString key = QString("%1_%2").arg( QString::number( almLevelId_keys ) )
.arg( itSub );
auto oneUnit = dto::CAlmLevelDataUnit::createShared();
oneUnit->level_color = mapCfgColor[almLevelId_keys].toStdString();
oneUnit->level_name = mapCfgDesc[almLevelId_keys].toStdString();
oneUnit->alarm_level = QString::number(almLevelId_keys).toStdString();
oneUnit->code = itSub.toStdString();
oneUnit->hasChildren = false;
oneUnit->address_id = QString("dev_group:%1").arg(itSub).toStdString();
oneUnit->name = subset[itSub].toStdString();
oneUnit->value = mapAlmSize[key];
spResp->data->data->push_back( oneUnit );
}
}
spResp->code = 200;
const std::string cn_strSuccess = I18N( "成功" );
spResp->message = cn_strSuccess;
return createDtoResponse( Status::CODE_200, spResp );
}
void fillOneAlm(dto::CAlmData::Wrapper& oneAlmResp, const CLiveAlmSp & almSp)
{
oneAlmResp->alm_type = almSp->getAlmType();
oneAlmResp->alm_status = almSp->getAlmStatus();
oneAlmResp->alm_status_desc = almSp->getAlmStatusDesc();
oneAlmResp->alm_logic_status = (int)almSp->getLogicState();
oneAlmResp->timestamp = QString::number(almSp->getTimeStamp()).toStdString();
// spOne->domain_id = almSp->getDomainId();
// spOne->domain_desc = almSp->getDomainDesc();
// spOne->location_id = almSp->getLocationId();
// spOne->app_id = almSp->getAppId();
oneAlmResp->priority = almSp->getPriority();
oneAlmResp->priority_desc = almSp->getPriorityDesc();
oneAlmResp->priority_order = almSp->getPriorityOrder();
// spOne->is_water_alm = almSp->isWaterAlm();
oneAlmResp->uuid_base64 = almSp->getUuidBase64();
oneAlmResp->content = almSp->getContent();
// spOne->sub_system = it->getSubSystem();
// spOne->sub_system_desc = it->getSubSystemDesc();
// spOne->dev_type = it->getDevType();
// spOne->dev_type_desc = it->getDevTypeDesc();
// spOne->has_region_id = it->hasRegionId();
// if(it->hasRegionId())
// {
// spOne->region_id = it->getRegionId();
// spOne->region_desc = it->getRegionDesc();
// }
// else
// {
// spOne->region_id = -1;
// spOne->region_desc = "";
// }
oneAlmResp->has_dev_group_tag = almSp->hasDevGroupTag();
if(almSp->hasDevGroupTag())
{
oneAlmResp->dev_group_tag = almSp->getDevGroupTag();
}
else
{
oneAlmResp->dev_group_tag = "";
}
oneAlmResp->key_id_tag = almSp->getKeyIdTag();
// oneAlmResp->graph_name = almSp->getGraphName();
}
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
CSimpleCtrl::getAllAlm()
{
auto spResp = dto::CGetAllAlmResp::createShared();
spResp->data = {};
const std::string cn_strSuccess = I18N( "成功" );
spResp->message = cn_strSuccess;
int nVer = 0;
std::vector<CLiveAlmSp> vecAlm;
CDataMngThread::getInstance()->getAllAlm(nVer,vecAlm);
spResp->version_no = nVer;
for ( auto &spAlm : vecAlm )
{
if ( !spAlm->isVisible() )
continue;
auto spOne = dto::CAlmData::createShared();
fillOneAlm(spOne,spAlm);
spResp->data->push_back( spOne );
}
spResp->size = static_cast<v_int32>(spResp->data->size());
spResp->code = 200;
return createDtoResponse(Status::CODE_200, spResp);
}
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
CSimpleCtrl::getChgLogAfter(const oatpp::Int32 & version_no)
{
auto spResp = dto::CGetChgLogAfterResp::createShared();
const std::string cn_strSuccess = I18N( "成功" );
spResp->message = cn_strSuccess;
spResp->chg_alm_add = {};
spResp->chg_alm_update = {};
spResp->chg_alm_del = {};
std::vector<CAlmChgLogSp> vecSpChgLog;
if ( !CDataMngThread::getInstance()->getChgLogAfter( version_no, vecSpChgLog ))
{
const std::string cn_strFailed = I18N( "失败" );
spResp->message = cn_strFailed;
spResp->code = 201;
spResp->version_no = version_no;
return createDtoResponse(Status::CODE_200, spResp);
}
if(vecSpChgLog.empty())
{
spResp->version_no = version_no;
return createDtoResponse(Status::CODE_200, spResp);
}
spResp->version_no = ( *vecSpChgLog.rbegin())->getVerNo();
for ( auto &spChgLog:vecSpChgLog )
{
switch ( spChgLog->getChgType())
{
case CAlmChgLog::EN_CT_NULL:
break;
case CAlmChgLog::EN_CT_ADD:
{
const auto &vecRefAlm = spChgLog->getRefAlm();
for ( auto &wpAlm:vecRefAlm )
{
CLiveAlmSp spAlm = wpAlm.lock();
if ( !spAlm )
continue;
if ( !spAlm->isVisible())
continue;
auto spOne = dto::CAlmData::createShared();
fillOneAlm(spOne,spAlm);
spResp->chg_alm_add->push_back( spOne );
}
}
break;
case CAlmChgLog::EN_CT_UPDATE:
{
const auto &vecRefAlm = spChgLog->getRefAlm();
for ( auto &wpAlm:vecRefAlm )
{
CLiveAlmSp spAlm = wpAlm.lock();
if ( !spAlm )
continue;
if ( !spAlm->isVisible())
continue;
auto spOne = dto::CAlmData::createShared();
fillOneAlm(spOne,spAlm);
spResp->chg_alm_update->push_back( spOne );
}
}
break;
case CAlmChgLog::EN_CT_DEL:
{
const auto &vecRefAlm = spChgLog->getRefAlm();
for ( auto &wpAlm:vecRefAlm )
{
CLiveAlmSp spAlm = wpAlm.lock();
if ( !spAlm )
continue;
spResp->chg_alm_del->push_back(spAlm->getUuidBase64());
}
}
break;
default:
break;
}
}
spResp->code = 200;
return createDtoResponse(Status::CODE_200, spResp);
}
// 获得设备告警数量 TODO 待实现
//std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
//CSimpleCtrl::getDeviceAlarmById(const std::shared_ptr<IncomingRequest> &request)
//{
// return createResponse(Status::CODE_200, "ok");
//}
} //namespace module_alarm } //namespace module_alarm
} //namespace web_server } //namespace web_server

View File

@ -46,6 +46,28 @@ public:
ENDPOINT( "GET", "queryEventConditionMs", queryEventConditionMs, ENDPOINT( "GET", "queryEventConditionMs", queryEventConditionMs,
/*QUERY( Int32 , type ), QUERY( Int32, id ),*/REQUEST( std::shared_ptr<IncomingRequest>, spRequest )); /*QUERY( Int32 , type ), QUERY( Int32, id ),*/REQUEST( std::shared_ptr<IncomingRequest>, spRequest ));
/**
* @brief
*/
ENDPOINT( "GET", "/api-query/databind/getAlarmLevelCount", getAlarmLevelCount,
REQUEST( std::shared_ptr<IncomingRequest>, spRequest ));
/**
* @brief
*/
ENDPOINT( "GET", "getAllAlm", getAllAlm);
/**
* @brief vetsion_no之后的告警
*/
ENDPOINT( "GET", "getChgLogAfter", getChgLogAfter, QUERY( Int32, version_no ));
/**
* @brief
*/
// ENDPOINT( "GET", "/api-query/databind/getDeviceAlarmById", getDeviceAlarmById ,
// REQUEST( std::shared_ptr<IncomingRequest>, spRequest ));
}; };
} //namespace module_alarm } //namespace module_alarm

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,157 @@

#pragma once
#include "DTOs.hpp"
#include "oatpp/web/server/api/ApiController.hpp"
#include "oatpp/core/macro/codegen.hpp"
#include "oatpp/core/macro/component.hpp"
#include "rdb_api/RdbTableMng.h"
#include "perm_mng_api/PermMngDefine.h"
#include "service/common/RdbTableDefine.h"
#include "rdb_api/CRdbAccess.h"
#include "rdb_net_api/CRdbNetApi.h"
#include "db_api_ex/CDbApi.h"
#include <pub_utility_api/TimeUtil.h>
#include <../include/SessionApi.h>
#include <QString>
#include <QDateTime>
#include "tsdb_api/CTsdbConn.h"
#include OATPP_CODEGEN_BEGIN( ApiController ) //<-- Begin Codegen
namespace web_server
{
namespace module_app
{
/**
* Sample Api Controller.
*/
class CtrlApp : public oatpp::web::server::api::ApiController
{
private:
iot_dbms::CRdbTableMngPtr m_ptrRdbTableMng;
QMap<int,QString> m_mapLocation; // locationId -> locationName
QMap<int,QString> m_mapSubsystem; // subsystemId -> subsystemName
bool getRealTimeValStatus(const QStringList & listKeyIdTag,oatpp::Object<rtDataDTO> & rtData,const std::string &tableName);
bool getInfluxdbDataByDeviceGroup(iot_dbms::CDbApi& objDbConn,iot_dbms::CTsdbConnPtr& pTsdbConn,List<oatpp::Object<historyDataDTO>> & hData,const QString& tableName,
QMap<int,String>& unitMap,QDateTime dtStart,QDateTime dtEnd,QString filterStr,QString deviceGroup);
void initBaseInfo();
public:
/**
* Constructor with object mapper.
* @param objectMapper - default object mapper used to serialize/deserialize DTOs.
*/
CtrlApp( OATPP_COMPONENT( std::shared_ptr<ObjectMapper>, objectMapper ))
: oatpp::web::server::api::ApiController( objectMapper )
{
initBaseInfo();
}
bool init();
public:
// 获得系统时间和安全天数
ENDPOINT( "GET", "/getAllDeviceTempCode", getAllDeviceTempCode );
ENDPOINT("GET", "/getAllTxCodeByDevGrp", getAllTxCodeByDevGrp,
QUERY( String, name,"name",""),
QUERY( Int32, pageNo,"pageNo",1),
QUERY( Int32, pageSize,"pageSize",30) ) ;
ENDPOINT("GET", "/getAllDeviceByGroupCode", getAllDeviceByGroupCode,
QUERY( String, groupCode ),
QUERY( Int32, pageNo,"pageNo",0),
QUERY( Int32, pageSize,"pageSize",0)
);
ENDPOINT("POST", "/getRealDataByCode", getRealDataByCode, BODY_STRING( String, strReq )) ;
ENDPOINT("GET", "/getAlarmCount", getAlarmCount,
QUERY( String, startTime ), QUERY( String, endTime ),
QUERY( String, priority,"priority",""), QUERY( String, type,"type",""), QUERY( String, devType,"devType",""),
QUERY( String, content,"content","")
) ;
ENDPOINT("GET", "/getDeviceTempKeyValue", getDeviceTempKeyValue,
QUERY( String, tag_name ),
QUERY( Int32, pageNo,"pageNo",0),
QUERY( Int32, pageSize,"pageSize",0)
);
ENDPOINT( "POST", "/setDeviceTempKeyValue", setDeviceTempKeyValue, BODY_STRING( String, strReq ));
ENDPOINT("POST", "/confirmAlm", confirmAlm,BODY_STRING( String, strReq ),
REQUEST( std::shared_ptr<IncomingRequest>, spRequest )) ;
ENDPOINT("POST", "/deleteAlm", deleteAlm,BODY_STRING( String, strReq )) ;
/**
* @brief location列表分页查询
*/
ENDPOINT("GET", "/app/location", queryLocationList,
QUERY( String, filterStr,"filterStr",""),
QUERY( String, devStr,"devStr",""),
QUERY( Int32, page,"page",1),
QUERY( Int32, pageSize,"pageSize",30)
);
/**
* @brief location详情查询
*/
ENDPOINT("GET", "/app/locationDetail", queryLocationDetail,
QUERY( String, filterStr,"filterStr",""),
QUERY( Int32, locationId,"locationId",0),
QUERY( String, startTime,"startTime",""),
QUERY( String, endTime,"endTime","")
);
/**
* @brief
*/
ENDPOINT("GET", "/app/deviceGroups", queryDeviceGroups,
QUERY( String, filterStr,"filterStr",""),
QUERY( String, devStr,"devStr",""),
QUERY( Int32, locationId,"locationId",0),
QUERY( Int32, page,"page",1),
QUERY( Int32, pageSize,"pageSize",30)
);
/**
* @brief
*/
ENDPOINT("GET", "/app/deviceGroupInfo", queryDeviceGroupInfo,
QUERY( String, deviceGroupTag,"deviceGroupTag",""),
QUERY( String, deviceStr,"deviceStr","")
);
/**
* @brief
*/
ENDPOINT("GET", "/app/getCodeByDevice", getCodeByDevice,
QUERY( String, deviceTag,"deviceTag",""),
QUERY( Int32, page,"page",1),
QUERY( Int32, pageSize,"pageSize",30)
);
};
} //namespace module_app
} //namespace web_server
#include OATPP_CODEGEN_END( ApiController ) //<-- End Codegen

View File

@ -0,0 +1,379 @@

#pragma once
#include "oatpp/core/macro/codegen.hpp"
#include "oatpp/core/Types.hpp"
#include <QString>
#include OATPP_CODEGEN_BEGIN( DTO )
namespace web_server
{
namespace module_app
{
/**
* Data Transfer Object. Object containing fields only.
* Used in API for serialization/deserialization and validation
*/
class almCountDataDTO : public oatpp::DTO
{
DTO_INIT( almCountDataDTO, DTO )
DTO_FIELD( Int32, ack ) = 0;
DTO_FIELD( Int32, unAck ) = 0;
DTO_FIELD( Int32, total ) = 0;
};
class almCountDTO : public oatpp::DTO
{
DTO_INIT( almCountDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD(String, message );
DTO_FIELD(Object<almCountDataDTO> , data );
};
class txCodeUnitDTO : public oatpp::DTO
{
DTO_INIT( txCodeUnitDTO, DTO )
DTO_FIELD( String, code ) ;
DTO_FIELD( String, name ) ;
DTO_FIELD( String, TxCode ) ;
};
class txCodeDataDTO : public oatpp::DTO
{
DTO_INIT( txCodeDataDTO, DTO )
DTO_FIELD( Int32, pageNo ) = 0;
DTO_FIELD( Int32, pageSize ) = 0;
DTO_FIELD( Int32, records ) = 0;
DTO_FIELD( Int32, total ) = 0;
DTO_FIELD(List<Object<txCodeUnitDTO>>, dataMap);
};
class txCodeDTO : public oatpp::DTO
{
DTO_INIT( txCodeDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD(String, message );
DTO_FIELD(Object<txCodeDataDTO> , data );
};
class deviceCodeUnitDTO : public oatpp::DTO
{
DTO_INIT( deviceCodeUnitDTO, DTO )
DTO_FIELD( String, treePcode ) ;
DTO_FIELD( String, code ) ;
DTO_FIELD( String, unitName ) ;
DTO_FIELD( String, unitCode ) ;
DTO_FIELD( String, sname ) ;
DTO_FIELD( String, name ) ;
DTO_FIELD( String, keyValue ) ;
DTO_FIELD( String, diNum ) ;
DTO_FIELD( String, type ) ;
};
class deviceCodeDataDTO : public oatpp::DTO
{
DTO_INIT( deviceCodeDataDTO, DTO )
DTO_FIELD( Int32, pageNo ) = 0;
DTO_FIELD( Int32, pageSize ) = 0;
DTO_FIELD( Int32, records ) = 0;
DTO_FIELD( Int32, total ) = 0;
DTO_FIELD(List<Object<deviceCodeUnitDTO>>, dataMap);
};
class deviceCodeDTO : public oatpp::DTO
{
DTO_INIT( deviceCodeDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD(String, message );
DTO_FIELD(Object<deviceCodeDataDTO> , data );
};
class deviceTPUnitDTO : public oatpp::DTO
{
DTO_INIT( deviceTPUnitDTO, DTO )
DTO_FIELD( String, treePcode ) ;
DTO_FIELD( String, code ) ;
DTO_FIELD( String, name ) ;
DTO_FIELD( String, keyValue ) ;
DTO_FIELD( String, type ) ;
};
class deviceTPDataDTO : public oatpp::DTO
{
DTO_INIT( deviceTPDataDTO, DTO )
DTO_FIELD( Int32, pageNo ) = 0;
DTO_FIELD( Int32, pageSize ) = 0;
DTO_FIELD( Int32, records ) = 0;
DTO_FIELD( Int32, total ) = 0;
DTO_FIELD(List<Object<deviceTPUnitDTO>>, dataMap);
};
class deviceTPDTO : public oatpp::DTO
{
DTO_INIT( deviceTPDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD(String, message );
DTO_FIELD(Object<deviceTPDataDTO> , data );
};
class setDevceTPDTO: public oatpp::DTO
{
DTO_INIT( setDevceTPDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD(String, message );
};
class setDevceTPReqUnitDTO: public oatpp::DTO
{
DTO_INIT( setDevceTPReqUnitDTO, DTO )
DTO_FIELD(String, deviceCode );
DTO_FIELD(String, code );
DTO_FIELD(String, keyValue );
DTO_FIELD(String, type );
};
class setDevceTPReqDTO: public oatpp::DTO
{
DTO_INIT( setDevceTPReqDTO, DTO )
DTO_FIELD( Int32, total ) ;
DTO_FIELD(List<Object<setDevceTPReqUnitDTO>> , data );
};
class rtDataUnitDTO : public oatpp::DTO
{
DTO_INIT( rtDataUnitDTO, DTO )
DTO_FIELD( String, key_id_tag ) ;
DTO_FIELD( Float64, value ) ;
DTO_FIELD( Int32, status ) ;
};
class rtDataDTO : public oatpp::DTO
{
DTO_INIT( rtDataDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD( String, message );
DTO_FIELD( String, time ) ;
DTO_FIELD(List<Object<rtDataUnitDTO>>, data );
};
class rtReqDTO : public oatpp::DTO
{
DTO_INIT( rtReqDTO, DTO )
DTO_FIELD( String, code );
};
class confirmAlmUnitReqDTO : public oatpp::DTO
{
DTO_INIT( confirmAlmUnitReqDTO, DTO )
DTO_FIELD( String, key_id_tag ) ;
DTO_FIELD( Int64, timestamp ) ;
DTO_FIELD( String, uuid_base64 ) ;
DTO_FIELD( Int32, alm_type ) ;
DTO_FIELD( Int32, app_id ) ;
};
class confirmAlmReqDTO: public oatpp::DTO
{
DTO_INIT( confirmAlmReqDTO, DTO )
DTO_FIELD( Int32, total ) ;
DTO_FIELD(List<Object<confirmAlmUnitReqDTO>> , data );
};
class confirmAlmRepDTO: public oatpp::DTO
{
DTO_INIT( confirmAlmRepDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD(String, message );
};
class deleteAlmReqDTO: public oatpp::DTO
{
DTO_INIT( deleteAlmReqDTO, DTO )
DTO_FIELD( Int32, total ) ;
DTO_FIELD(List<String> , data );
};
class deviceTempUnitDTO : public oatpp::DTO
{
DTO_INIT( deviceTempUnitDTO, DTO )
DTO_FIELD( String, tag_name ) ;
DTO_FIELD( String, desc ) ;
};
class allDeviceTempDTO: public oatpp::DTO
{
DTO_INIT( allDeviceTempDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD( String, message );
DTO_FIELD(List<Object<deviceTempUnitDTO>> , data );
};
class deleteAlmRepDTO: public oatpp::DTO
{
DTO_INIT( deleteAlmRepDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD(String, message );
};
class realTimeDataDTO: public oatpp::DTO
{
DTO_INIT( realTimeDataDTO, DTO )
DTO_FIELD(String, tagName );
DTO_FIELD(String, desc );
DTO_FIELD( Float64, value );
DTO_FIELD( Int32, status );
DTO_FIELD(String, unitName );
};
class historyDataDTO: public oatpp::DTO
{
DTO_INIT(historyDataDTO, DTO )
DTO_FIELD(String, tagName );
DTO_FIELD(String, desc );
DTO_FIELD( Float64, value );
DTO_FIELD( Int32, status );
DTO_FIELD(String, unitName );
DTO_FIELD(Int32, type );
DTO_FIELD(String, stateTxt );
};
class locationDTO: public oatpp::DTO
{
DTO_INIT( locationDTO, DTO )
DTO_FIELD(String, locationName );
DTO_FIELD( Int32, id );
DTO_FIELD( Int32, devCnt );
DTO_FIELD( String, tagName );
DTO_FIELD(List<Object<historyDataDTO>> , data );
};
class locationListDTO: public oatpp::DTO
{
DTO_INIT( locationListDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD( String, message );
DTO_FIELD( Int32, total );
DTO_FIELD( Int32, page );
DTO_FIELD( Int32, pageSize );
DTO_FIELD(List<Object<locationDTO>> , rows );
};
class locationDetailDTO: public oatpp::DTO
{
DTO_INIT( locationDetailDTO, DTO )
DTO_FIELD(String, locationName );
DTO_FIELD( Int32, id );
DTO_FIELD( String, tagName );
DTO_FIELD(List<Object<historyDataDTO>> , data );
};
class locationDetailResponseDTO:public oatpp::DTO
{
DTO_INIT( locationDetailResponseDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD( String, message );
DTO_FIELD(Object<locationDetailDTO> , data );
};
class deviceGroupDTO: public oatpp::DTO
{
DTO_INIT( deviceGroupDTO, DTO )
DTO_FIELD(String, deviceGroupName );
DTO_FIELD( String, deviceGroupTag );
DTO_FIELD(List<Object<historyDataDTO>> , data );
};
class deviceGroupListDTO: public oatpp::DTO
{
DTO_INIT( deviceGroupListDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD( String, message );
DTO_FIELD( Int32, total );
DTO_FIELD( Int32, page );
DTO_FIELD( Int32, pageSize );
DTO_FIELD(List<Object<deviceGroupDTO>> , rows );
};
struct TagTuple {
int unitId;
QString description;
QString stateTxt;
};
class deviceDTO:public oatpp::DTO
{
DTO_INIT( deviceDTO, DTO )
DTO_FIELD( String, deviceTag );
DTO_FIELD( String, desc );
};
class deviceGroupInfoDTO:public oatpp::DTO
{
DTO_INIT( deviceGroupInfoDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD( String, message );
DTO_FIELD(List<Object<deviceDTO>> , rows );
};
class pointCodeDTO:public oatpp::DTO
{
DTO_INIT( pointCodeDTO, DTO )
DTO_FIELD(String, tagName );
DTO_FIELD(String, desc );
DTO_FIELD(String, unitName );
DTO_FIELD(Int32, type );
DTO_FIELD(String, stateTxt );
};
class devicePointCodeListDTO: public oatpp::DTO
{
DTO_INIT( devicePointCodeListDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD( String, message );
DTO_FIELD( Int32, total );
DTO_FIELD( Int32, page );
DTO_FIELD( Int32, pageSize );
DTO_FIELD(List<Object<pointCodeDTO>> , rows );
};
} //namespace module_app
} //namespace web_server
#include OATPP_CODEGEN_END( DTO )

View File

@ -0,0 +1,51 @@

#include "boost/make_shared.hpp"
#include "oatpp/web/server/HttpRouter.hpp"
#include "CtrlApp.h"
#include "ModuleApp.h"
namespace web_server
{
namespace module_app
{
bool CModuleApp::init()
{
auto router = getSimpleRouter();
auto ctrlGen = std::make_shared<CtrlApp>();
if(!ctrlGen->init())
{
LOGERROR(" ctrlUser failed to init!\n");
return false;
}
router->addController( ctrlGen );
return true;
}
bool CModuleApp::redundantSwitch( bool bMaster, bool bSlave )
{
//< 避免参数未使用编译告警
( void ) bMaster;
( void ) bSlave;
return true;
}
bool CModuleApp::clean()
{
return true;
}
boost::shared_ptr<CModuleApp> CModuleApp::create()
{
return boost::make_shared<CModuleApp>();
}
}
}

View File

@ -0,0 +1,28 @@

#pragma once
#include "../include/BaseModule.h"
namespace web_server
{
namespace module_app
{
class CModuleApp final : public CBaseModule
{
public:
CModuleApp() = default;
~CModuleApp() override = default;
bool init() override;
bool redundantSwitch( bool bMaster, bool bSlave ) override;
bool clean() override;
static boost::shared_ptr<CModuleApp> create();
};
} //< namespace module_app
} //< namespace web_server

View File

@ -0,0 +1,30 @@
# 该模块为 工业级电源智能监控项目APP需要
QT += sql
#module.pri中已指定编译为静态库生成路径在编译的临时目录
TEMPLATE = lib
TARGET = module_app
HEADERS += \
DTOs.hpp \
ModuleApp.h \
CtrlApp.h
SOURCES += \
ModuleApp.cpp \
CtrlApp.cpp
#静态库不要连接统一在server中连接
#LIBS +=
#-------------------------------------------------------------------
#所有web_server的模块应包含此pri无需包含common.pri
MODULE_PRI=$$PWD/../module.pri
exists($$MODULE_PRI) {
include($$MODULE_PRI)
}else {
error("FATAL error: can not find module.pri")
}

View File

@ -1,6 +1,9 @@
 
#include "CtrlGeneral.hpp" #include "CtrlGeneral.hpp"
#include "../include/ServerApi.h" #include "../include/ServerApi.h"
#include <QtSql/QSql>
#include "db_api_ex/CDbApi.h"
namespace web_server namespace web_server
{ {
@ -40,7 +43,7 @@ std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> CtrlGeneral::get
} }
if ( objRet.msgrecord_size() != 1 || objRet.msgrecord( 0 ).msgvaluearray_size() != 2 ) if ( objRet.msgrecord_size() != 1 || objRet.msgrecord( 0 ).msgvaluearray_size() != 2 )
{ {
LOGERROR( "wropng size of results of the safe_day" ); LOGERROR( "wrong size of results of the safe_day" );
return createResponse( Status::CODE_500, "查询失败" ); return createResponse( Status::CODE_500, "查询失败" );
} }
auto safeDto = SafeDayDto::createShared(); auto safeDto = SafeDayDto::createShared();
@ -146,5 +149,101 @@ CtrlGeneral::isPageAndReportAuthority( const oatpp::Int32 &type, const oatpp::St
} }
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
CtrlGeneral::getDictStateText(const oatpp::Int32 &subSystemId)
{
auto dstResp = dictTextDto::createShared();
dstResp->data=Fields<Fields<String> >::createShared();
iot_dbms::CDbApi objDbConn( DB_CONN_MODEL_READ );
QSqlQuery objQuery;
if ( !objDbConn.open())
{
const char *szMsg = "db open faild";
LOGERROR( "%s", szMsg );
dstResp->message = szMsg;
return createDtoResponse( Status::CODE_201, dstResp );
}
QString strSql=QString("select state_text_name,actual_value,display_value from dict_state_text_info where sub_system=%1").arg(subSystemId);
if(!objDbConn.execute( strSql, objQuery ))
{
LOGERROR( "getDictStateText(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
const char *szMsg = "db query faild";
dstResp->message = szMsg;
return createDtoResponse( Status::CODE_201, dstResp );
}
while (objQuery.next()) {
oatpp::String sttn=objQuery.value("state_text_name").toString().toStdString();
oatpp::String av=objQuery.value("actual_value").toString().toStdString();
oatpp::String dv=objQuery.value("display_value").toString().toStdString();
if(!dstResp->data[sttn])
{
oatpp::Fields<oatpp::String> newInnerFields=oatpp::Fields<oatpp::String>::createShared();
newInnerFields[av] = dv;
dstResp->data[sttn]=newInnerFields;
}else{
dstResp->data[sttn][av]=dv;
}
}
return createDtoResponse( Status::CODE_200, dstResp );
}
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
CtrlGeneral::getCtrlGrpName(const oatpp::Int32 &subSystemId)
{
auto dstResp = dictTextDto::createShared();
dstResp->data=Fields<Fields<String> >::createShared();
iot_dbms::CDbApi objDbConn( DB_CONN_MODEL_READ );
QSqlQuery objQuery;
if ( !objDbConn.open())
{
const char *szMsg = "db open faild";
LOGERROR( "%s", szMsg );
dstResp->message = szMsg;
return createDtoResponse( Status::CODE_201, dstResp );
}
QString strSql=QString("select ctrl_grp_name,ctrl_act_name,ctrl_act_type from opt_ctrl_act_define where sub_system=%1").arg(subSystemId);
if(!objDbConn.execute( strSql, objQuery ))
{
LOGERROR( "getCtrlGrpName(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
const char *szMsg = "db query faild";
dstResp->message = szMsg;
return createDtoResponse( Status::CODE_201, dstResp );
}
while (objQuery.next()) {
oatpp::String sttn=objQuery.value("ctrl_grp_name").toString().toStdString();
oatpp::String can=objQuery.value("ctrl_act_name").toString().toStdString();
oatpp::String cat=objQuery.value("ctrl_act_type").toString().toStdString();
if(!dstResp->data[sttn])
{
oatpp::Fields<oatpp::String> newInnerFields=oatpp::Fields<oatpp::String>::createShared();
newInnerFields[can] = cat;
dstResp->data[sttn]=newInnerFields;
}else{
dstResp->data[sttn][can]=cat;
}
}
return createDtoResponse( Status::CODE_200, dstResp );
}
} //namespace module_general } //namespace module_general
} //namespace web_server } //namespace web_server

View File

@ -70,6 +70,14 @@ public:
,QUERY(String, content) ,QUERY(String, content)
,REQUEST(std::shared_ptr<IncomingRequest>, request) ,REQUEST(std::shared_ptr<IncomingRequest>, request)
); );
ENDPOINT("GET","/gen/getDictStateText",getDictStateText,
QUERY(Int32, subSystemId)
);
ENDPOINT("GET","/gen/getCtrlGrpName",getCtrlGrpName,
QUERY(Int32, subSystemId)
);
}; };
} //namespace module_general } //namespace module_general

View File

@ -45,6 +45,14 @@ class SystemDateTimeDto : public oatpp::DTO
}; };
class dictTextDto:public oatpp::DTO
{
DTO_INIT( dictTextDto, DTO )
DTO_FIELD( Int32, code )=200;
DTO_FIELD( String, message );
DTO_FIELD( Fields<Fields<String> >, data ) = {};
};
} //namespace module_general } //namespace module_general
} //namespace web_server } //namespace web_server

View File

@ -1,5 +1,6 @@
#module.pri中已指定编译为静态库生成路径在编译的临时目录 #module.pri中已指定编译为静态库生成路径在编译的临时目录
QT += sql
TEMPLATE = lib TEMPLATE = lib
TARGET = module_general TARGET = module_general

View File

@ -0,0 +1,43 @@
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include "CModule.h"
#include "CSimpleController.h"
using namespace web_server::module_operate;
bool CModule::init()
{
//< todo 按oatpp的注释貌似依赖注入和获取区分线程尚未验证
//< todo 本程序依赖注入在主线程中本段代码在主线程中执行没有问题不知在其他线程中获取注入的component是否有问题
OATPP_COMPONENT( std::shared_ptr<oatpp::web::server::HttpRouter>, router, "simpleRouter" );
router->addController( std::make_shared<CSimpleController>());
//< todo 初始化业务资源,比如自己的线程
return true;
}
bool CModule::redundantSwitch( bool bMaster, bool bSlave )
{
//< 避免参数未使用编译告警
( void ) bMaster;
( void ) bSlave;
//< todo 按业务需求启、停自己的线程等
return true;
}
bool CModule::clean()
{
//< todo 貌似没有 addController 的逆操作
//< todo 清理业务资源
return true;
}
boost::shared_ptr<CModule> CModule::create()
{
return boost::make_shared<CModule>();
}

View File

@ -0,0 +1,21 @@
#pragma once
#include "../include/BaseModule.h"
namespace web_server { namespace module_operate
{
class CModule final : public CBaseModule
{
public:
CModule() = default;
~CModule() override = default;
public:
bool init() override;
bool redundantSwitch( bool bMaster, bool bSlave ) override;
bool clean() override;
static boost::shared_ptr<CModule> create();
};
}}

View File

@ -0,0 +1,155 @@
#include "CMsgDeal.h"
#include <QObject>
#include <QDebug>
namespace web_server {
namespace module_operate{
CMsgDeal::CMsgDeal(int appId)
{
m_sysInfo = NULL;
m_objSendCMb = new CMbCommunicator;
m_objRecvCMb = new CMbCommunicator;
m_appId=appId;
InitMsgBus();
}
CMsgDeal::~CMsgDeal()
{
delete m_objSendCMb;
m_objSendCMb = nullptr;
m_objRecvCMb->delSub(m_appId, CH_OPT_TO_HMI_OPTCMD_UP);
delete m_objRecvCMb;
m_objRecvCMb = nullptr;
}
int CMsgDeal::SendMessage(int channelId, int msgType, const std::string &content, int domain)
{
int ret = 0;
iot_net::CMbMessage msg;
msg.setData(content);
msg.setMsgType(msgType);
msg.setSubject(m_appId, channelId);
if(m_objSendCMb->sendMsgToDomain(msg, domain))
{
ret = 1;
}
return ret;
}
int CMsgDeal::RevMessage(int msgType,QString& result,std::string& resultStr, SOptCtrlRequest& request)
{
iot_net::CMbMessage msg;
while(m_objRecvCMb->recvMsg(msg, 60000))
{
if(msg.getMsgType() != msgType)
{
continue;
}
std::string str((const char*)msg.getDataPtr(), msg.getDataSize());
SOptCtrlReply socr;
if(!COptCtrlReply::parse(str,socr))
{
return 1;
}
if(socr.stHead.nIsSuccess==1&&
socr.stHead.strKeyIdTag==request.vecOptCtrlQueue[0].strKeyIdTag
)
{
resultStr=socr.stHead.strResultStr;
return 0;
}else
{
result=QString::fromStdString(str);
resultStr=socr.stHead.strResultStr;
return 2;
}
}
return 3;
}
int CMsgDeal::RevMessage(int msgType,QString& result,std::string& resultStr, SOptCustCtrlRequest& request, SOptCustCtrlReply& socr)
{
iot_net::CMbMessage msg;
while(m_objRecvCMb->recvMsg(msg, 60000))
{
if(msg.getMsgType() != msgType)
{
continue;
}
std::string str((const char*)msg.getDataPtr(), msg.getDataSize());
if(!COptCustCtrlReply::parse(str,socr))
{
return 1;
}
if(socr.stHead.nIsSuccess==1&&
socr.stHead.strKeyIdTag==request.strKeyIdTag
)
{
resultStr=socr.stHead.strResultStr;
return 0;
}else
{
result=QString::fromStdString(str);
resultStr=socr.stHead.strResultStr;
return 2;
}
}
return 3;
}
QString CMsgDeal::getNodeName()
{
SNodeInfo sNodeInfo;
m_sysInfo->getLocalNodeInfo(sNodeInfo);
return QString::fromStdString(sNodeInfo.strName);
}
QString CMsgDeal::getSendCMbName()
{
return QString::fromStdString(m_objSendCMb->getName());
}
void CMsgDeal::InitMsgBus()
{
if(!createSysInfoInstance(m_sysInfo))
{
qDebug() << QObject::tr("创建系统信息访问库实例失败!");
}
if(!m_objRecvCMb->addSub(m_appId, CH_OPT_TO_HMI_OPTCMD_UP))
{
qDebug() << QObject::tr("总线订阅失败!");
return;
}
}
void CMsgDeal::clearMsgBus()
{
iot_net::CMbMessage msg;
while(true)
{
if(!m_objRecvCMb->recvMsg(msg, 0))
{
break;
}
}
}
}}

View File

@ -0,0 +1,50 @@
#ifndef CMSGDEAL_H
#define CMSGDEAL_H
#include "public/pub_sysinfo_api/SysInfoApi.h"
#include "perm_mng_api/PermMngApi.h"
#include "net_msg_bus_api/CMbCommunicator.h"
#include "common/MessageChannel.h"
#include "QString"
#include "service/operate_server_api/JsonMessageStruct.h"
#include "service/operate_server_api/JsonOptCommand.h"
using namespace std;
using namespace iot_public;
using namespace iot_service;
using namespace iot_net;
namespace web_server {
namespace module_operate{
class CMsgDeal
{
public:
CMsgDeal(int appId);
~CMsgDeal();
public:
int SendMessage(int channelId, int msgType, const std::string &content, int domain);
int RevMessage(int msgType,QString& result,std::string& resultStr, SOptCtrlRequest& request);
int RevMessage(int msgType,QString& result,std::string& resultStr, SOptCustCtrlRequest& request,SOptCustCtrlReply& socr);
QString getNodeName();
QString getSendCMbName();
private:
void InitMsgBus();
void clearMsgBus();
private:
iot_public::CSysInfoInterfacePtr m_sysInfo;
iot_net::CMbCommunicator* m_objSendCMb;//发送
iot_net::CMbCommunicator* m_objRecvCMb;//接收
int m_appId;
};
}}
#endif // CMSGDEAL_H

View File

@ -0,0 +1,647 @@
#include "CSimpleController.h"
#include "dbms/db_his_query_api/DbHisQueryApi.h"
#include <QtSql/QSql>
#include "public/pub_logger_api/logger.h"
#include "DTOs.hpp"
#include "dbms/db_his_query_api/DbHisQueryBase.h"
#include "tsdb_api/TsdbApi.h"
#include "CMsgDeal.h"
using namespace iot_dbms;
namespace web_server {
namespace module_operate {
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
CSimpleController::getControlDeviceByDeviceGroup(const oatpp::String & deviceGroupTag)
{
auto deviceGroupInfodto=deviceGroupInfoDTO::createShared();
deviceGroupInfodto->rows={};
iot_dbms::CDbApi objDbConn( DB_CONN_MODEL_READ );
if ( !objDbConn.open())
{
const char *szMsg = "db open faild";
LOGERROR( "%s", szMsg );
deviceGroupInfodto->message = szMsg;
return createDtoResponse( Status::CODE_201, deviceGroupInfodto );
}
QString strSql;
std::string stdStr(deviceGroupTag->c_str(), deviceGroupTag->size());
QString sdeviceGroupTag=QString::fromStdString(stdStr);
strSql=QString("select tag_name,description from dev_info where group_tag_name='%1'").arg(sdeviceGroupTag);
QSqlQuery objQuery;
if ( !objDbConn.execute( strSql, objQuery ))
{
LOGERROR( "queryDeviceGroupInfo(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
const char *szMsg = "db query faild";
deviceGroupInfodto->message = szMsg;
return createDtoResponse( Status::CODE_201, deviceGroupInfodto );
}
while ( objQuery.next())
{
QString deviceTag=objQuery.value( 0 ).toString();
auto deviceDTO= deviceDTO::createShared();
deviceDTO->deviceTag = deviceTag.toStdString();
deviceDTO->desc = objQuery.value( 1 ).toString().toStdString();
if(deviceHasControl(objDbConn,deviceTag))
{
deviceDTO->type=1;
deviceGroupInfodto->rows->insert(deviceGroupInfodto->rows->end(),deviceDTO);
}else if(deviceHasConst(objDbConn,deviceTag))
{
deviceDTO->type=2;
deviceGroupInfodto->rows->insert(deviceGroupInfodto->rows->end(),deviceDTO);
}
}
return createDtoResponse( Status::CODE_200, deviceGroupInfodto );
}
bool CSimpleController::deviceHasControl(iot_dbms::CDbApi& objDbConn,QString deviceTag)
{
QSqlQuery objQuery;
QString condition=QString(" where is_control=1 and device='%1' ").arg(deviceTag);
QString sql="SELECT tag_name "
" from analog "+condition+
" union "+
"SELECT tag_name"+
" from digital "+condition+
" union "+
"SELECT tag_name"+
" from mix "+condition;
QString cntSql=QString("select count(1) from ( %1 ) as cnt_query").arg(sql);
if ( !objDbConn.execute( cntSql, objQuery ))
{
LOGERROR( "deviceHasControl(): 查询错误SQL语句如下\n%s", cntSql.toUtf8().constData());
return false;
}
int totalCnt{0};
while ( objQuery.next())
{
totalCnt = objQuery.value( 0 ).toString().toInt();
}
if( totalCnt == 0)
{
return false;
}
return true;
}
bool CSimpleController::deviceHasConst(CDbApi &objDbConn, QString deviceTag)
{
QSqlQuery objQuery;
QString cntSql=QString("select count(1) from fes_const where dev_tag='%1' ").arg(deviceTag);
if ( !objDbConn.execute( cntSql, objQuery ))
{
LOGERROR( "deviceHasConst(): 查询错误SQL语句如下\n%s", cntSql.toUtf8().constData());
return false;
}
int totalCnt{0};
while ( objQuery.next())
{
totalCnt = objQuery.value( 0 ).toString().toInt();
}
if( totalCnt == 0)
{
return false;
}
return true;
}
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
CSimpleController::getControlCodeInfoByDevice(
const oatpp::String & deviceTag,
const oatpp::Int32 & page,
const oatpp::Int32 & pageSize
)
{
//查出控制测点查询influxdb最新值
auto controlPointListdto=controlPointListDTO::createShared();
controlPointListdto->rows={};
iot_dbms::CDbApi objDbConn( DB_CONN_MODEL_READ );
QSqlQuery objQuery;
if ( !objDbConn.open())
{
const char *szMsg = "db open faild";
LOGERROR( "%s", szMsg );
controlPointListdto->message = szMsg;
return createDtoResponse( Status::CODE_201, controlPointListdto );
}
//查询单位
QMap<int,String> unitMap;
QString strSql="select unit_id,unit_name from dict_unit_info";
if ( !objDbConn.execute( strSql, objQuery ))
{
LOGERROR( "getControlCodeInfoByDevice(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
const char *szMsg = "db query faild";
controlPointListdto->message = szMsg;
return createDtoResponse( Status::CODE_201, controlPointListdto );
}
while ( objQuery.next())
{
unitMap[objQuery.value( 0 ).toString().toInt()]=objQuery.value( 1 ).toString().toStdString();
}
std::string stdStr(deviceTag->c_str(), deviceTag->size());
QString sDeviceStr=QString::fromStdString(stdStr);
QString sCondition=QString(" where is_control=1 and device='%1' ").arg(sDeviceStr);
QString sql="SELECT location_id,sub_system,tag_name,description, unit_id,'analog' AS table_name,'' AS state_text_name, '' AS ctrl_act_name "
" from analog "+sCondition+
" union "
"SELECT d.location_id,d.sub_system,d.tag_name,description, '' as unit_id,'digital' AS table_name,state_text_name,dc.ctrl_act_name"
" from digital d INNER JOIN digital_control dc ON d.tag_name=dc.tag_name "+sCondition+
" union "
"SELECT m.location_id,m.sub_system,m.tag_name,description, '' as unit_id,'mix' AS table_name,state_text_name,mc.ctrl_act_name"
" from mix m INNER JOIN mix_control mc ON m.tag_name=mc.tag_name "+sCondition;
QString cntSql=QString("select count(1) from ( %1 ) as cnt_query").arg(sql);
if ( !objDbConn.execute( cntSql, objQuery ))
{
LOGERROR( "getControlCodeInfoByDevice(): 查询错误SQL语句如下\n%s", cntSql.toUtf8().constData());
const char *szMsg = "db query faild";
controlPointListdto->message = szMsg;
return createDtoResponse( Status::CODE_201, controlPointListdto );
}
int totalCnt{0};
while ( objQuery.next())
{
totalCnt = objQuery.value( 0 ).toString().toInt();
}
if( totalCnt == 0)
{
return createDtoResponse( Status::CODE_200, controlPointListdto );
}
controlPointListdto->total = totalCnt / pageSize + 1;
controlPointListdto->pageSize = pageSize;
controlPointListdto->page = page;
QString pageSql=QString("select location_id,sub_system,tag_name,description, unit_id,table_name,state_text_name,ctrl_act_name from (%1) as page_query limit %2 offset %3 ").arg(sql).arg(QString::number(pageSize)).arg(QString::number( pageSize *(page- 1 )));
if ( !objDbConn.execute( pageSql, objQuery ))
{
LOGERROR( "getControlCodeInfoByDevice(): 查询错误SQL语句如下\n%s", pageSql.toUtf8().constData());
const char *szMsg = "db query faild";
controlPointListdto->message = szMsg;
return createDtoResponse( Status::CODE_201, controlPointListdto );
}
//如果三个表出现相同的tag则需要修改逻辑
QMap<QString,TagTuple> tagDataMap;
while(objQuery.next())
{
tagDataMap[objQuery.value("tag_name").toString()]={
objQuery.value("unit_id").toString().toInt(),
objQuery.value("table_name").toString(),
objQuery.value("description").toString(),
objQuery.value("state_text_name").toString(),
objQuery.value("ctrl_act_name").toString()
};
}
//查询influxdb最新值
QStringList listTag;
std::vector<SMeasPointKey> vecKey;
listTag=tagDataMap.keys();
for(auto it = tagDataMap.cbegin(); it != tagDataMap.cend(); ++it)
{
SMeasPointKey stPointKey;
if((*it).tableName=="analog")
{
stPointKey.m_enType = MPT_AI;
}else if((*it).tableName=="digital")
{
stPointKey.m_enType = MPT_DI;
}else if((*it).tableName=="mix")
{
stPointKey.m_enType = MPT_MIX;
}
std::string tag_tmp = it.key().toStdString();
char * tag = (char*)malloc(tag_tmp.size() + 1);
memset(tag, 0, tag_tmp.size() + 1);
memcpy(tag, tag_tmp.c_str(), tag_tmp.size());
stPointKey.m_pszTagName = tag;
vecKey.push_back( stPointKey );
}
QDateTime dtStart(QDateTime::currentDateTime().date(),QTime(0,0,0));
QDateTime dtEnd=QDateTime::currentDateTime();
CTsdbConnPtr pTsdbConn = iot_dbms::getOneUseableConn(true);
std::vector<std::vector<SVarHisSamplePoint> *> vecResult;
for ( size_t i=0; i<vecKey.size(); i++ )
vecResult.push_back( new std::vector<SVarHisSamplePoint>() );
if ( !getHisSamplePoint(*pTsdbConn, 10000,
vecKey,
dtStart.toMSecsSinceEpoch(), dtEnd.toMSecsSinceEpoch(),
NULL,
NULL,
CM_LAST,
0, FM_NULL_METHOD,
vecResult) )
{
LOGINFO("getHisSamplePoint 查询失败");
const char *szMsg = "influxdb query faild";
controlPointListdto->message = szMsg;
return createDtoResponse( Status::CODE_201, controlPointListdto );
}
for (size_t i=0; i<vecResult.size(); i++)
{
std::vector<SVarHisSamplePoint>* pVecPoint = vecResult.at(i);
auto pointdto=pointDTO::createShared();
pointdto->tagName=vecKey.at(i).m_pszTagName;
QString key=QString(vecKey.at(i).m_pszTagName);
pointdto->unitName=unitMap[tagDataMap[key].unitId];
pointdto->desc=tagDataMap[key].desc.toStdString();
pointdto->stateTxt=tagDataMap[key].stateTxt.toStdString();
pointdto->ctlTxt=tagDataMap[key].ctrlActName.toStdString();
if(tagDataMap[key].tableName=="analog")
{
pointdto->tagType = MPT_AI;
}else if(tagDataMap[key].tableName=="digital")
{
pointdto->tagType = MPT_DI;
}else if(tagDataMap[key].tableName=="mix")
{
pointdto->tagType = MPT_MIX;
}
for(size_t l=0; l<pVecPoint->size(); l++)
{
const SVarHisSamplePoint& objPoint = pVecPoint->at(l);
double dVal = 0.0f;
if (typeid(boost::int32_t) == objPoint.m_varValue.type())
dVal = (double)boost::get<boost::int32_t>(objPoint.m_varValue);
else if (typeid(boost::float64_t) == objPoint.m_varValue.type())
dVal = (double)boost::get<boost::float64_t>(objPoint.m_varValue);
else
{
LOGERROR("tag:%s Invalid data type of SVarHisSamplePoint.m_varValue ",vecKey.at(i).m_pszTagName);
}
pointdto->value=QString::number(dVal).toStdString();
}
controlPointListdto->rows->insert(controlPointListdto->rows->end(),pointdto);
}
return createDtoResponse( Status::CODE_200, controlPointListdto);
}
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> CSimpleController::deviceControl( const oatpp::String &strReq,const std::shared_ptr<IncomingRequest> &request)
{
auto dcResp = deviceControlReponseDTO::createShared();
auto perm_mng_api = getSessionApi()->getCurPermApi( request );
if ( nullptr == perm_mng_api )
{
LOGERROR( "perm_mng_api is nullptr!" );
const char *szMsg = " 解析session失败";
dcResp->message = szMsg;
return createDtoResponse( Status::CODE_500, dcResp );
}
int nUserId, nUserGrpId, nLevel, nLoginSec;
std::string strInstanceName;
if ( PERM_NORMAL != perm_mng_api->CurUser( nUserId, nUserGrpId, nLevel, nLoginSec, strInstanceName ))
{
LOGERROR( "cannot query cur-user" );
const char *szMsg = " 查询用户失败";
dcResp->message = szMsg;
return createDtoResponse( Status::CODE_201, dcResp);
}
auto spReq = getDefaultObjectMapper()->readFromString< oatpp::Object<deviceControlRequestDTO> >( strReq );
if ( !spReq )
{
LOGERROR( "deviceControl(): 请求解析失败,请求内容:%s", strReq->c_str());
const char *szMsg = " 请求解析失败";
dcResp->message = szMsg;
return createDtoResponse( Status::CODE_201, dcResp );
}
iot_dbms::CDbApi objDbConn( DB_CONN_MODEL_READ );
if ( !objDbConn.open())
{
const char *szMsg = "db open faild";
LOGERROR( "%s", szMsg );
dcResp->message = szMsg;
return createDtoResponse( Status::CODE_201, dcResp );
}
int locationId=spReq->locationId;
QString strSql=QString("select domain_id from sys_model_location_info where location_id=%1 ").arg(locationId);
QSqlQuery objQuery;
if ( !objDbConn.execute( strSql, objQuery ))
{
LOGERROR( "deviceControl(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
const char *szMsg = "db query faild";
dcResp->message = szMsg;
return createDtoResponse( Status::CODE_201, dcResp );
}
int domianId;
while ( objQuery.next())
{
domianId=objQuery.value( 0 ).toString().toInt();
}
CMsgDeal msgDeal(spReq->appId);
SOptCtrlRequest socReq;
SOptReqHead stHead;
std::string stdStr(spReq->controlSrc->c_str(), spReq->controlSrc->size());
QString strChain=QString("%1:%2:web_server:modelue_operate:deviceControl").arg(QString::fromStdString(stdStr)).arg(msgDeal.getNodeName());
stHead.strSrcTag=strChain.toStdString();
stHead.nSrcDomainID=domianId;
stHead.nDstDomainID=domianId;
stHead.nAppID=spReq->appId;
stHead.strInstName=msgDeal.getNodeName().toStdString();
stHead.strHostName="web_server";
stHead.strCommName=msgDeal.getSendCMbName().toStdString();
stHead.nUserID=nUserId;
stHead.nUserGroupID=nUserGrpId;
stHead.nOptTime=QDateTime::currentDateTime().currentMSecsSinceEpoch();
socReq.stHead=stHead;
for(auto it = spReq->data->cbegin(); it != spReq->data->cend(); ++it)
{
SOptCtrlReqQueue sosRq;
if((*it)->tagType == MPT_AI)
{
sosRq.strKeyIdTag=("analog."+(*it)->tagName+".value")->c_str();
}else if((*it)->tagType == MPT_DI)
{
sosRq.strKeyIdTag=("digital."+(*it)->tagName+".value")->c_str();
}else if((*it)->tagType == MPT_MIX)
{
sosRq.strKeyIdTag=("mix."+(*it)->tagName+".value")->c_str();
}
sosRq.nCtrlType=1;
sosRq.dTargetValue=QString::fromStdString((*it)->value).toDouble();
socReq.vecOptCtrlQueue.push_back(sosRq);
}
std::string content = COptCtrlRequest::generate(socReq);
//发送总线消息
if(1!=msgDeal.SendMessage(CH_HMI_TO_OPT_OPTCMD_DOWN,MT_OPT_CTRL_DOWN_EXECUTE,content,domianId))
{
LOGERROR( "deviceControl(): 命令发送失败,遥控内容:%s", content.c_str());
const char *szMsg = " 命令发送失败";
dcResp->message = szMsg;
return createDtoResponse( Status::CODE_201, dcResp );
}
//接受响应消息
QString result;
std::string messages;
int msgRes=msgDeal.RevMessage(MT_OPT_CTRL_UP_EXECUTE_REPLY,result,messages,socReq);
if(0==msgRes)
{
dcResp->message = messages.c_str();
return createDtoResponse( Status::CODE_200, dcResp );
}
else if(1==msgRes)
{
LOGERROR( "deviceControl():结果解析失败,遥控内容:%s", content.c_str());
const char *szMsg = "响应结果解析失败";
dcResp->message = szMsg;
dcResp->code=500;
return createDtoResponse( Status::CODE_201, dcResp );
}else if(3==msgRes)
{
LOGERROR( "deviceControl():命令无响应,遥控内容:%s", content.c_str());
const char *szMsg = "命令无响应";
dcResp->message = szMsg;
dcResp->code=500;
return createDtoResponse( Status::CODE_201, dcResp );
}
else{
LOGERROR( "deviceControl(): 命令执行失败,遥控内容:%s,遥控结果:%s", content.c_str(),result.toStdString().c_str());
messages="执行失败:"+messages;
const char *szMsg = messages.c_str();
dcResp->message = szMsg;
dcResp->code=500;
return createDtoResponse( Status::CODE_201, dcResp );
}
}
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> CSimpleController::customQuery( const oatpp::String &strReq,const std::shared_ptr<IncomingRequest> &request)
{
auto dcResp = customQueryReponseDTO::createShared();
dcResp->data={};
auto perm_mng_api = getSessionApi()->getCurPermApi( request );
if ( nullptr == perm_mng_api )
{
LOGERROR( "perm_mng_api is nullptr!" );
const char *szMsg = " 解析session失败";
dcResp->message = szMsg;
return createDtoResponse( Status::CODE_500, dcResp );
}
int nUserId, nUserGrpId, nLevel, nLoginSec;
std::string strInstanceName;
if ( PERM_NORMAL != perm_mng_api->CurUser( nUserId, nUserGrpId, nLevel, nLoginSec, strInstanceName ))
{
LOGERROR( "cannot query cur-user" );
const char *szMsg = " 查询用户失败";
dcResp->message = szMsg;
return createDtoResponse( Status::CODE_201, dcResp);
}
auto spReq = getDefaultObjectMapper()->readFromString< oatpp::Object<customQueryRequestDTO> >( strReq );
if ( !spReq )
{
LOGERROR( "customQuery(): 请求解析失败,请求内容:%s", strReq->c_str());
const char *szMsg = " 请求解析失败";
dcResp->message = szMsg;
return createDtoResponse( Status::CODE_201, dcResp );
}
iot_dbms::CDbApi objDbConn( DB_CONN_MODEL_READ );
if ( !objDbConn.open())
{
const char *szMsg = "db open faild";
LOGERROR( "%s", szMsg );
dcResp->message = szMsg;
return createDtoResponse( Status::CODE_201, dcResp );
}
int locationId=spReq->locationId;
int commType = spReq->commType; //用于区分自定义命令类型
QString strSql=QString("select domain_id from sys_model_location_info where location_id=%1 ").arg(locationId);
QSqlQuery objQuery;
if ( !objDbConn.execute( strSql, objQuery ))
{
LOGERROR( "customQuery(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
const char *szMsg = "db query faild";
dcResp->message = szMsg;
return createDtoResponse( Status::CODE_201, dcResp );
}
int domianId;
while ( objQuery.next())
{
domianId=objQuery.value( 0 ).toString().toInt();
}
std::string devStr(spReq->devTag->c_str(), spReq->devTag->size());
//取其中一条来找前置设备名
strSql=QString("select dev_tag from fes_digital where location_id=%1 and app_tag_name LIKE '%2%' LIMIT 1 ").arg(locationId).arg(QString::fromStdString(devStr));
if ( !objDbConn.execute( strSql, objQuery ))
{
LOGERROR( "customQuery(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
const char *szMsg = "db query faild";
dcResp->message = szMsg;
return createDtoResponse( Status::CODE_201, dcResp );
}
QString fesDevStr="";
while ( objQuery.next())
{
fesDevStr=objQuery.value( 0 ).toString();
}
strSql=QString("select tag_name,rtu_tag from fes_const where location_id=%1 and dev_tag='%2' ").arg(locationId).arg(fesDevStr);
if ( !objDbConn.execute( strSql, objQuery ))
{
LOGERROR( "customQuery(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
const char *szMsg = "db query faild";
dcResp->message = szMsg;
return createDtoResponse( Status::CODE_201, dcResp );
}
QList<QPair<QString, QString>> tagList;
while ( objQuery.next())
{
tagList.append(QPair<QString, QString>(objQuery.value( 0 ).toString(), objQuery.value( 1 ).toString()));
}
CMsgDeal msgDeal(spReq->appId);
SOptCustCtrlRequest socReq;
SOptReqHead stHead;
std::string stdStr(spReq->controlSrc->c_str(), spReq->controlSrc->size());
QString strChain=QString("%1:%2:web_server:modelue_operate:customQuery").arg(QString::fromStdString(stdStr)).arg(msgDeal.getNodeName());
stHead.strSrcTag=strChain.toStdString();
stHead.nSrcDomainID=domianId;
stHead.nDstDomainID=domianId;
stHead.nAppID=spReq->appId;
stHead.strInstName=msgDeal.getNodeName().toStdString();
stHead.strHostName="web_server";
stHead.strCommName=msgDeal.getSendCMbName().toStdString();
stHead.nUserID=nUserId;
stHead.nUserGroupID=nUserGrpId;
stHead.nOptTime=QDateTime::currentDateTime().currentMSecsSinceEpoch();
socReq.stHead=stHead;
SOptCustCtrlQueue commInfo; //用于自定义查询存放命令;
commInfo.strKeyName = "CustomType";
commInfo.strKeyValue = std::to_string(commType);
socReq.vecOptCustCtrlQueue.push_back(commInfo);
if(0==tagList.size())
{
LOGERROR( "customQuery(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
const char *szMsg = "custom config bad";
dcResp->message = szMsg;
return createDtoResponse( Status::CODE_201, dcResp );
}
for (int i = 0; i < tagList.size(); ++i)
{
//接受响应消息
QString result;
std::string messages;
SOptCustCtrlReply socr;
socReq.strKeyIdTag="fes_const."+tagList[i].first.toStdString()+".value";
socReq.strRtuTag=tagList[i].second.toStdString();
std::string content = COptCustCtrlRequest::generate(socReq);
//发送总线消息
if(1!=msgDeal.SendMessage(CH_HMI_TO_OPT_OPTCMD_DOWN,MT_OPT_COMMON_DOWN,content,domianId))
{
LOGERROR( "customQuery(): 命令发送失败,遥控内容:%s", content.c_str());
const char *szMsg = " 命令发送失败";
dcResp->message = szMsg;
return createDtoResponse( Status::CODE_201, dcResp );
}
int msgRes=msgDeal.RevMessage(MT_OPT_COMMON_UP,result,messages,socReq,socr);
if(0==msgRes)
{
for(auto it=socr.vecOptCustCtrlQueue.begin();it!=socr.vecOptCustCtrlQueue.end();++it)
{
SOptCustCtrlQueue info=*(it);
oatpp::Fields<oatpp::String> kv=oatpp::Fields<oatpp::String>::createShared();
kv["key"]=info.strKeyName;
kv["value"]=info.strKeyValue;
dcResp->data->insert(dcResp->data->end(),kv);
}
}
else if(1==msgRes)
{
LOGERROR( "customQuery():结果解析失败,遥控内容:%s", content.c_str());
const char *szMsg = "响应结果解析失败";
dcResp->message = szMsg;
dcResp->code=500;
return createDtoResponse( Status::CODE_201, dcResp );
}else if(3==msgRes)
{
LOGERROR( "customQuery():命令无响应,遥控内容:%s", content.c_str());
const char *szMsg = "命令无响应";
dcResp->message = szMsg;
dcResp->code=500;
return createDtoResponse( Status::CODE_201, dcResp );
}
else{
LOGERROR( "customQuery(): 命令执行失败,遥控内容:%s,遥控结果:%s", content.c_str(),result.toStdString().c_str());
messages="执行失败:"+messages;
const char *szMsg = messages.c_str();
dcResp->message = szMsg;
dcResp->code=500;
return createDtoResponse( Status::CODE_201, dcResp );
}
}
return createDtoResponse( Status::CODE_200, dcResp );
}
}
}

View File

@ -0,0 +1,56 @@
#pragma once
#include "oatpp/core/macro/component.hpp"
#include "oatpp/web/server/api/ApiController.hpp"
#include "QString"
#include "db_api_ex/CDbApi.h"
#include <../include/SessionApi.h>
#include OATPP_CODEGEN_BEGIN( ApiController )
namespace web_server {
namespace module_operate{
class CSimpleController: public oatpp::web::server::api::ApiController
{
public:
CSimpleController( OATPP_COMPONENT(std::shared_ptr<ObjectMapper>,objectMapper) )
: oatpp::web::server::api::ApiController( objectMapper )
{}
~CSimpleController()
{}
private:
bool deviceHasControl(iot_dbms::CDbApi& objDbConn,QString deviceTag);
bool deviceHasConst(iot_dbms::CDbApi& objDbConn,QString deviceTag);
public:
/**
* @brief
*/
ENDPOINT("GET", "/operate/getControlDeviceByDeviceGroup", getControlDeviceByDeviceGroup,
QUERY( String, deviceGroupTag,"deviceGroupTag","")
);
/**
* @brief
*/
ENDPOINT("GET", "/operate/getControlCodeInfoByDevice", getControlCodeInfoByDevice,
QUERY( String, deviceTag,"deviceTag",""),
QUERY( Int32, page,"page",1),
QUERY( Int32, pageSize,"pageSize",30)
);
/**
* @brief
*/
ENDPOINT("POST", "/operate/deviceControl", deviceControl, BODY_STRING( String, strReq ),REQUEST(std::shared_ptr<IncomingRequest>, request)) ;
/**
* @brief
*/
ENDPOINT("POST", "/operate/customQuery", customQuery, BODY_STRING( String, strReq ),REQUEST(std::shared_ptr<IncomingRequest>, request)) ;
};
}
}
#include OATPP_CODEGEN_END( ApiController )

View File

@ -0,0 +1,114 @@
#pragma once
#include "oatpp/core/macro/codegen.hpp"
#include "oatpp/core/Types.hpp"
#include <QString>
#include OATPP_CODEGEN_BEGIN( DTO )
namespace web_server {
namespace module_operate {
class deviceDTO:public oatpp::DTO
{
DTO_INIT( deviceDTO, DTO )
DTO_FIELD( String, deviceTag );
DTO_FIELD( String, desc );
DTO_FIELD( Int32, type );
};
class deviceGroupInfoDTO:public oatpp::DTO
{
DTO_INIT( deviceGroupInfoDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD( String, message );
DTO_FIELD(List<Object<deviceDTO>> , rows );
};
class pointDTO:public oatpp::DTO
{
DTO_INIT( pointDTO, DTO )
DTO_FIELD(String, tagName );
DTO_FIELD(String, desc );
DTO_FIELD(Int32, tagType );
DTO_FIELD(String, value );
DTO_FIELD(String, unitName );
DTO_FIELD(String, stateTxt );
DTO_FIELD(String, ctlTxt );
};
class controlPointListDTO:public oatpp::DTO
{
DTO_INIT( controlPointListDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD( String, message );
DTO_FIELD( Int32, total );
DTO_FIELD( Int32, page );
DTO_FIELD( Int32, pageSize );
DTO_FIELD(List<Object<pointDTO>> , rows );
};
struct TagTuple {
int unitId;
QString tableName;
QString desc;
QString stateTxt;
QString ctrlActName;
int type;
};
class controlPointDTO:public oatpp::DTO
{
DTO_INIT( controlPointDTO, DTO )
DTO_FIELD( Int32, tagType );
DTO_FIELD( String, value );
DTO_FIELD( String, tagName );
};
class deviceControlRequestDTO:public oatpp::DTO
{
DTO_INIT( deviceControlRequestDTO, DTO )
DTO_FIELD( Int32, appId );
DTO_FIELD( Int32, locationId );
DTO_FIELD( String, controlSrc );
DTO_FIELD(List<Object<controlPointDTO>> , data );
};
class deviceControlReponseDTO:public oatpp::DTO
{
DTO_INIT( deviceControlReponseDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD( String, message );
};
class customQueryRequestDTO:public oatpp::DTO
{
DTO_INIT( customQueryRequestDTO, DTO )
DTO_FIELD( Int32, locationId );
DTO_FIELD( Int32, appId );
DTO_FIELD( Int32, commType );
DTO_FIELD( String, controlSrc );
DTO_FIELD( String, devTag );
};
class customQueryReponseDTO:public oatpp::DTO
{
DTO_INIT( customQueryReponseDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD( String, message );
DTO_FIELD( List<Fields<String> >, data ) = {};
};
}
}
#include OATPP_CODEGEN_END( DTO )

View File

@ -0,0 +1,42 @@
#-------------------------------------------------
#
# Project created by QtCreator 2024-07-25T14:57:04
# 该模块为web提供控制功能的模块
#-------------------------------------------------
QT += sql
TARGET = module_operate
TEMPLATE = lib
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \
CModule.cpp \
CSimpleController.cpp \
CMsgDeal.cpp
HEADERS += \
../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \
../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \
CModule.h \
CSimpleController.h \
DTOs.hpp \
CMsgDeal.h
#静态库不要连接统一在server中连接
#LIBS +=
#-------------------------------------------------------------------
#所有web_server的模块应包含此pri无需包含common.pri
MODULE_PRI=$$PWD/../module.pri
exists($$MODULE_PRI) {
include($$MODULE_PRI)
}else {
error("FATAL error: can not find module.pri")
}

View File

@ -0,0 +1,42 @@
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include "CModule.h"
#include "CSimpleController.h"
using namespace web_server::module_statistics;
bool CModule::init()
{
//< todo 按oatpp的注释貌似依赖注入和获取区分线程尚未验证
//< todo 本程序依赖注入在主线程中本段代码在主线程中执行没有问题不知在其他线程中获取注入的component是否有问题
OATPP_COMPONENT( std::shared_ptr<oatpp::web::server::HttpRouter>, router, "simpleRouter" );
router->addController( std::make_shared<CSimpleController>());
//< todo 初始化业务资源,比如自己的线程
return true;
}
bool CModule::redundantSwitch( bool bMaster, bool bSlave )
{
//< 避免参数未使用编译告警
( void ) bMaster;
( void ) bSlave;
//< todo 按业务需求启、停自己的线程等
return true;
}
bool CModule::clean()
{
//< todo 貌似没有 addController 的逆操作
//< todo 清理业务资源
return true;
}
boost::shared_ptr<CModule> CModule::create()
{
return boost::make_shared<CModule>();
}

View File

@ -0,0 +1,21 @@
#pragma once
#include "../include/BaseModule.h"
namespace web_server { namespace module_statistics
{
class CModule final : public CBaseModule
{
public:
CModule() = default;
~CModule() override = default;
public:
bool init() override;
bool redundantSwitch( bool bMaster, bool bSlave ) override;
bool clean() override;
static boost::shared_ptr<CModule> create();
};
}}

View File

@ -0,0 +1,756 @@
#include "CSimpleController.h"
#include "dbms/db_his_query_api/DbHisQueryApi.h"
#include "DTOs.hpp"
#include <QDateTime>
#include "db_api_ex/CDbApi.h"
#include <QtSql/QSql>
#include "public/pub_logger_api/logger.h"
#include "tsdb_api/TsdbApi.h"
#include "dbms/db_his_query_api/DbHisQueryBase.h"
#include "CTsdbQuery.h"
using namespace iot_dbms;
using namespace web_server::module_statistics;
namespace web_server {
namespace module_statistics {
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> CSimpleController::queryLocationStatistics(
const oatpp::String & filterStr,
const oatpp::Int32 & locationId
)
{
auto locationStatResponsedto=locationStatResponseDTO::createShared();
iot_dbms::CDbApi objDbConn( DB_CONN_MODEL_READ );
if ( !objDbConn.open())
{
const char *szMsg ="db open faild";
LOGERROR( "%s", szMsg );
locationStatResponsedto->message = szMsg;
return createDtoResponse( Status::CODE_201, locationStatResponsedto );
}
QString strSql;
strSql=QString("select location_id,tag_name,description from sys_model_location_info where location_id=%1 ").arg(locationId);
QSqlQuery objQuery;
if ( !objDbConn.execute( strSql, objQuery ))
{
LOGERROR( "queryLocationStatistics(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
const char *szMsg = "db query faild";
locationStatResponsedto->message = szMsg;
return createDtoResponse( Status::CODE_201, locationStatResponsedto );
}
auto locationStatdto=locationStatDTO::createShared();
locationStatResponsedto->data=locationStatdto;
locationStatdto->data={};
while ( objQuery.next())
{
locationStatdto->id = objQuery.value( 0 ).toString().toInt();
locationStatdto->tagName =objQuery.value( 1 ).toString().toStdString();
locationStatdto->locationName =objQuery.value( 2 ).toString().toStdString();
}
//查询单位
QMap<int,String> unitMap;
strSql="select unit_id,unit_name from dict_unit_info";
if ( !objDbConn.execute( strSql, objQuery ))
{
LOGERROR( "queryLocationStatistics(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
const char *szMsg = "db query faild";
locationStatResponsedto->message = szMsg;
return createDtoResponse( Status::CODE_201, locationStatResponsedto );
}
while ( objQuery.next())
{
unitMap[objQuery.value( 0 ).toString().toInt()]=objQuery.value( 1 ).toString().toStdString();
}
//根据字符串查询所有表字符串的表--累积量
QMap<QString,TagTuple> tagDataMap;
QString tableName="accuml";
std::string stdStr(filterStr->c_str(), filterStr->size());
QString locationCondition=QString(" location_id=%1 ").arg(locationId);
strSql="select tag_name,unit_id,description from "+tableName+" where "+ locationCondition +" and tag_name like '%"+QString::fromStdString(stdStr)+"%'";
if ( !objDbConn.execute( strSql, objQuery ))
{
LOGERROR( "queryLocationStatistics(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
const char *szMsg = "db query faild";
locationStatResponsedto->message = szMsg;
return createDtoResponse( Status::CODE_201, locationStatResponsedto );
}
while ( objQuery.next())
{
tagDataMap.insert(objQuery.value( 0 ).toString(),{objQuery.value( 1 ).toString().toInt(),objQuery.value( 2 ).toString()});
}
//进行influxdb查询
QStringList listTag;
listTag=tagDataMap.keys();
std::vector<SMeasPointKey> vecKey;
for(auto it = tagDataMap.cbegin(); it != tagDataMap.cend(); ++it)
{
SMeasPointKey stPointKey;
stPointKey.m_enType = MPT_ACC;
std::string tag_tmp = it.key().toStdString();
char * tag = (char*)malloc(tag_tmp.size() + 1);
memset(tag, 0, tag_tmp.size() + 1);
memcpy(tag, tag_tmp.c_str(), tag_tmp.size());
stPointKey.m_pszTagName = tag;
vecKey.push_back( stPointKey );
}
if(vecKey.size() <= 0)
{
LOGERROR("queryLocationStatistics tag-key is null");
const char *szMsg = "无有效的key";
locationStatResponsedto->message = szMsg;
return createDtoResponse( Status::CODE_201, locationStatResponsedto );
}
QDateTime currentDateTime = QDateTime::currentDateTime();
QDate currentDate = currentDateTime.date();
QDateTime startOfDay(currentDate, QTime(0, 0, 0));
// 获取tsdb连接
CTsdbConnPtr pTsdbConn = iot_dbms::getOneUseableConn(true);
if ( !pTsdbConn )
{
LOGERROR("getOneUseableConn() return NULL !");
return createDtoResponse( Status::CODE_201, locationStatResponsedto );
}
std::vector<std::vector<SVarHisSamplePoint> *> vecResult;
for ( size_t i=0; i<vecKey.size(); i++ )
vecResult.push_back( new std::vector<SVarHisSamplePoint>() );
if ( !getHisSamplePoint(*pTsdbConn, 10000,
vecKey,
startOfDay.toMSecsSinceEpoch(), currentDateTime.toMSecsSinceEpoch(),
NULL,
NULL,
CM_LAST,
0, FM_NULL_METHOD,
vecResult) )
{
LOGINFO("queryLocationStatistics-getHisSamplePoint 查询失败");
}
for (size_t i=0; i<vecResult.size(); i++)
{
std::vector<SVarHisSamplePoint>* pVecPoint = vecResult.at(i);
auto historyDatadto=historyDataDTO::createShared();
historyDatadto->tagName=vecKey.at(i).m_pszTagName;
QString key=QString(vecKey.at(i).m_pszTagName);
historyDatadto->unitName=unitMap[tagDataMap[key].unitId];
historyDatadto->desc=tagDataMap[key].description.toStdString();
for(size_t l=0; l<pVecPoint->size(); l++)
{
const SVarHisSamplePoint& objPoint = pVecPoint->at(l);
double dVal = 0.0f;
if (typeid(boost::int32_t) == objPoint.m_varValue.type())
dVal = (double)boost::get<boost::int32_t>(objPoint.m_varValue);
else if (typeid(boost::float64_t) == objPoint.m_varValue.type())
dVal = (double)boost::get<boost::float64_t>(objPoint.m_varValue);
else
{
LOGERROR("tag:%s Invalid data type of SVarHisSamplePoint.m_varValue ",vecKey.at(i).m_pszTagName);
}
historyDatadto->value=dVal;
}
locationStatdto->data->insert(locationStatdto->data->end(),historyDatadto);
}
return createDtoResponse( Status::CODE_200, locationStatResponsedto );
}
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> CSimpleController::getCodeByLocation(
const oatpp::String & filterStr,
const oatpp::Int32 & locationId,
const oatpp::Int32 & page,
const oatpp::Int32 & pageSize
)
{
auto locationPointCodeListdto=locationPointCodeListDTO::createShared();
locationPointCodeListdto->rows={};
iot_dbms::CDbApi objDbConn( DB_CONN_MODEL_READ );
QSqlQuery objQuery;
if ( !objDbConn.open())
{
const char *szMsg = "db open faild";
LOGERROR( "%s", szMsg );
locationPointCodeListdto->message = szMsg;
return createDtoResponse( Status::CODE_201, locationPointCodeListdto );
}
//查询单位
QMap<int,String> unitMap;
QString strSql="select unit_id,unit_name from dict_unit_info";
if ( !objDbConn.execute( strSql, objQuery ))
{
LOGERROR( "getCodeByLocation(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
const char *szMsg = "db query faild";
locationPointCodeListdto->message = szMsg;
return createDtoResponse( Status::CODE_201, locationPointCodeListdto );
}
while ( objQuery.next())
{
unitMap[objQuery.value( 0 ).toString().toInt()]=objQuery.value( 1 ).toString().toStdString();
}
std::string stdStr(filterStr->c_str(), filterStr->size());
QString sFilterStr=QString::fromStdString(stdStr);
QString sCondition;
if(sFilterStr.isEmpty())
{
sCondition=QString(" where location_id=%1").arg(locationId);
}else{
sCondition=QString(" where location_id=%1 and tag_name like '%%2%' ").arg(locationId).arg(sFilterStr);
}
QString sql="SELECT location_id,sub_system,tag_name,description, unit_id,'accuml' AS table_name"
" from accuml "+sCondition+
" union "
"SELECT location_id,sub_system,tag_name,description, unit_id,'analog' AS table_name"
" from analog "+sCondition+
" union "
"SELECT location_id,sub_system,tag_name,description, '' as unit_id,'digital' AS table_name"
" from digital "+sCondition+
" union "
"SELECT location_id,sub_system,tag_name,description, '' as unit_id,'mix' AS table_name"
" from mix "+sCondition;
QString cntSql=QString("select count(1) from (%1) as cnt_query").arg(sql);
if ( !objDbConn.execute( cntSql, objQuery ))
{
LOGERROR( "getCodeByLocation(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
const char *szMsg = "db query faild";
locationPointCodeListdto->message = szMsg;
return createDtoResponse( Status::CODE_201, locationPointCodeListdto );
}
int totalCnt{0};
while ( objQuery.next())
{
totalCnt = objQuery.value( 0 ).toString().toInt();
}
if( totalCnt == 0)
{
return createDtoResponse( Status::CODE_200, locationPointCodeListdto );
}
locationPointCodeListdto->total = totalCnt / pageSize + 1;
locationPointCodeListdto->pageSize = pageSize;
locationPointCodeListdto->page = page;
QString pageSql=QString("select location_id,sub_system,tag_name,description, unit_id,table_name from (%1) as page_query limit %2 offset %3 ").arg(sql)
.arg(QString::number(pageSize)).arg(QString::number( pageSize *(page- 1 )));
if ( !objDbConn.execute( pageSql, objQuery ))
{
LOGERROR( "getCodeByLocation(): 查询错误SQL语句如下\n%s", pageSql.toUtf8().constData());
const char *szMsg = "db query error";
locationPointCodeListdto->message = szMsg;
return createDtoResponse( Status::CODE_201, locationPointCodeListdto );
}
while(objQuery.next())
{
auto pointCodedto= pointCodeDTO::createShared();
pointCodedto->tagName = objQuery.value("tag_name").toString().toStdString();
pointCodedto->desc = objQuery.value("description").toString().toStdString();
pointCodedto->unitName = unitMap[ objQuery.value("unit_id").toString().toInt()];
QString tableName=objQuery.value("table_name").toString();
if(tableName=="analog")
{
pointCodedto->type=EnMeasPiontType::MPT_AI;
}else if(tableName=="accuml")
{
pointCodedto->type=EnMeasPiontType::MPT_DI;
}else if(tableName=="digital")
{
pointCodedto->type=EnMeasPiontType::MPT_MIX;
}else if(tableName=="mix")
{
pointCodedto->type=EnMeasPiontType::MPT_ACC;
}else
{
LOGERROR( "getCodeByLocation(): 查询错误-point-type-missSQL语句如下\n%s", pageSql.toUtf8().constData());
const char *szMsg = "point type miss";
locationPointCodeListdto->message = szMsg;
return createDtoResponse( Status::CODE_201, locationPointCodeListdto );
}
locationPointCodeListdto->rows->insert(locationPointCodeListdto->rows->end(),pointCodedto);
}
return createDtoResponse( Status::CODE_200, locationPointCodeListdto );
}
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> CSimpleController::queryLocationDataSeries( const oatpp::String &strReq)
{
auto ldResp = locationDataSeriesReponseDTO::createShared();
ldResp->rows={};
auto spReq = getDefaultObjectMapper()->readFromString< oatpp::Object<locationDataSeriesRequestDTO> >( strReq );
if ( !spReq )
{
LOGERROR( "queryLocationDataSeries(): 请求解析失败,请求内容:%s", strReq->c_str());
const char *szMsg = " 请求解析失败";
ldResp->message = szMsg;
return createDtoResponse( Status::CODE_201, ldResp );
}
std::vector<SMeasPointKey> vecKey;
for(auto it = spReq->tags->cbegin(); it != spReq->tags->cend(); ++it)
{
SMeasPointKey stPointKey;
if((*it)->type == MPT_AI)
{
stPointKey.m_enType = MPT_AI;
}else if((*it)->type == MPT_DI)
{
stPointKey.m_enType = MPT_DI;
}else if((*it)->type == MPT_MIX)
{
stPointKey.m_enType = MPT_MIX;
}
stPointKey.m_pszTagName =(*it)->tagName->c_str();
vecKey.push_back( stPointKey );
}
std::string stdYearStr(spReq->year->c_str(), spReq->year->size());
QString sYear=QString::fromStdString(stdYearStr);
std::string stdMonthStr(spReq->month->c_str(), spReq->month->size());
QString sMonth=QString::fromStdString(stdMonthStr);
std::string stdDayStr(spReq->day->c_str(), spReq->day->size());
QString sDay=QString::fromStdString(stdDayStr);
std::vector<std::vector<QPair<VALUE_STATUS, double>>> allData;
CTsdbQuery tdbQuery;
auto ret=tdbQuery.queryTagByTimeType(QString("%1-%2-%3").arg(sYear).arg(sMonth).arg(sDay),spReq->timeType,vecKey,allData);
if(!ret)
{
LOGERROR( "queryLocationDataSeries():query influxdb faild请求内容%s", strReq->c_str());
const char *szMsg = " query influxdb faild";
ldResp->message = szMsg;
return createDtoResponse( Status::CODE_201, ldResp );
};
//列向获取同一个测点的数据
size_t col=allData[0].size();
size_t row=allData.size();
for(int i=0;i<col;i++)
{
auto unitdto=dataSeriesUnitDTO::createShared();
unitdto->tagName= spReq->tags[i]->tagName;
unitdto->data={};
for(int j=0;j<row;j++)
{
unitdto->data->insert(unitdto->data->end(),allData[j][i].second);
}
ldResp->rows->insert(ldResp->rows->end(),unitdto);
}
return createDtoResponse( Status::CODE_200, ldResp );
}
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> CSimpleController::queryDeviceGroupStatistics(
const oatpp::String & filterStr,
const oatpp::String & deviceGroupTag
)
{
auto deviceGroupStatResponsedto=deviceGroupStatResponseDTO::createShared();
auto deviceGroupStatdto=deviceGroupStatDTO::createShared();
deviceGroupStatResponsedto->data=deviceGroupStatdto;
QSqlQuery objQuery;
iot_dbms::CDbApi objDbConn( DB_CONN_MODEL_READ );
if ( !objDbConn.open())
{
const char *szMsg ="db open faild";
LOGERROR( "%s", szMsg );
deviceGroupStatResponsedto->message = szMsg;
return createDtoResponse( Status::CODE_201, deviceGroupStatResponsedto );
}
//查询单位
QMap<int,String> unitMap;
QString strSql="select unit_id,unit_name from dict_unit_info";
if ( !objDbConn.execute( strSql, objQuery ))
{
LOGERROR( "queryDeviceGroupStatistics(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
const char *szMsg = "db query faild";
deviceGroupStatResponsedto->message = szMsg;
return createDtoResponse( Status::CODE_201, deviceGroupStatResponsedto );
}
while ( objQuery.next())
{
unitMap[objQuery.value( 0 ).toString().toInt()]=objQuery.value( 1 ).toString().toStdString();
}
//查询设备组下的设备
QStringList devices;
std::string devStdStr(deviceGroupTag->c_str(), deviceGroupTag->size());
QString deviceGroupCondition=QString("where group_tag_name='%1' ").arg(QString::fromStdString(devStdStr));
strSql="select tag_name from dev_info "+deviceGroupCondition;
if ( !objDbConn.execute( strSql, objQuery ))
{
LOGERROR( "queryLocationStatistics(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
const char *szMsg = "db query faild";
deviceGroupStatResponsedto->message = szMsg;
return createDtoResponse( Status::CODE_201, deviceGroupStatResponsedto );
}
while ( objQuery.next())
{
devices.append(objQuery.value( 0 ).toString());
}
for (int i = 0; i < devices.size(); ++i) {
devices[i] = QString("'%1'").arg(devices[i]);
}
QString sDevice=devices.join(",");
//根据字符串查询所有表字符串的表--累积量
QMap<QString,TagTuple> tagDataMap;
QString tableName="accuml";
std::string stdStr(filterStr->c_str(), filterStr->size());
QString deviceCondition=QString(" device in (%1) ").arg(sDevice);
strSql="select tag_name,unit_id,description from "+tableName+" where "+ deviceCondition +" and tag_name like '%"+QString::fromStdString(stdStr)+"%'";
if ( !objDbConn.execute( strSql, objQuery ))
{
LOGERROR( "queryDeviceGroupStatistics(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
const char *szMsg = "db query faild";
deviceGroupStatResponsedto->message = szMsg;
return createDtoResponse( Status::CODE_201, deviceGroupStatResponsedto );
}
while ( objQuery.next())
{
tagDataMap.insert(objQuery.value( 0 ).toString(),{objQuery.value( 1 ).toString().toInt(),objQuery.value( 2 ).toString()});
}
//进行influxdb查询
QStringList listTag;
listTag=tagDataMap.keys();
std::vector<SMeasPointKey> vecKey;
for(auto it = tagDataMap.cbegin(); it != tagDataMap.cend(); ++it)
{
SMeasPointKey stPointKey;
stPointKey.m_enType = MPT_ACC;
std::string tag_tmp = it.key().toStdString();
char * tag = (char*)malloc(tag_tmp.size() + 1);
memset(tag, 0, tag_tmp.size() + 1);
memcpy(tag, tag_tmp.c_str(), tag_tmp.size());
stPointKey.m_pszTagName = tag;
vecKey.push_back( stPointKey );
}
if(vecKey.size() <= 0)
{
LOGERROR("queryDeviceGroupStatistics tag-key is null");
const char *szMsg = "无有效的key";
deviceGroupStatResponsedto->message = szMsg;
return createDtoResponse( Status::CODE_201, deviceGroupStatResponsedto );
}
QDateTime currentDateTime = QDateTime::currentDateTime();
QDate currentDate = currentDateTime.date();
QDateTime startOfDay(currentDate, QTime(0, 0, 0));
// 获取tsdb连接
CTsdbConnPtr pTsdbConn = iot_dbms::getOneUseableConn(true);
if ( !pTsdbConn )
{
LOGERROR("getOneUseableConn() return NULL !");
return createDtoResponse( Status::CODE_201, deviceGroupStatResponsedto );
}
std::vector<std::vector<SVarHisSamplePoint> *> vecResult;
for ( size_t i=0; i<vecKey.size(); i++ )
vecResult.push_back( new std::vector<SVarHisSamplePoint>() );
if ( !getHisSamplePoint(*pTsdbConn, 10000,
vecKey,
startOfDay.toMSecsSinceEpoch(), currentDateTime.toMSecsSinceEpoch(),
NULL,
NULL,
CM_LAST,
0, FM_NULL_METHOD,
vecResult) )
{
LOGINFO("queryDeviceGroupStatistics-getHisSamplePoint 查询失败");
}
deviceGroupStatdto->data={};
for (size_t i=0; i<vecResult.size(); i++)
{
std::vector<SVarHisSamplePoint>* pVecPoint = vecResult.at(i);
auto historyDatadto=historyDataDTO::createShared();
historyDatadto->tagName=vecKey.at(i).m_pszTagName;
QString key=QString(vecKey.at(i).m_pszTagName);
historyDatadto->unitName=unitMap[tagDataMap[key].unitId];
historyDatadto->desc=tagDataMap[key].description.toStdString();
for(size_t l=0; l<pVecPoint->size(); l++)
{
const SVarHisSamplePoint& objPoint = pVecPoint->at(l);
double dVal = 0.0f;
if (typeid(boost::int32_t) == objPoint.m_varValue.type())
dVal = (double)boost::get<boost::int32_t>(objPoint.m_varValue);
else if (typeid(boost::float64_t) == objPoint.m_varValue.type())
dVal = (double)boost::get<boost::float64_t>(objPoint.m_varValue);
else
{
LOGERROR("tag:%s Invalid data type of SVarHisSamplePoint.m_varValue ",vecKey.at(i).m_pszTagName);
}
historyDatadto->value=dVal;
}
deviceGroupStatdto->data->insert(deviceGroupStatdto->data->end(),historyDatadto);
}
return createDtoResponse( Status::CODE_200, deviceGroupStatResponsedto);
}
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> CSimpleController::getCodeByDeviceGroup(
const oatpp::String & deviceGroupTag,
const oatpp::Int32 & page,
const oatpp::Int32 & pageSize
)
{
auto deviceGroupPointCodeListdto=deviceGroupPointCodeListDTO::createShared();
deviceGroupPointCodeListdto->rows={};
iot_dbms::CDbApi objDbConn( DB_CONN_MODEL_READ );
QSqlQuery objQuery;
if ( !objDbConn.open())
{
const char *szMsg = "db open faild";
LOGERROR( "%s", szMsg );
deviceGroupPointCodeListdto->message = szMsg;
return createDtoResponse( Status::CODE_201, deviceGroupPointCodeListdto );
}
//查询单位
QMap<int,String> unitMap;
QString strSql="select unit_id,unit_name from dict_unit_info";
if ( !objDbConn.execute( strSql, objQuery ))
{
LOGERROR( "getCodeByDeviceGroup(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
const char *szMsg = "db query faild";
deviceGroupPointCodeListdto->message = szMsg;
return createDtoResponse( Status::CODE_201, deviceGroupPointCodeListdto );
}
while ( objQuery.next())
{
unitMap[objQuery.value( 0 ).toString().toInt()]=objQuery.value( 1 ).toString().toStdString();
}
//查询设备组下的设备
QStringList devices;
std::string devStdStr(deviceGroupTag->c_str(), deviceGroupTag->size());
QString deviceGroupCondition=QString("where group_tag_name='%1' ").arg(QString::fromStdString(devStdStr));
strSql="select tag_name from dev_info "+deviceGroupCondition;
if ( !objDbConn.execute( strSql, objQuery ))
{
LOGERROR( "getCodeByDeviceGroup(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
const char *szMsg = "db query faild";
deviceGroupPointCodeListdto->message = szMsg;
return createDtoResponse( Status::CODE_201, deviceGroupPointCodeListdto );
}
while ( objQuery.next())
{
devices.append(objQuery.value( 0 ).toString());
}
for (int i = 0; i < devices.size(); ++i) {
devices[i] = QString("'%1'").arg(devices[i]);
}
QString sDevice=devices.join(",");
QString sCondition=QString(" where device in (%1) ").arg(sDevice);
QString sql="SELECT location_id,sub_system,tag_name,description, unit_id,'accuml' AS table_name"
" from accuml "+sCondition+
" union "
"SELECT location_id,sub_system,tag_name,description, unit_id,'analog' AS table_name"
" from analog "+sCondition+
" union "
"SELECT location_id,sub_system,tag_name,description, '' as unit_id,'digital' AS table_name"
" from digital "+sCondition+
" union "
"SELECT location_id,sub_system,tag_name,description, '' as unit_id,'mix' AS table_name"
" from mix "+sCondition;
QString cntSql=QString("select count(1) from (%1) as cnt_query").arg(sql);
if ( !objDbConn.execute( cntSql, objQuery ))
{
LOGERROR( "getCodeByLocation(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
const char *szMsg = "db query faild";
deviceGroupPointCodeListdto->message = szMsg;
return createDtoResponse( Status::CODE_201, deviceGroupPointCodeListdto );
}
int totalCnt{0};
while ( objQuery.next())
{
totalCnt = objQuery.value( 0 ).toString().toInt();
}
if( totalCnt == 0)
{
return createDtoResponse( Status::CODE_200, deviceGroupPointCodeListdto );
}
deviceGroupPointCodeListdto->total = totalCnt / pageSize + 1;
deviceGroupPointCodeListdto->pageSize = pageSize;
deviceGroupPointCodeListdto->page = page;
QString pageSql=QString("select location_id,sub_system,tag_name,description, unit_id,table_name from (%1) as page_query limit %2 offset %3 ").arg(sql)
.arg(QString::number(pageSize)).arg(QString::number( pageSize *(page- 1 )));
if ( !objDbConn.execute( pageSql, objQuery ))
{
LOGERROR( "getCodeByLocation(): 查询错误SQL语句如下\n%s", pageSql.toUtf8().constData());
const char *szMsg = "db query error";
deviceGroupPointCodeListdto->message = szMsg;
return createDtoResponse( Status::CODE_201, deviceGroupPointCodeListdto );
}
while(objQuery.next())
{
auto pointCodedto= pointCodeDTO::createShared();
pointCodedto->tagName = objQuery.value("tag_name").toString().toStdString();
pointCodedto->desc = objQuery.value("description").toString().toStdString();
pointCodedto->unitName = unitMap[ objQuery.value("unit_id").toString().toInt()];
QString tableName=objQuery.value("table_name").toString();
if(tableName=="analog")
{
pointCodedto->type=EnMeasPiontType::MPT_AI;
}else if(tableName=="accuml")
{
pointCodedto->type=EnMeasPiontType::MPT_DI;
}else if(tableName=="digital")
{
pointCodedto->type=EnMeasPiontType::MPT_MIX;
}else if(tableName=="mix")
{
pointCodedto->type=EnMeasPiontType::MPT_ACC;
}else
{
LOGERROR( "getCodeByLocation(): 查询错误-point-type-missSQL语句如下\n%s", pageSql.toUtf8().constData());
const char *szMsg = "point type miss";
deviceGroupPointCodeListdto->message = szMsg;
return createDtoResponse( Status::CODE_201, deviceGroupPointCodeListdto );
}
deviceGroupPointCodeListdto->rows->insert(deviceGroupPointCodeListdto->rows->end(),pointCodedto);
}
return createDtoResponse( Status::CODE_200, deviceGroupPointCodeListdto );
}
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> CSimpleController::queryDeviceGroupDataSeries( const oatpp::String &strReq)
{
auto dgResp = deviceGroupDataSeriesReponseDTO::createShared();
dgResp->rows={};
auto spReq = getDefaultObjectMapper()->readFromString< oatpp::Object<deviceGroupDataSeriesRequestDTO> >( strReq );
if ( !spReq )
{
LOGERROR( "queryDeviceGroupDataSeries(): 请求解析失败,请求内容:%s", strReq->c_str());
const char *szMsg = " 请求解析失败";
dgResp->message = szMsg;
return createDtoResponse( Status::CODE_201, dgResp );
}
std::vector<SMeasPointKey> vecKey;
for(auto it = spReq->tags->cbegin(); it != spReq->tags->cend(); ++it)
{
SMeasPointKey stPointKey;
if((*it)->type == MPT_AI)
{
stPointKey.m_enType = MPT_AI;
}else if((*it)->type == MPT_DI)
{
stPointKey.m_enType = MPT_DI;
}else if((*it)->type == MPT_MIX)
{
stPointKey.m_enType = MPT_MIX;
}
stPointKey.m_pszTagName =(*it)->tagName->c_str();
vecKey.push_back( stPointKey );
}
std::string stdYearStr(spReq->year->c_str(), spReq->year->size());
QString sYear=QString::fromStdString(stdYearStr);
std::string stdMonthStr(spReq->month->c_str(), spReq->month->size());
QString sMonth=QString::fromStdString(stdMonthStr);
std::string stdDayStr(spReq->day->c_str(), spReq->day->size());
QString sDay=QString::fromStdString(stdDayStr);
std::vector<std::vector<QPair<VALUE_STATUS, double>>> allData;
CTsdbQuery tdbQuery;
auto ret=tdbQuery.queryTagByTimeType(QString("%1-%2-%3").arg(sYear).arg(sMonth).arg(sDay),spReq->timeType,vecKey,allData);
if(!ret)
{
LOGERROR( "queryDeviceGroupDataSeries():query influxdb faild请求内容%s", strReq->c_str());
const char *szMsg = " query influxdb faild";
dgResp->message = szMsg;
return createDtoResponse( Status::CODE_201, dgResp );
};
//列向获取同一个测点的数据
size_t col=allData[0].size();
size_t row=allData.size();
for(int i=0;i<col;i++)
{
auto unitdto=dataSeriesUnitDTO::createShared();
unitdto->tagName= spReq->tags[i]->tagName;
unitdto->data={};
for(int j=0;j<row;j++)
{
unitdto->data->insert(unitdto->data->end(),allData[j][i].second);
}
dgResp->rows->insert(dgResp->rows->end(),unitdto);
}
return createDtoResponse( Status::CODE_200, dgResp );
}
}
}

View File

@ -0,0 +1,68 @@
#pragma once
#include "oatpp/core/macro/component.hpp"
#include "oatpp/web/server/api/ApiController.hpp"
#include OATPP_CODEGEN_BEGIN( ApiController )
namespace web_server {
namespace module_statistics{
class CSimpleController: public oatpp::web::server::api::ApiController
{
public:
CSimpleController( OATPP_COMPONENT(std::shared_ptr<ObjectMapper>,objectMapper) )
: oatpp::web::server::api::ApiController( objectMapper )
{}
~CSimpleController()
{}
public:
/**
* @brief location统计查询
*/
ENDPOINT("GET", "/stats/locationStatistics", queryLocationStatistics,
QUERY( String, filterStr,"filterStr",""),
QUERY( Int32, locationId,"locationId",0)
);
/**
* @brief location的测点标签
*/
ENDPOINT("GET", "/stats/getCodeByLocation", getCodeByLocation,
QUERY( String, filterStr,"filterStr",""),
QUERY( Int32, locationId,"locationId",0),
QUERY( Int32, page,"page",1),
QUERY( Int32, pageSize,"pageSize",30)
);
/**
* @brief location的测点序列数据
*/
ENDPOINT("POST", "/stats/locationDataSeries", queryLocationDataSeries, BODY_STRING( String, strReq )) ;
/**
* @brief
*/
ENDPOINT("GET", "/stats/deviceGroupStatistics", queryDeviceGroupStatistics,
QUERY( String, filterStr,"filterStr",""),
QUERY( String, deviceGroupTag,"deviceGroupTag","")
);
/**
* @brief deviceGroup的测点标签
*/
ENDPOINT("GET", "/stats/getCodeByDeviceGroup", getCodeByDeviceGroup,
QUERY( String, deviceGroupTag,"deviceGroupTag",""),
QUERY( Int32, page,"page",1),
QUERY( Int32, pageSize,"pageSize",30)
);
/**
* @brief deviceGroup的测点序列数据
*/
ENDPOINT("POST", "/stats/deviceGroupDataSeries", queryDeviceGroupDataSeries, BODY_STRING( String, strReq )) ;
};
}
}
#include OATPP_CODEGEN_END( ApiController )

View File

@ -0,0 +1,197 @@
#include "CTsdbQuery.h"
#include "QPair"
#include "QDateTime"
#include "public/pub_logger_api/logger.h"
#include "dbms/db_his_query_api/DbHisQueryApi.h"
using namespace iot_dbms;
namespace web_server {
namespace module_statistics {
CTsdbQuery::CTsdbQuery()
{
m_pTsdbConn = iot_dbms::getOneUseableConn(true);
}
CTsdbQuery::~CTsdbQuery()
{
}
bool CTsdbQuery::queryTagByTimeType(QString timeStr,int timeType,const std::vector<SMeasPointKey>& vecMpKey, std::vector<std::vector<QPair<VALUE_STATUS, double>>>& allData)
{
QDate date=QDate::fromString(timeStr,"yyyy-MM-dd");
QPair<QDateTime, QDateTime>time_temp;
QList<QPair<QDateTime,QDateTime>> timeList;
switch (timeType) {
case TimeType::YEAR:
{
//从1月-12月
QDateTime date_time;
for (int i = 1; i <= 12; i++)
{
//取每月1号0时作为查询点
date_time.setDate(QDate(date.year(), i, 1));
date_time.setTime(QTime(0, 0, 0, 0));
time_temp.first = date_time.addSecs(-5 * 30);
time_temp.second = date_time.addSecs(5 * 30);
timeList.append(time_temp);
}
//时间段的起始时间
date_time.setDate(QDate(date.year(), 1, 1));
date_time.setTime(QTime(0, 0, 0, 0));
time_temp.first = date_time;
//时间段的结束时间
date_time.setDate(QDate(date.year(), 12, date.daysInMonth()));
date_time.setTime(QTime(23, 59, 59, 999));
time_temp.second = date_time;
}
break;
case TimeType::MONTH:
{
//从1号到本月最后一天
QDateTime date_time;
for (int i = 1; i <= date.daysInMonth(); i++)
{
date_time.setDate(QDate(date.year(), date.month(), i));
date_time.setTime(QTime(0, 0, 0, 0));
time_temp.first = date_time.addSecs(-5 * 30);
time_temp.second = date_time.addSecs(5 * 30);
timeList.append(time_temp);
}
//时间段的起始时间
date_time.setDate(QDate(date.year(), date.month(), 1));
date_time.setTime(QTime(0, 0, 0, 0));
time_temp.first = date_time;
//时间段的结束时间
date_time.setDate(QDate(date.year(), date.month(), date.daysInMonth()));
date_time.setTime(QTime(23, 59, 59, 999));
time_temp.second = date_time;
}
break;
case TimeType::DAY:
{
//从0时到23时
QDateTime date_time;
for (int i = 0; i < 24; i++)
{
date_time.setDate(date);
date_time.setTime(QTime(i, 0, 0, 0));
time_temp.first = date_time.addSecs(-5 * 30);
time_temp.second = date_time.addSecs(5 * 30);
timeList.append(time_temp);
}
//时间段的起始时间
date_time.setDate(date);
date_time.setTime(QTime(0, 0, 0, 0));
time_temp.first = date_time;
//时间段的结束时间
date_time.setDate(date);
date_time.setTime(QTime(23, 59, 59, 999));
time_temp.second = date_time;
}
break;
default:
LOGERROR( "queryTagByTimeType(): is bad timeType");
return false;
}
qint64 start = 0; //查询开始时间
qint64 end = 0; //查询结束时间
int length = timeList.length(); //时间列表长度
bool ret = false;
for(int row = 0; row < length; row++)
{
start =timeList[row].first.toMSecsSinceEpoch();
end = timeList[row].second.toMSecsSinceEpoch();
std::vector<QPair<VALUE_STATUS, double>>data;
data.resize(vecMpKey.size());
ret = queryTagByPeriod(start, end, vecMpKey, data);
if (ret)
{
allData.push_back(data);
}
else
{
return false;
}
}
return true;
}
void CTsdbQuery::parseResult(const std::vector<SMeasPointKey>& vecMpKey,const std::vector<std::vector<SUniHisValue> *> vecResult,std::vector<QPair<VALUE_STATUS, double>> &record)
{
for (size_t nIndex(0); nIndex < vecResult.size(); nIndex++)
{
if (vecResult.at(nIndex)->size() == 0)
{
record[nIndex].first = INVALID_VS;
record[nIndex].second = -1;
}
else
{
record[nIndex].first = VALID_VS;
if (vecMpKey.at(nIndex).m_enType == MPT_AI || vecMpKey.at(nIndex).m_enType == MPT_ACC)
{
record[nIndex].second =vecResult.at(nIndex)->at(0).m_uniValue.m_float64Val;
}
else
{
record[nIndex].second = vecResult.at(nIndex)->at(0).m_uniValue.m_int32Val;
}
}
}
}
bool CTsdbQuery::queryTagByPeriod(qint64 startTime, qint64 endTime, const std::vector<SMeasPointKey> &vecMpKey, std::vector<QPair<VALUE_STATUS, double> > &record)
{
std::vector<std::vector<SUniHisValue> *> vecResult;
for (size_t nIndex(0); nIndex < vecMpKey.size(); nIndex++)
{
vecResult.push_back(new std::vector<SUniHisValue>());
}
std::vector<boost::int32_t> vecNotStatusHave(vecMpKey.size());
for (size_t nIndex(0); nIndex <vecMpKey.size(); nIndex++)
{
vecNotStatusHave[nIndex] = boost::int32_t(STAUS_NOT_HAVE);
}
EnComputeMethod method = CM_NULL;
if (!getHisValue(*m_pTsdbConn, 10000, vecMpKey, startTime, endTime, NULL, &vecNotStatusHave, method, 0, FM_NULL_METHOD, vecResult))
{
LOGERROR("CTsdbQuery::queryEventByPeriod: 查询超时Lower: %I64u, Upper: %I64u", startTime, endTime);
return false;
}
parseResult(vecMpKey,vecResult,record);
std::vector<std::vector<iot_dbms::SUniHisValue> *>::iterator res = vecResult.begin();
while (res != vecResult.end())
{
delete (*res);
++res;
}
return true;
}
}
}

View File

@ -0,0 +1,42 @@
#ifndef CTSDBQUERY_H
#define CTSDBQUERY_H
#include "tsdb_api/TsdbApi.h"
#include "dbms/db_his_query_api/DbHisQueryBase.h"
#include "QPair"
using namespace iot_dbms;
namespace web_server {
namespace module_statistics {
#define STAUS_NOT_HAVE 4
enum TimeType
{
DAY=1,
MONTH,
YEAR
};
enum VALUE_STATUS { INVALID_VS = 0, VALID_VS=1};
class CTsdbQuery
{
public:
CTsdbQuery();
~CTsdbQuery();
bool queryTagByTimeType(QString timeStr,int timeType,const std::vector<SMeasPointKey>& vecMpKey, std::vector<std::vector<QPair<VALUE_STATUS, double>>>& allData);
void parseResult(const std::vector<SMeasPointKey>& vecMpKey,const std::vector<std::vector<SUniHisValue> *> vecResult,std::vector<QPair<VALUE_STATUS, double>> &record);
bool queryTagByPeriod(qint64 startTime, qint64 endTime,const std::vector<SMeasPointKey>& vecMpKey,std::vector<QPair<VALUE_STATUS, double>>& record);
private:
CTsdbConnPtr m_pTsdbConn;
};
}
}
#endif // CTSDBQUERY_H

View File

@ -0,0 +1,167 @@
#pragma once
#include "oatpp/core/macro/codegen.hpp"
#include "oatpp/core/Types.hpp"
#include <QString>
#include OATPP_CODEGEN_BEGIN( DTO )
namespace web_server
{
namespace module_statistics
{
/**
* Data Transfer Object. Object containing fields only.
* Used in API for serialization/deserialization and validation
*/
class historyDataDTO: public oatpp::DTO
{
DTO_INIT(historyDataDTO, DTO )
DTO_FIELD(String, tagName );
DTO_FIELD(String, desc );
DTO_FIELD( Float64, value );
DTO_FIELD( Int32, status );
DTO_FIELD(String, unitName );
};
class locationStatDTO: public oatpp::DTO
{
DTO_INIT( locationStatDTO, DTO )
DTO_FIELD(String, locationName );
DTO_FIELD( Int32, id );
DTO_FIELD( String, tagName );
DTO_FIELD(List<Object<historyDataDTO>> , data );
};
class locationStatResponseDTO: public oatpp::DTO
{
DTO_INIT(locationStatResponseDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD( String, message );
DTO_FIELD(Object<locationStatDTO> , data );
};
struct TagTuple {
int unitId;
QString description;
};
class pointCodeDTO:public oatpp::DTO
{
DTO_INIT( pointCodeDTO, DTO )
DTO_FIELD(String, tagName );
DTO_FIELD(String, desc );
DTO_FIELD(String, unitName );
DTO_FIELD( Int32, type );
};
class locationPointCodeListDTO: public oatpp::DTO
{
DTO_INIT( locationPointCodeListDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD( String, message );
DTO_FIELD( Int32, total );
DTO_FIELD( Int32, page );
DTO_FIELD( Int32, pageSize );
DTO_FIELD(List<Object<pointCodeDTO>> , rows );
};
class locationDataSeriesRequestUnitDTO: public oatpp::DTO
{
DTO_INIT( locationDataSeriesRequestUnitDTO, DTO )
DTO_FIELD( Int32, type ) = 0;
DTO_FIELD( String, tagName );
};
class locationDataSeriesRequestDTO: public oatpp::DTO
{
DTO_INIT( locationDataSeriesRequestDTO, DTO )
DTO_FIELD( String, year );
DTO_FIELD( String, month );
DTO_FIELD( String, day );
DTO_FIELD( Int32, timeType );
DTO_FIELD( Int32, locationId );
DTO_FIELD(List<Object<locationDataSeriesRequestUnitDTO>> , tags );
};
class dataSeriesUnitDTO: public oatpp::DTO
{
DTO_INIT( dataSeriesUnitDTO, DTO )
DTO_FIELD( String, tagName );
DTO_FIELD( List<Float64>, data );
};
class locationDataSeriesReponseDTO: public oatpp::DTO
{
DTO_INIT( locationDataSeriesReponseDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD( String, message );
DTO_FIELD(List<Object<dataSeriesUnitDTO>> , rows );
};
class deviceGroupStatDTO: public oatpp::DTO
{
DTO_INIT( deviceGroupStatDTO, DTO )
DTO_FIELD( String, deviceTag);
DTO_FIELD(List<Object<historyDataDTO>> , data );
};
class deviceGroupStatResponseDTO: public oatpp::DTO
{
DTO_INIT(deviceGroupStatResponseDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD( String, message );
DTO_FIELD(Object<deviceGroupStatDTO> , data );
};
class deviceGroupPointCodeListDTO: public oatpp::DTO
{
DTO_INIT( deviceGroupPointCodeListDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD( String, message );
DTO_FIELD( Int32, total );
DTO_FIELD( Int32, page );
DTO_FIELD( Int32, pageSize );
DTO_FIELD(List<Object<pointCodeDTO>> , rows );
};
class deviceGroupDataSeriesRequestUnitDTO: public oatpp::DTO
{
DTO_INIT( deviceGroupDataSeriesRequestUnitDTO, DTO )
DTO_FIELD( Int32, type ) = 0;
DTO_FIELD( String, tagName );
};
class deviceGroupDataSeriesRequestDTO: public oatpp::DTO
{
DTO_INIT( deviceGroupDataSeriesRequestDTO, DTO )
DTO_FIELD( String, year );
DTO_FIELD( String, month );
DTO_FIELD( String, day );
DTO_FIELD( Int32, timeType );
DTO_FIELD( Int32, locationId );
DTO_FIELD(List<Object<deviceGroupDataSeriesRequestUnitDTO>> , tags );
};
class deviceGroupDataSeriesReponseDTO: public oatpp::DTO
{
DTO_INIT( deviceGroupDataSeriesReponseDTO, DTO )
DTO_FIELD( Int32, code ) = 200;
DTO_FIELD( String, message );
DTO_FIELD(List<Object<dataSeriesUnitDTO>> , rows );
};
}
}
#include OATPP_CODEGEN_END( DTO )

View File

@ -0,0 +1,41 @@
#-------------------------------------------------
#
# Project created by QtCreator 2024-07-25T13:58:24
# 该模块为web提供统计功能的模块
#-------------------------------------------------
QT += sql
#module.pri中已指定编译为静态库生成路径在编译的临时目录
TARGET = module_statistics
TEMPLATE = lib
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
CModule.cpp \
CSimpleController.cpp \
CTsdbQuery.cpp
HEADERS += \
CModule.h \
CSimpleController.h \
DTOs.hpp \
CTsdbQuery.h
#静态库不要连接统一在server中连接
#LIBS +=
#-------------------------------------------------------------------
#所有web_server的模块应包含此pri无需包含common.pri
MODULE_PRI=$$PWD/../module.pri
exists($$MODULE_PRI) {
include($$MODULE_PRI)
}else {
error("FATAL error: can not find module.pri")
}

View File

@ -254,7 +254,7 @@ bool CController::getDeviceGroupInfoByLocationId( iot_dbms::CDbApi& objDb, oatpp
auto pData = CDto_response_stationLocationMS::createShared(); auto pData = CDto_response_stationLocationMS::createShared();
pData->code = objQuery.value(0).toString().toStdString(); pData->code = objQuery.value(0).toString().toStdString();
pData->treeCode = pData->code; pData->treeCode = pData->code;
pData->name = objQuery.value(1).toString().split(".").last().toStdString(); pData->name = objQuery.value(1).toString().toStdString();
pData->treePCode = objQuery.value(2).toString().toStdString(); pData->treePCode = objQuery.value(2).toString().toStdString();
pData->type = objQuery.value(3).toString().toStdString(); pData->type = objQuery.value(3).toString().toStdString();
sDeviceGroupTagName = sDeviceGroupTagName + "'" + QString(pData->code->c_str()) + "',"; sDeviceGroupTagName = sDeviceGroupTagName + "'" + QString(pData->code->c_str()) + "',";
@ -310,7 +310,7 @@ bool CController::getDeviceInfoByDeviceGroupTagName( iot_dbms::CDbApi& objDb, oa
auto pData = CDto_response_stationLocationMS::createShared(); auto pData = CDto_response_stationLocationMS::createShared();
pData->code = objQuery.value(0).toString().toStdString(); pData->code = objQuery.value(0).toString().toStdString();
pData->treeCode = pData->code; pData->treeCode = pData->code;
pData->name = objQuery.value(1).toString().split(".").last().toStdString(); pData->name = objQuery.value(1).toString().toStdString();
pData->treePCode = objQuery.value(2).toString().toStdString(); pData->treePCode = objQuery.value(2).toString().toStdString();
pData->type = objQuery.value(3).toString().toStdString(); pData->type = objQuery.value(3).toString().toStdString();
sDeviceTagName = sDeviceTagName + "'" + QString(pData->code->c_str()) + "',"; sDeviceTagName = sDeviceTagName + "'" + QString(pData->code->c_str()) + "',";
@ -348,7 +348,7 @@ bool CController::getYMInfoByDeviceTagName( iot_dbms::CDbApi& objDb, oatpp::data
auto pData = CDto_response_stationLocationMS::createShared(); auto pData = CDto_response_stationLocationMS::createShared();
pData->code = objQuery.value(0).toString().toStdString(); pData->code = objQuery.value(0).toString().toStdString();
pData->treeCode = pData->code; pData->treeCode = pData->code;
pData->name = objQuery.value(1).toString().split(".").last().toStdString(); pData->name = objQuery.value(1).toString().toStdString();
pData->treePCode = objQuery.value(2).toString().toStdString(); pData->treePCode = objQuery.value(2).toString().toStdString();
pData->type = objQuery.value(3).toString().toStdString(); pData->type = objQuery.value(3).toString().toStdString();
pData->sname = objQuery.value(4).toString().toStdString(); pData->sname = objQuery.value(4).toString().toStdString();
@ -386,7 +386,7 @@ bool CController::getYCInfoByDeviceTagName( iot_dbms::CDbApi& objDb, oatpp::data
auto pData = CDto_response_stationLocationMS::createShared(); auto pData = CDto_response_stationLocationMS::createShared();
pData->code = objQuery.value(0).toString().toStdString(); pData->code = objQuery.value(0).toString().toStdString();
pData->treeCode = pData->code; pData->treeCode = pData->code;
pData->name = objQuery.value(1).toString().split(".").last().toStdString(); pData->name = objQuery.value(1).toString().toStdString();
pData->treePCode = objQuery.value(2).toString().toStdString(); pData->treePCode = objQuery.value(2).toString().toStdString();
pData->type = objQuery.value(3).toString().toStdString(); pData->type = objQuery.value(3).toString().toStdString();
pData->sname = objQuery.value(4).toString().toStdString(); pData->sname = objQuery.value(4).toString().toStdString();

View File

@ -20,6 +20,9 @@
#include "../module_general/ModuleGeneral.hpp" #include "../module_general/ModuleGeneral.hpp"
#include "../module_realTimeData/CModule.h" #include "../module_realTimeData/CModule.h"
#include "../module_trend/CModule.h" #include "../module_trend/CModule.h"
#include "../module_app/ModuleApp.h"
#include "../module_statistics/CModule.h"
#include "../module_operate/CModule.h"
#include "GlobalMng.h" #include "GlobalMng.h"
@ -146,6 +149,33 @@ bool CGlobalMng::init( const std::string &strAppName )
return false; return false;
} }
ptrModule = module_app::CModuleApp::create();
if ( ptrModule->init())
m_vecModules.push_back( ptrModule );
else
{
LOGERROR( "module_app failed to init" );
return false;
}
ptrModule = module_statistics::CModule::create();
if ( ptrModule->init())
m_vecModules.push_back( ptrModule );
else
{
LOGERROR( "module_app failed to init" );
return false;
}
ptrModule = module_operate::CModule::create();
if ( ptrModule->init())
m_vecModules.push_back( ptrModule );
else
{
LOGERROR( "module_app failed to init" );
return false;
}
//< todo 其他组件 //< todo 其他组件
} }

View File

@ -13,6 +13,7 @@
#include "pub_logger_api/logger.h" #include "pub_logger_api/logger.h"
#include "pub_utility_api/SingleProcInstance.h" #include "pub_utility_api/SingleProcInstance.h"
#include "pub_utility_api/FileUtil.h" #include "pub_utility_api/FileUtil.h"
#include "pub_utility_api/I18N.h"
#include "net_msg_bus_api/MsgBusApi.h" #include "net_msg_bus_api/MsgBusApi.h"
#include "tsdb_api/TsdbApi.h" #include "tsdb_api/TsdbApi.h"
@ -115,6 +116,16 @@ bool CWebServer::start( int argc, char *argv[], int & /*nStatus*/)
return false; return false;
} }
//< 初始化翻译
if (iot_public::initI18N("/web_server_bi/translate", "web_server_bi"))
{
LOGDEBUG(I18N_C("I18N output test\n This is src hardcode. \n int = [%d] , str = [%s]\n"), 123, "test");
}
else
{
LOGWARN("国际化初始化失败!");
}
//< 业务初始化,加载配置等 //< 业务初始化,加载配置等
if ( !m_ptrGlobalMng->init( strAppName )) if ( !m_ptrGlobalMng->init( strAppName ))
{ {

View File

@ -4,14 +4,15 @@
#include "oatpp/core/macro/component.hpp" #include "oatpp/core/macro/component.hpp"
#include "oatpp/web/protocol/http/outgoing/ResponseFactory.hpp" #include "oatpp/web/protocol/http/outgoing/ResponseFactory.hpp"
#include "oatpp/network/tcp/server/ConnectionProvider.hpp" #include "oatpp/network/tcp/server/ConnectionProvider.hpp"
#include "pub_utility_api/FileUtil.h"
#include "pub_utility_api/CommonConfigParse.h"
#include "AuthInterceptor.h" #include "AuthInterceptor.h"
#include "boost/uuid/random_generator.hpp" #include "boost/uuid/random_generator.hpp"
#include "boost/regex.hpp" #include "boost/regex.hpp"
#include <regex>
#include <sstream> #include <sstream>
#include <QDateTime>
using namespace web_server::auth; using namespace web_server::auth;
@ -56,65 +57,45 @@ static void generateUuidBase64(std::string &strOut)
strOut.shrink_to_fit(); strOut.shrink_to_fit();
} }
//获取地址访问白名单
bool getAddrAlwayAllow(std::string &strAddrAllow)
{
iot_public::CCommonConfigParse objCfgParse;
if(objCfgParse.load(iot_public::CFileUtil::getPathOfCfgFile("web_server.xml"))==iotFailed)
{
LOGDEBUG("AuthInterceptor::getAddrAlawyAllow() web_server.xml load fail .\n");
return false;
}
if(objCfgParse.getStringValue("web_server","addr_allow",strAddrAllow) != iotSuccess)
{
strAddrAllow="";
return false;
}
LOGDEBUG("AuthInterceptor::AddrAlwayAllow=[%s] .\n",strAddrAllow.c_str());
return true;
}
bool isAddrAlwayAllow(const std::string&strAddress)
{
std::string strAddrAllow = "";
if(false == getAddrAlwayAllow(strAddrAllow))
{
return false; //失败白名单失效
}
int nPos = strAddrAllow.find(strAddress) ;
if( nPos < 0 ) //没有找到
{
LOGDEBUG("isAddrAlawyAllow::strAddress=[%s] .\n",strAddress.c_str());
return false;
}
return true;
}
// 路径白名单 // 路径白名单
bool isPathAlwaysAllow(const std::string& path ) bool AuthInterceptor::isPathAlwaysAllow(const std::string& path )
{ {
boost::regex loginWsRegex("^\\/login$");
// std::regex alarmCntWsRegex("^\\/alarmCountWebsocket$"); // std::regex alarmCntWsRegex("^\\/alarmCountWebsocket$");
// std::regex alarmWsRegex("^\\/alarmWebsocket$"); // std::regex alarmWsRegex("^\\/alarmWebsocket$");
// std::regex hisEvtWsRegex("^\\/historyEvent$"); // std::regex hisEvtWsRegex("^\\/historyEvent$");
// std::regex realtimeWsRegex("^\\/realTimeDataWebsocket$"); // std::regex realtimeWsRegex("^\\/realTimeDataWebsocket$");
if ( boost::regex_match(path, boost::regex(loginWsRegex))) // if ( std::regex_match(path, std::regex(alarmCntWsRegex))
// || std::regex_match(path, std::regex(alarmWsRegex)) // || std::regex_match(path, std::regex(alarmWsRegex))
// || std::regex_match(path, std::regex(hisEvtWsRegex)) // || std::regex_match(path, std::regex(hisEvtWsRegex))
// || std::regex_match(path, std::regex(realtimeWsRegex))) // || std::regex_match(path, std::regex(realtimeWsRegex)))
// {
// return true;
// }
int ivalue;
std::string pathAllow;
std::string pathWsRegex ;
confirm.getIntValue("Allow", "Num", ivalue);
for (int i = 1;i<ivalue;i++)
{
pathAllow = "pathAllow" + std::to_string(i);
confirm.getStringValue("Allow", pathAllow, pathWsRegex);
std::string newPattern = "/";
newPattern = newPattern + pathWsRegex;
//newPattern = newPattern + "";
std::regex patternMatch(newPattern);
if (std::regex_match(path, std::regex(patternMatch)))
{ {
LOGDEBUG("isPathAlwaysAllow::path=[%s] .\n",path.c_str());
return true; return true;
} }
// TODO 结束测试后该行改为false }
return false; return false;
// TODO 结束测试后该行改为false
} }
// 路径黑名单 // 路径黑名单
@ -153,6 +134,41 @@ bool isPathNeedLogout(const std::string& path)
// 账户锁定数据库 username 对应 密码错误次数和最后一次访问出错的时间
static std::map<std::string, std::pair<int,int64> > mapLockedDb = std::map<std::string, std::pair<int,int64> >();
bool isUsernameLocked(const std::string &name)
{
if( mapLockedDb.find(name) == mapLockedDb.end() )
{
mapLockedDb.emplace(name,std::make_pair<int,int64>(0,0) );
return false;
}
else
{
bool isExpired = QDateTime::currentMSecsSinceEpoch() > ( mapLockedDb[name].second + 300 * 1000 ) ;// 300ms
bool isOverRetryTimes = mapLockedDb[name].first > 5;
if( !isExpired && isOverRetryTimes )
{
return true;
}
else if( isExpired )
{
mapLockedDb[name].first = 0;
return false;
}
}
if(mapLockedDb.size() > 10000)
{
mapLockedDb.clear();
}
return false;
}
std::shared_ptr<oatpp::web::server::interceptor::RequestInterceptor::OutgoingResponse> AuthInterceptor::intercept(const std::shared_ptr<oatpp::web::server::interceptor::RequestInterceptor::IncomingRequest> &request) std::shared_ptr<oatpp::web::server::interceptor::RequestInterceptor::OutgoingResponse> AuthInterceptor::intercept(const std::shared_ptr<oatpp::web::server::interceptor::RequestInterceptor::IncomingRequest> &request)
{ {
auto routes = request->getStartingLine().path.std_str(); auto routes = request->getStartingLine().path.std_str();
@ -162,11 +178,15 @@ std::shared_ptr<oatpp::web::server::interceptor::RequestInterceptor::OutgoingRes
std::string address = request->getConnection()->getInputStreamContext().getProperties().get(oatpp::network::tcp::server::ConnectionProvider::ExtendedConnection::PROPERTY_PEER_ADDRESS); std::string address = request->getConnection()->getInputStreamContext().getProperties().get(oatpp::network::tcp::server::ConnectionProvider::ExtendedConnection::PROPERTY_PEER_ADDRESS);
std::string port = request->getConnection()->getInputStreamContext().getProperties().get(oatpp::network::tcp::server::ConnectionProvider::ExtendedConnection::PROPERTY_PEER_PORT); std::string port = request->getConnection()->getInputStreamContext().getProperties().get(oatpp::network::tcp::server::ConnectionProvider::ExtendedConnection::PROPERTY_PEER_PORT);
// << 地址白名单判断,白名单内IP不判断权限。但是不能影响正常的WEB访问 // 配置文件允许的连接不拦截
if( isAddrAlwayAllow(address) && !isPathAlwaysAllow(routes)) //在白名单内 && 不是登录操作,直接返回,不校验权限 // if( isPathAlwaysAllow(routes) )
{ // {
return nullptr; // return nullptr;
} // }
// else
// {
// throw oatpp::web::protocol::http::HttpError(oatpp::web::protocol::http::Status::CODE_401, "Unauthorized", {});
// }
if( isPathAlwaysBlock(routes) ) if( isPathAlwaysBlock(routes) )
{ {
@ -188,6 +208,22 @@ std::shared_ptr<oatpp::web::server::interceptor::RequestInterceptor::OutgoingRes
auto username = queryParams.get("username"); auto username = queryParams.get("username");
auto password = queryParams.get("password"); auto password = queryParams.get("password");
if(username == nullptr || password == nullptr)
{
throw oatpp::web::protocol::http::HttpError(oatpp::web::protocol::http::Status::CODE_400, "Unauthorized", {});
}
if( isUsernameLocked( *username ) )
{
auto loginFail = LoginFailDto::createShared();
loginFail->dateTime = m_rdbUtil.getCurrentDateTime();
loginFail->content = "账户已锁定, 请稍后重试";
OATPP_COMPONENT( std::shared_ptr<oatpp::data::mapping::ObjectMapper>, spMapper );
const auto && json = spMapper->writeToString(loginFail);
LOGINFO("Username Locked, address:[%s], port:[%s],username:[%s]",address.c_str(), port.c_str(),username->c_str());
return oatpp::web::protocol::http::outgoing::ResponseFactory::createResponse( oatpp::web::protocol::http::Status::CODE_200, json );
}
auto loginSucc = LoginSuccDto::createShared(); auto loginSucc = LoginSuccDto::createShared();
bool ret = m_rdbUtil.isPermOk(username,password); bool ret = m_rdbUtil.isPermOk(username,password);
@ -199,6 +235,9 @@ std::shared_ptr<oatpp::web::server::interceptor::RequestInterceptor::OutgoingRes
else else
{ {
rdbRet = false; rdbRet = false;
mapLockedDb[username].first += 1;
mapLockedDb[username].second = QDateTime::currentMSecsSinceEpoch();
} }
bool loginRet = true; bool loginRet = true;
@ -211,6 +250,7 @@ std::shared_ptr<oatpp::web::server::interceptor::RequestInterceptor::OutgoingRes
std::string id; std::string id;
generateUuidBase64(id); generateUuidBase64(id);
response->putHeader("Set-Cookie",std::string("id=") + id + ";Path=/"); response->putHeader("Set-Cookie",std::string("id=") + id + ";Path=/");
response->putHeader("token",std::string("id=") + id + ";Path=/");
if(!m_ptrSessionApiImpl->addSession(id,username,password,loginSucc->groupList[0])) if(!m_ptrSessionApiImpl->addSession(id,username,password,loginSucc->groupList[0]))
{ {
@ -249,7 +289,6 @@ std::shared_ptr<oatpp::web::server::interceptor::RequestInterceptor::OutgoingRes
LOGERROR("cannot get sessionid from cookie"); LOGERROR("cannot get sessionid from cookie");
throw oatpp::web::protocol::http::HttpError(oatpp::web::protocol::http::Status::CODE_401, "Unauthorized", {}); throw oatpp::web::protocol::http::HttpError(oatpp::web::protocol::http::Status::CODE_401, "Unauthorized", {});
} }
// 注销处理 // 注销处理
if( isPathNeedLogout( routes ) ) if( isPathNeedLogout( routes ) )
{ {
@ -265,6 +304,7 @@ std::shared_ptr<oatpp::web::server::interceptor::RequestInterceptor::OutgoingRes
oatpp::web::protocol::http::Status::CODE_200,"{\"url\":null,\"dateTime\":null,\"groupList\":null,\"codeStuts\":\"/login\",\"content\":\"success\"}"); oatpp::web::protocol::http::Status::CODE_200,"{\"url\":null,\"dateTime\":null,\"groupList\":null,\"codeStuts\":\"/login\",\"content\":\"success\"}");
response->putHeader("Set-Cookie", ""); response->putHeader("Set-Cookie", "");
response->putHeader("token", "");
LOGINFO("Logout address:[%s], port:[%s]",address.c_str(), port.c_str()); LOGINFO("Logout address:[%s], port:[%s]",address.c_str(), port.c_str());
return response; return response;
@ -298,7 +338,11 @@ bool AuthInterceptor::init()
LOGERROR("rdbUtil failed to init!"); LOGERROR("rdbUtil failed to init!");
return false; return false;
} }
if (confirm.load("../../data/config/", "pathallow.xml") == iotFailed)
{
LOGDEBUG("pathallow.xml error");
return true;
}
LOGDEBUG("pathallow.xml ok");
return true; return true;
} }

View File

@ -9,6 +9,8 @@
#include "SesssionApiImpl.h" #include "SesssionApiImpl.h"
#include "pub_logger_api/logger.h" #include "pub_logger_api/logger.h"
#include "AuthRdbUtil.h" #include "AuthRdbUtil.h"
#include "pub_utility_api/CommonConfigParse.h"
using namespace iot_public;
namespace web_server namespace web_server
{ {
namespace auth namespace auth
@ -22,9 +24,11 @@ public:
std::shared_ptr<OutgoingResponse> intercept(const std::shared_ptr<IncomingRequest>& request) override; std::shared_ptr<OutgoingResponse> intercept(const std::shared_ptr<IncomingRequest>& request) override;
bool init(); bool init();
bool isPathAlwaysAllow(const std::string& path );
private: private:
CCommonConfigParse confirm;
CSesssionApiImplPtr m_ptrSessionApiImpl = getSessionApiImplInstance(); CSesssionApiImplPtr m_ptrSessionApiImpl = getSessionApiImplInstance();
CAuthRdbUtil m_rdbUtil; CAuthRdbUtil m_rdbUtil;
}; };

View File

@ -406,12 +406,6 @@ iot_service::CPermMngApiPtr CSesssionApiImpl::getCurPermApi(const std::shared_pt
bool CSesssionApiImpl::isSessionValid(const std::string &sessionId) bool CSesssionApiImpl::isSessionValid(const std::string &sessionId)
{ {
static std::set<std::string> setAllowedId = {"kbdct","kehua","ganyuhangsb","iwantquit","kangbidasb","kehuasb"};
if(setAllowedId.find(sessionId) != setAllowedId.end()) // 加入白名单验证
{
return true;
}
iot_service::CPermMngApiPtr pPermMngApi = getCurPermApi(sessionId); iot_service::CPermMngApiPtr pPermMngApi = getCurPermApi(sessionId);
if( nullptr == pPermMngApi ) if( nullptr == pPermMngApi )
{ {

View File

@ -17,7 +17,7 @@ TEMPLATE = app
TARGET = web_server TARGET = web_server
#连接模块静态库 #连接模块静态库
LIBS += -lmodule_alarm -lmodule_general -lmodule_realTimeData -lmodule_user -lmodule_trend LIBS += -lmodule_alarm -lmodule_general -lmodule_realTimeData -lmodule_user -lmodule_trend -lmodule_app -lmodule_operate -lmodule_statistics
#oatpp-websocket要写在oatpp之前否则连接器报错 #oatpp-websocket要写在oatpp之前否则连接器报错
LIBS += -loatpp-websocket -loatpp LIBS += -loatpp-websocket -loatpp
@ -26,12 +26,13 @@ if(CONFIG(enable_oatpp_zlib)) {
LIBS += -loatpp-zlib -lz LIBS += -loatpp-zlib -lz
} }
LIBS += -lboost_regex -lboost_chrono -lboost_system -lboost_program_options -lboost_date_time -lboost_thread -llog4cplus \ LIBS += -lboost_regex -lboost_chrono -lboost_system -lboost_program_options -lboost_date_time -lboost_thread -llog4cplus -lboost_locale \
-lpub_logger_api -lpub_utility_api -lpub_sysinfo_api \ -lpub_logger_api -lpub_utility_api -lpub_sysinfo_api \
-lsys_proc_mng_api -lsys_node_mng_api -ldb_api_ex -ltsdb_api -lrdb_api -lrdb_net_api \ -lsys_proc_mng_api -lsys_node_mng_api -ldb_api_ex -ltsdb_api -lrdb_api -lrdb_net_api \
-lnet_msg_bus_api -lalarm_server_api -ldp_chg_data_api -lperm_mng_api \ -lnet_msg_bus_api -lalarm_server_api -ldp_chg_data_api -lperm_mng_api \
-ldb_his_query_api -ldb_his_query_api
win32{ win32{
LIBS += -lbcrypt LIBS += -lbcrypt
} }

View File

@ -1,13 +1,17 @@
TEMPLATE = subdirs TEMPLATE = subdirs
WEB_MODULES = module_alarm \ WEB_MODULES = \
module_alarm \
module_general \ module_general \
module_realTimeData \ module_realTimeData \
module_user \ module_user \
module_trend module_trend \
module_app
SUBDIRS += $$WEB_MODULES server SUBDIRS += $$WEB_MODULES server \
module_statistics \
module_operate
#不用CONFIG += ordered方案改为depends模块可以并行编译 #不用CONFIG += ordered方案改为depends模块可以并行编译
server.depends = $$WEB_MODULES server.depends = $$WEB_MODULES

View File

@ -83,6 +83,19 @@ public:
const QByteArray &baContent, iot_dbms::CDbApi *pDbApi = nullptr,qint64 *nUploadTime = nullptr); const QByteArray &baContent, iot_dbms::CDbApi *pDbApi = nullptr,qint64 *nUploadTime = nullptr);
/**
* 3D模型接口
* 使QT的数据类型1便使2QT的COW机制
* @param [in] strParentCode 22ID
* @param [in] strGroup "/"config/1/json
* @param [in] strOriginalName colorConfig.json
* @param [in] baContent
* @param [in] nCategory
* @param [in] pDbApi 使
* @return bool
*/
static bool uploadModel( const QString &strParentCode,const QString &strGroup, const QString &strOriginalName,
int nCategory,const QByteArray &baContent, iot_dbms::CDbApi *pDbApi = nullptr);
/** /**
* path更新文件 * path更新文件
@ -130,6 +143,9 @@ public:
*/ */
static bool readFileByPath( const QString &strPath, QByteArray &baContent ); static bool readFileByPath( const QString &strPath, QByteArray &baContent );
static bool readFileByFileNameAndGroup(const QString &strFileName,const QString &strFileGroup, QByteArray &baContent );
}; };
} //< namespace web_server_bi } //< namespace web_server_bi

View File

@ -11,19 +11,18 @@ using namespace oatpp;
using namespace web_server_bi::module_file; using namespace web_server_bi::module_file;
namespace multipart = oatpp::web::mime::multipart; namespace multipart = oatpp::web::mime::multipart;
#define MAX_FILE_SIZE 1024l * 1024l * 50l // 最大文件大小 50MB 基本上全景图片一亿像素保证质量的上限 #define MAX_FILE_SIZE 1024l * 1024l * 100l // 最大文件大小 50MB 基本上全景图片一亿像素保证质量的上限
// assume that the default id of tenant is 1 // assume that the default id of tenant is 1
const QString &cn_fileGroupImage = QStringLiteral("config/1/image"); const QString &cn_fileGroupImage = QStringLiteral("config/1/image");
const QString &cn_fileGroupJSON = QStringLiteral("config/1/json"); const QString &cn_fileGroupJSON = QStringLiteral("config/1/json");
const QString &cn_fileGroupDefault = QStringLiteral("config/1"); const QString &cn_fileGroupDefault = QStringLiteral("config/1");
const char *cn_contentTypeJPEG = "image/jpeg"; const char *cn_contentTypeJPEG = "image/jpeg";
const char *cn_contentTypePNG = "image/png"; const char *cn_contentTypePNG = "image/png";
const char *cn_contentTypeGIF = "image/gif"; const char *cn_contentTypeGIF = "image/gif";
const char *cn_contentTypeJSON = "application/json"; const char *cn_contentTypeJSON = "application/json";
const char *cn_contentTypeOctetSteam = "application/octet-stream";
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
web_server_bi::module_file::CController::uploadFile(const std::shared_ptr<IncomingRequest> &request) web_server_bi::module_file::CController::uploadFile(const std::shared_ptr<IncomingRequest> &request)
@ -53,7 +52,6 @@ web_server_bi::module_file::CController::uploadFile( const std::shared_ptr<Incom
return createDtoResponse(Status::CODE_400, spResp); return createDtoResponse(Status::CODE_400, spResp);
} }
// content -> file->getPayload()->getInMemoryData()->c_str() // content -> file->getPayload()->getInMemoryData()->c_str()
// content-type -> file->getHeader(Header::CONTENT_TYPE)->c_str() // content-type -> file->getHeader(Header::CONTENT_TYPE)->c_str()
// fileName -> file->getFilename()->c_str() // fileName -> file->getFilename()->c_str()
@ -61,9 +59,7 @@ web_server_bi::module_file::CController::uploadFile( const std::shared_ptr<Incom
QString strFileGroup, strFileName = file->getFilename()->c_str(); QString strFileGroup, strFileName = file->getFilename()->c_str();
qint64 uploadTime; qint64 uploadTime;
if( file->getHeader(Header::CONTENT_TYPE) == cn_contentTypeJPEG if (file->getHeader(Header::CONTENT_TYPE) == cn_contentTypeJPEG || file->getHeader(Header::CONTENT_TYPE) == cn_contentTypePNG || file->getHeader(Header::CONTENT_TYPE) == cn_contentTypeGIF)
|| file->getHeader(Header::CONTENT_TYPE) == cn_contentTypePNG
|| file->getHeader(Header::CONTENT_TYPE) == cn_contentTypeGIF )
{ {
strFileGroup = cn_fileGroupImage; strFileGroup = cn_fileGroupImage;
} }
@ -72,7 +68,6 @@ web_server_bi::module_file::CController::uploadFile( const std::shared_ptr<Incom
strFileGroup = cn_fileGroupJSON; strFileGroup = cn_fileGroupJSON;
} }
strFileName = CFileApi::uploadFile(strFileGroup, strFileName = CFileApi::uploadFile(strFileGroup,
strFileName, strFileName,
QByteArray(file->getPayload()->getInMemoryData()->c_str(), (int)(file->getPayload()->getInMemoryData()->size())), QByteArray(file->getPayload()->getInMemoryData()->c_str(), (int)(file->getPayload()->getInMemoryData()->size())),
@ -121,7 +116,209 @@ web_server_bi::module_file::CController::uploadFile( const std::shared_ptr<Incom
return createDtoResponse(Status::CODE_200, spResp); return createDtoResponse(Status::CODE_200, spResp);
} }
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
web_server_bi::module_file::CController::upLoadModel(const std::shared_ptr<IncomingRequest> &request)
{
/* Prepare multipart container. */
auto multipart = std::make_shared<multipart::PartList>(request->getHeaders());
/* Create multipart reader. */
multipart::Reader multipartReader(multipart.get());
/* Configure to read part with name "file" into memory */
multipartReader.setPartReader("file", multipart::createInMemoryPartReader(MAX_FILE_SIZE /* max-data-size */));
/* Read multipart body */
request->transferBody(&multipartReader);
/* Print value of "file" */
auto file = multipart->getNamedPart("file");
auto spResp = CUploadModelResp::createShared();
if (!file)
{
const std::string strMsg = I18N("无效的请求参数,文件为空");
spResp->code = 400;
LOGERROR("uploadFile()%s", strMsg.c_str());
spResp->message = strMsg;
return createDtoResponse(Status::CODE_400, spResp);
}
// content -> file->getPayload()->getInMemoryData()->c_str()
// content-type -> file->getHeader(Header::CONTENT_TYPE)->c_str()
// fileName -> file->getFilename()->c_str()
// fileSize -> file->getPayload()->getInMemoryData()->size()
QString strFileGroup, strParentCode, strFileName = file->getFilename()->c_str();
int nCategory;
bool bRc = false;
// 解析POST参数
{
strFileGroup = request->getQueryParameter("fileGroup").getValue("").c_str();
nCategory = QString(request->getQueryParameter("category").getValue("").c_str()).toInt(&bRc);
strParentCode = request->getQueryParameter("parentCode").getValue("").c_str();
}
if (!bRc)
{
// 返回失败
const std::string strMsg = I18N("无效的请求参数,category错误");
spResp->code = 400;
LOGERROR("upLoadModel()%s", strMsg.c_str());
spResp->message = strMsg;
return createDtoResponse(Status::CODE_400, spResp);
}
if (file->getHeader(Header::CONTENT_TYPE) != cn_contentTypeOctetSteam)
{
// 返回失败
const std::string strMsg = I18N("无效的请求参数,contentType应为application/octet-stream");
spResp->code = 400;
LOGERROR("upLoadModel()%s", strMsg.c_str());
spResp->message = strMsg;
return createDtoResponse(Status::CODE_400, spResp);
}
iot_dbms::CDbApi objDbConn( DB_CONN_MODEL_WRITE );
if ( !objDbConn.open())
{
const std::string strMsg = I18N("数据库连接建立失败");
LOGERROR("upLoadModel()%s", strMsg.c_str());
spResp->code = 500;
spResp->message = strMsg;
return createDtoResponse(Status::CODE_500, spResp);
}
// content filegroup category parentCode
bool result = CFileApi::uploadModel(strParentCode,
strFileGroup,
strFileName,
nCategory,
QByteArray(file->getPayload()->getInMemoryData()->c_str(), (int)(file->getPayload()->getInMemoryData()->size())),
&objDbConn);
if (!result)
{
const std::string strMsg = I18N("保存模型失败");
LOGERROR("upLoadModel()%s", strMsg.c_str());
spResp->code = 500;
spResp->message = strMsg;
return createDtoResponse(Status::CODE_500, spResp);
}
spResp->code = 200;
spResp->message = cn_strSuccess;
LOGINFO("uploadModel :%s,fileSize:%zu", file->getFilename()->c_str(), file->getPayload()->getInMemoryData()->size());
return createDtoResponse(Status::CODE_200, spResp);
}
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
web_server_bi::module_file::CController::uploadByString(const std::shared_ptr<IncomingRequest> &request)
{
auto spResp = CUploadFileResp::createShared();
auto multipart = std::make_shared<multipart::PartList>(request->getHeaders());
multipart::Reader multipartReader(multipart.get());
multipartReader.setPartReader("fileGroup", multipart::createInMemoryPartReader(1024l /* max-data-size */));
multipartReader.setPartReader("fileName", multipart::createInMemoryPartReader(1024l /* max-data-size */));
multipartReader.setPartReader("str", multipart::createInMemoryPartReader(1024l * 50l /* max-data-size */));
request->transferBody(&multipartReader);
auto objFileGroup = multipart->getNamedPart("fileGroup");
auto objFileName = multipart->getNamedPart("fileName");
auto objStr = multipart->getNamedPart("str");
QString strFileGroup, strFileName, strContent;
strFileGroup = objFileGroup->getPayload()->getInMemoryData()->c_str();
strFileName = objFileName->getPayload()->getInMemoryData()->c_str();
strContent = objStr->getPayload()->getInMemoryData()->c_str();
// LOGERROR("body is %s",request->readBodyToString()->c_str() );
// QUrlQuery objUrlQuery( QUrl::fromPercentEncoding( request->readBodyToString()->c_str() ) );
// strFileGroup = objUrlQuery.queryItemValue("fileGroup");
// strFileName = objUrlQuery.queryItemValue("fileName");
// strContent = objUrlQuery.queryItemValue("str");
// strFileGroup = request->getQueryParameter("fileGroup").getValue("").c_str();
// strFileName = request->getQueryParameter("fileName").getValue("").c_str();
// strContent = request->getQueryParameter("str").getValue("").c_str();
if( strFileGroup.isEmpty() )
{
const std::string strMsg = I18N("fileGroup参数为空");
LOGERROR("uploadByString()%s", strMsg.c_str());
spResp->code = 500;
spResp->message = strMsg;
return createDtoResponse(Status::CODE_500, spResp);
}
if( strFileName.isEmpty() )
{
const std::string strMsg = I18N("fileName参数为空");
LOGERROR("uploadByString()%s", strMsg.c_str());
spResp->code = 500;
spResp->message = strMsg;
return createDtoResponse(Status::CODE_500, spResp);
}
if( strContent.isEmpty() )
{
const std::string strMsg = I18N("str为空");
LOGERROR("uploadByString()%s", strMsg.c_str());
spResp->code = 500;
spResp->message = strMsg;
return createDtoResponse(Status::CODE_500, spResp);
}
qint64 uploadTime;
QString strSavedFileName = CFileApi::uploadFile(strFileGroup,
strFileName,
strContent.toUtf8(),
nullptr,
&uploadTime);
if (strSavedFileName.isEmpty())
{
const std::string strMsg = I18N("保存文件失败");
LOGERROR("uploadFile()%s", strMsg.c_str());
spResp->code = 500;
spResp->message = strMsg;
return createDtoResponse(Status::CODE_500, spResp);
}
spResp->data = COneFile::createShared();
QString strExt, strId;
int extIndex;
if ((extIndex = strSavedFileName.lastIndexOf(".")) != -1)
{
strId = strSavedFileName.left(extIndex);
strExt = strSavedFileName.mid(extIndex, -1);
}
else
{
const std::string strMsg = I18N("服务器内部错误,文件名错误");
spResp->code = 502;
LOGERROR("uploadFile()%s", strMsg.c_str());
spResp->message = strMsg;
return createDtoResponse(Status::CODE_502, spResp);
}
spResp->data->ext = strExt.toStdString();
spResp->data->path = (strFileGroup + "/" + strSavedFileName).toStdString();
spResp->data->size = strContent.size() / 1024.0;
spResp->data->name = strFileName.toStdString();
spResp->data->id = strId.toStdString();
spResp->data->fileGroup = strFileGroup.toStdString();
spResp->data->uploadTime = uploadTime;
spResp->data->url = CFileApi::getUrl(strFileGroup, strSavedFileName).toStdString();
spResp->data->status = 0;
spResp->code = 200;
spResp->message = cn_strSuccess;
LOGINFO("uploadByString file:%s,fileSize:%zu", strFileName.toStdString().c_str(), strContent.size());
return createDtoResponse(Status::CODE_200, spResp);}
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
web_server_bi::module_file::CController::getFileByPath(const std::shared_ptr<IncomingRequest> &request) web_server_bi::module_file::CController::getFileByPath(const std::shared_ptr<IncomingRequest> &request)
@ -161,10 +358,7 @@ web_server_bi::module_file::CController::getFileByPath( const std::shared_ptr<In
{ {
response->putHeader("Content-Type", cn_contentTypeJSON); response->putHeader("Content-Type", cn_contentTypeJSON);
} }
else if( strExt == "png" else if (strExt == "png" || strExt == "gif" || strExt == "jpg" || strExt == "jpeg")
|| strExt == "gif"
|| strExt == "jpg"
|| strExt == "jpeg")
{ {
response->putHeader("Content-Type", QString("image/%1").arg(strExt).toStdString()); response->putHeader("Content-Type", QString("image/%1").arg(strExt).toStdString());
} }
@ -182,7 +376,6 @@ web_server_bi::module_file::CController::getFileByNameAndGroup( const std::share
} }
strFileGroup = QUrl::fromPercentEncoding(strFileGroup->c_str()).toStdString(); strFileGroup = QUrl::fromPercentEncoding(strFileGroup->c_str()).toStdString();
String strFileName = request->getQueryParameter("fileName"); String strFileName = request->getQueryParameter("fileName");
if (strFileName.get() == nullptr || strFileName->empty()) if (strFileName.get() == nullptr || strFileName->empty())
{ {
@ -192,7 +385,6 @@ web_server_bi::module_file::CController::getFileByNameAndGroup( const std::share
} }
strFileName = QUrl::fromPercentEncoding(strFileName->c_str()).toStdString(); strFileName = QUrl::fromPercentEncoding(strFileName->c_str()).toStdString();
String strPath = strFileGroup + "/" + strFileName; String strPath = strFileGroup + "/" + strFileName;
// TODO 图片特殊处理 // TODO 图片特殊处理
@ -202,11 +394,16 @@ web_server_bi::module_file::CController::getFileByNameAndGroup( const std::share
QByteArray baContent; QByteArray baContent;
if (!CFileApi::readFileByPath(strPath->c_str(), baContent)) if (!CFileApi::readFileByPath(strPath->c_str(), baContent))
{
if (!CFileApi::readFileByFileNameAndGroup(strFileName->c_str(),strFileGroup->c_str(), baContent))
{ {
const std::string strMsg = I18N("读取文件失败"); const std::string strMsg = I18N("读取文件失败");
LOGERROR("getFileByNameAndGroup()%s", strMsg.c_str()); LOGERROR("getFileByNameAndGroup()%s", strMsg.c_str());
return createResponse(Status::CODE_500, strMsg); return createResponse(Status::CODE_500, strMsg);
} }
}
// Content-Type 处理 // Content-Type 处理
QString strExt, strFilePath = strPath->c_str(); QString strExt, strFilePath = strPath->c_str();
@ -221,10 +418,7 @@ web_server_bi::module_file::CController::getFileByNameAndGroup( const std::share
{ {
response->putHeader("Content-Type", cn_contentTypeJSON); response->putHeader("Content-Type", cn_contentTypeJSON);
} }
else if( strExt == "png" else if (strExt == "png" || strExt == "gif" || strExt == "jpg" || strExt == "jpeg")
|| strExt == "gif"
|| strExt == "jpg"
|| strExt == "jpeg")
{ {
response->putHeader("Content-Type", QString("image/%1").arg(strExt).toStdString()); response->putHeader("Content-Type", QString("image/%1").arg(strExt).toStdString());
} }
@ -280,10 +474,7 @@ web_server_bi::module_file::CController::getContentByPath( const std::shared_ptr
{ {
response->putHeader("Content-Type", cn_contentTypeJSON); response->putHeader("Content-Type", cn_contentTypeJSON);
} }
else if( strExt == "png" else if (strExt == "png" || strExt == "gif" || strExt == "jpg" || strExt == "jpeg")
|| strExt == "gif"
|| strExt == "jpg"
|| strExt == "jpeg")
{ {
response->putHeader("Content-Type", QString("image/%1").arg(strExt).toStdString()); response->putHeader("Content-Type", QString("image/%1").arg(strExt).toStdString());
} }

View File

@ -28,18 +28,45 @@ public:
public: public:
/**
* @brief
*/
ENDPOINT( "POST", "/api-common/config/uploadFile",uploadFile, ENDPOINT( "POST", "/api-common/config/uploadFile",uploadFile,
REQUEST( std::shared_ptr<IncomingRequest>, request ) ); REQUEST( std::shared_ptr<IncomingRequest>, request ) );
/**
* @brief 3d模型
*/
ENDPOINT( "POST", "/api-common/config/upLoadModel",upLoadModel,
REQUEST( std::shared_ptr<IncomingRequest>, request ) );
/**
* @brief
*/
ENDPOINT( "POST", "/api-file/file/upload/uploadByString",uploadByString,
REQUEST( std::shared_ptr<IncomingRequest>, request ) );
/**
* @brief
*/
ENDPOINT( "GET", "/api-file/file/get/getFileByPath", getFileByPath, ENDPOINT( "GET", "/api-file/file/get/getFileByPath", getFileByPath,
REQUEST( std::shared_ptr<IncomingRequest>, request ) ); REQUEST( std::shared_ptr<IncomingRequest>, request ) );
/**
* @brief
*/
ENDPOINT( "GET", "/api-file/file/get/getFileByNameAndGroup", getFileByNameAndGroup, ENDPOINT( "GET", "/api-file/file/get/getFileByNameAndGroup", getFileByNameAndGroup,
REQUEST( std::shared_ptr<IncomingRequest>, request ) ); REQUEST( std::shared_ptr<IncomingRequest>, request ) );
/**
* @brief
*/
ENDPOINT( "GET", "/api-file/file/get/getContentByPath", getContentByPath, ENDPOINT( "GET", "/api-file/file/get/getContentByPath", getContentByPath,
REQUEST( std::shared_ptr<IncomingRequest>, request ) ); REQUEST( std::shared_ptr<IncomingRequest>, request ) );
/**
* @brief
*/
ENDPOINT( "GET", "/api-sys/getSystemTime", getSystemTime ); ENDPOINT( "GET", "/api-sys/getSystemTime", getSystemTime );
}; };

View File

@ -35,6 +35,14 @@ class CUploadFileResp : public oatpp::DTO
DTO_FIELD( Object < COneFile >, data ); DTO_FIELD( Object < COneFile >, data );
}; };
class CUploadModelResp : public oatpp::DTO
{
DTO_INIT( CUploadModelResp, DTO );
DTO_FIELD( Int32, code );
DTO_FIELD( String, message );
DTO_FIELD( Object < COneFile >, data );
};
class CGetFileResp : public oatpp::DTO class CGetFileResp : public oatpp::DTO
{ {
DTO_INIT( CGetFileResp, DTO ); DTO_INIT( CGetFileResp, DTO );

View File

@ -4,6 +4,7 @@
#include "oatpp/web/server/HttpRouter.hpp" #include "oatpp/web/server/HttpRouter.hpp"
#include "CController.h" #include "CController.h"
#include "CModule.h" #include "CModule.h"
#include "SyncthingMngThread.h"
#include "pub_sysinfo_api/SysInfoApi.h" #include "pub_sysinfo_api/SysInfoApi.h"
@ -20,6 +21,46 @@ bool CModule::init()
OATPP_COMPONENT( std::shared_ptr<oatpp::web::server::HttpRouter>, router, "simpleRouter" ); OATPP_COMPONENT( std::shared_ptr<oatpp::web::server::HttpRouter>, router, "simpleRouter" );
router->addController( std::make_shared<CController>()); router->addController( std::make_shared<CController>());
bool isSingleNode = false;
{
iot_public::CSysInfoInterfacePtr ptrSysInfo;
if ( iot_public::createSysInfoInstance( ptrSysInfo ) == false )
{
LOGFATAL( "createSysInfoInstance() return false !" );
return false;
}
//< 获取本机域ID和主机名
{
iot_public::SNodeInfo stLocalNodeInfo;
if ( iotSuccess != ptrSysInfo->getLocalNodeInfo( stLocalNodeInfo ))
{
LOGFATAL( "getLocalNodeInfo() failed !" );
return false;
}
if( "127.0.0.1" == stLocalNodeInfo.strNic1Addr)
{
isSingleNode = true;
}
}
}
if( !isSingleNode )
{
m_ptrSyncthingMngThread = boost::make_shared<SyncthingMngThread>();
if ( m_ptrSyncthingMngThread == nullptr )
{
LOGERROR( "cannot syncthingmngthread class" );
return false;
}
if ( false == m_ptrSyncthingMngThread->init())
{
LOGERROR( "cannot initialize syncthingmngthread class " );
return false;
}
}
return true; return true;
} }
@ -39,6 +80,12 @@ bool CModule::clean()
//< todo 貌似没有 addController 的逆操作 //< todo 貌似没有 addController 的逆操作
//< todo 清理业务资源 //< todo 清理业务资源
if ( m_ptrSyncthingMngThread != nullptr )
{
m_ptrSyncthingMngThread->quit();
m_ptrSyncthingMngThread.reset();
}
return true; return true;
} }

View File

@ -2,6 +2,8 @@
#include "../include/BaseModule.h" #include "../include/BaseModule.h"
class SyncthingMngThread;
typedef boost::shared_ptr<SyncthingMngThread> SyncthingMngThreadPtr;
namespace web_server_bi { namespace module_file namespace web_server_bi { namespace module_file
{ {
@ -16,6 +18,7 @@ public:
bool redundantSwitch( bool bMaster, bool bSlave ) override; bool redundantSwitch( bool bMaster, bool bSlave ) override;
bool clean() override; bool clean() override;
static boost::shared_ptr<CModule> create(); static boost::shared_ptr<CModule> create();
SyncthingMngThreadPtr m_ptrSyncthingMngThread = nullptr;
}; };

View File

@ -0,0 +1,342 @@
#include "SyncthingMngThread.h"
#include "oatpp/web/client/HttpRequestExecutor.hpp"
#include "oatpp/network/tcp/client/ConnectionProvider.hpp"
#include "oatpp/core/macro/component.hpp"
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
#include "pub_logger_api/logger.h"
#include "../include/ServerApi.h"
#include "pub_utility_api/FileUtil.h"
#include "MessageChannel.h"
#include "rapidjson/document.h"
#include "Common.h"
#include <QProcess>
#include <QDir>
#include <QThread>
#include <SyncthingRestDTO.hpp>
#define SYNCTHING_GUI_APIKEY EMS_DEFAULT_PASSWD
SyncthingMngThread::SyncthingMngThread() : iot_public::CTimerThreadBase( "SyncthingMngThread", 1000 )
{
m_strSyncthingHomePath = iot_public::CFileUtil::getSimplePath( iot_public::CFileUtil::getCurModuleDir() + "../../data/syncthing_home").c_str();
m_strWebserverDataPath = iot_public::CFileUtil::getSimplePath(iot_public::CFileUtil::getCurModuleDir() + "../../data/web_server_files");
}
SyncthingMngThread::~SyncthingMngThread()
{
if(!stopSyncthing())
{
LOGERROR("cannot stop syncthing");
}
}
bool SyncthingMngThread::init()
{
if(!stopSyncthing())
{
LOGERROR("cannot stop syncthing");
return false;
}
if( !startSyncthing() )
{
LOGERROR("cannot start syncthing ");
return false;
}
if( m_comm.addSub(web_server_bi::getServerApi()->getRunAppInfo().nAppId,CH_WEB_FILE_SYNCTHING_BROADCAST) )
{
LOGINFO( "订阅通道:%d[CH_WEB_FILE_SYNCTHING_BROADCAST]成功", CH_WEB_FILE_SYNCTHING_BROADCAST );
}
else
{
LOGERROR( "订阅通道:%d[CH_WEB_FILE_SYNCTHING_BROADCAST]失败", CH_WEB_FILE_SYNCTHING_BROADCAST );
return false;
}
{
OATPP_COMPONENT( std::shared_ptr<oatpp::data::mapping::ObjectMapper>, objectMapper );
auto connectionProvider = oatpp::network::tcp::client::ConnectionProvider::createShared({"127.0.0.1", 8384});
auto requestExecutor = oatpp::web::client::HttpRequestExecutor::createShared(connectionProvider);
m_client = CSynctingRestOp::createShared(requestExecutor, objectMapper);
}
resume();
return true;
}
int SyncthingMngThread::beforeExecute()
{
m_runAppInfo = web_server_bi::getServerApi()->getRunAppInfo();
int cnt = 0;
while(!getDeviceId())
{
LOGERROR("cannot get device id,retryCnt:%d",cnt);
QThread::msleep(500);
if(++cnt > 20)
{
LOGERROR("beyond limited times to get device id, stop syncthing");
stopSyncthing();
return iotFailed;
}
}
return iotSuccess;
}
bool SyncthingMngThread::startSyncthing()
{
QString syncthingPath = iot_public::CFileUtil::getPathOfBinFile("syncthing").c_str();
QStringList args;
args << QString("--home=%1").arg(m_strSyncthingHomePath)
<< QString("--gui-apikey=%1").arg(SYNCTHING_GUI_APIKEY)
#ifdef OS_WINDOWS
<< "--no-console"
#endif
<< "--no-browser"
<< "--no-default-folder"
<< "--no-upgrade";
if( !QProcess::startDetached(syncthingPath,args))
{
LOGERROR("cannot start detached syncthing srv!");
return false;
}
return true;
}
bool SyncthingMngThread::stopSyncthing()
{
QString syncthingPath = iot_public::CFileUtil::getPathOfBinFile("syncthing").c_str();
QStringList args;
args << "cli"
<< QString("--home=%1").arg(m_strSyncthingHomePath)
<< "operations"
<< "shutdown";
QProcess syncthing;
syncthing.start(syncthingPath, args);
if (!syncthing.waitForStarted())
{
LOGERROR("cannot start syncthing cli tool to terminate syncthing srv.");
return false;
}
if (!syncthing.waitForFinished())
{
LOGERROR("cannot terminate syncthing cli tool.");
return false;
}
return true;
}
void SyncthingMngThread::broadcast()
{
iot_net::CMbMessage msg;
msg.setData( m_strHandshake.c_str(), m_strHandshake.size() );
msg.setSubject(m_runAppInfo.nAppId,CH_WEB_FILE_SYNCTHING_BROADCAST);
if(!m_comm.sendMsgToDomain(msg)){
LOGERROR("cannot send broadcast msg");
}
}
void SyncthingMngThread::genSyncthingCfg()
{
// 生成对象
oatpp::List<oatpp::Object<CDeviceDTO>> devices = oatpp::List<oatpp::Object<CDeviceDTO>>::createShared();
{
auto currentDevie = CDeviceDTO::createShared();
currentDevie->deviceID = m_strDeviceId;
devices->insert( devices->end(),currentDevie);
for(auto it = m_mapDeviceId.begin(); it != m_mapDeviceId.end(); ++it)
{
auto OneDevice = CDeviceDTO::createShared();
OneDevice->deviceID = it->first;
devices->insert( devices->end(),OneDevice);
}
}
oatpp::List<oatpp::Object<CFolderDTO>> folders = oatpp::List<oatpp::Object<CFolderDTO>>::createShared();
{
auto oneFolder = CFolderDTO::createShared();
oneFolder->id = "web_server_files";
oneFolder->path = m_strWebserverDataPath;
for(auto it = m_mapDeviceId.begin(); it != m_mapDeviceId.end(); ++it)
{
auto oneDevice = CFolderDeivceDTO::createShared();
oneDevice->deviceId = it->first;
oneFolder->devices->insert( oneFolder->devices->end(),oneDevice);
}
folders->insert(folders->end(),oneFolder);
}
OATPP_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>,objectMapper);
auto devicesJson = objectMapper->writeToString(devices);
auto folderJson = objectMapper->writeToString(folders);
char retryCnt = 0;
bool isRequestCorrent = false;
while(!isRequestCorrent && retryCnt < 60){
try{
// 先设置devices再设置folder
auto code = m_client->putDevices(SYNCTHING_GUI_APIKEY,devicesJson)->getStatusCode();
if( code != 200)
{
LOGERROR("cannot put devices of syncthing! code:[%d]",code);
return ;
}
code = m_client->putFolders(SYNCTHING_GUI_APIKEY,folderJson)->getStatusCode();
if( code != 200)
{
LOGERROR("cannot put folders of syncthing! code:[%d]",code);
return ;
}
if(retryCnt != 0)
{
LOGINFO("genSyncthingCfg done! total retry cnt:%d",retryCnt);
}
isRequestCorrent = true;
}catch(const std::exception &exc){
LOGINFO("catch exception:%s,retry cnt:[%d]",exc.what(),retryCnt);
++retryCnt;
QThread::msleep(500); // 500 * 60 最多30秒钟
continue;
}
}
}
void SyncthingMngThread::deleteDevice(const std::string &deviceId)
{
auto code = m_client->deleteDevice(SYNCTHING_GUI_APIKEY,deviceId)->getStatusCode();
if( code != 200)
{
LOGERROR("cannot delete deviceId:[%s]! code:[%d]",deviceId.c_str(),code);
return ;
}
}
bool SyncthingMngThread::getDeviceId()
{
QString syncthingPath = iot_public::CFileUtil::getPathOfBinFile("syncthing").c_str();
QStringList args;
args << QString("--home=%1").arg(m_strSyncthingHomePath)
<< "--device-id";
QProcess syncthing;
syncthing.start(syncthingPath, args);
if (!syncthing.waitForStarted()){
LOGERROR("cannot start syncthing srv to get device id");
return false;
}
if (!syncthing.waitForFinished()){
LOGERROR("cannot terminate syncthing srv to get device id");
return false;
}
if( syncthing.exitCode() != 0)
{
LOGERROR("cannot terminate syncthing srv to get device id");
return false;
}
m_strDeviceId = syncthing.readAll().toStdString();
m_strDeviceId = QString(m_strDeviceId.c_str()).trimmed().toStdString();
LOGINFO("current syncthing deviceId is %s",m_strDeviceId.c_str());
m_strHandshake = QString("{\"DEVICE_ID\":\"%1\"}").arg(m_strDeviceId.c_str()).toStdString();
return true;
}
void SyncthingMngThread::execute()
{
broadcast();
iot_net::CMbMessage objMsg;
bool bNeedRefresh = false;
std::list<std::string> listDeviceId;
while( m_comm.recvMsg(objMsg, 0 ) )
{
const std::string strRcvData((char *) objMsg.getDataPtr(), objMsg.getDataSize());
using namespace rapidjson;
Document d;
d.Parse(strRcvData.c_str());
if ( d.HasParseError() )
{
continue;
}
Value& s = d["DEVICE_ID"];
if( !s.IsString() )
{
continue;
}
std::string device_id = s.GetString();
if( device_id == m_strDeviceId)
{
continue;
}
else
{
listDeviceId.push_back(device_id);
if(m_mapDeviceId.find(device_id) == m_mapDeviceId.end())
{
LOGINFO("device id:[%s] added!",device_id.c_str());
bNeedRefresh = true;
}
}
}
for(auto it = listDeviceId.begin(); it != listDeviceId.end(); ++it)
{
m_mapDeviceId[*it] = 5;
}
for(auto it = m_mapDeviceId.begin(); it != m_mapDeviceId.end(); )
{
it->second -= 1;
if( it->second <= 0 )
{
LOGINFO("device id:[%s] removed!",it->first.c_str());
deleteDevice(it->first);
it = m_mapDeviceId.erase(it);
bNeedRefresh = true;
}
else
{
++it;
}
}
if( bNeedRefresh )
{
genSyncthingCfg();
}
}

View File

@ -0,0 +1,50 @@
#ifndef SYNCTHINGMNGTHREAD_H
#define SYNCTHINGMNGTHREAD_H
#include "pub_utility_api/TimerThreadBase.h"
#include <QString>
#include <QMap>
#include "net_msg_bus_api/CMbCommunicator.h"
#include "pub_sysinfo_api/SysInfoBase.h"
#include "SyncthingRestOp.hpp"
class SyncthingMngThread : public iot_public::CTimerThreadBase
{
public:
SyncthingMngThread();
~SyncthingMngThread();
int beforeExecute() override;
void execute() override;
bool init();
private:
bool startSyncthing();
bool stopSyncthing();
void broadcast();
void genSyncthingCfg();
void deleteDevice(const std::string& deviceId);
bool getDeviceId();
std::string m_strDeviceId;
std::string m_strHandshake;
QString m_strSyncthingHomePath;
std::string m_strWebserverDataPath;
std::map<std::string,int> m_mapDeviceId;
iot_net::CMbCommunicator m_comm;
iot_public::SRunAppInfo m_runAppInfo;
std::shared_ptr<CSynctingRestOp> m_client;
};
typedef boost::shared_ptr<SyncthingMngThread> SyncthingMngThreadPtr;
#endif // SYNCTHINGMNGTHREAD_H

View File

@ -0,0 +1,115 @@
#pragma once
#include "oatpp/core/Types.hpp"
#include "oatpp/core/macro/codegen.hpp"
#include OATPP_CODEGEN_BEGIN( DTO )
class COneFile : public oatpp::DTO
{
DTO_INIT( COneFile, DTO );
DTO_FIELD( String, ext );
// DTO_FIELD( String, uid );
DTO_FIELD( String, path );
DTO_FIELD( Int32, size );
DTO_FIELD( String, name );
// DTO_FIELD( String, businessId );
// DTO_FIELD( String, remark );
DTO_FIELD( String, id );
DTO_FIELD( String, fileGroup );
DTO_FIELD( Int64, uploadTime );
DTO_FIELD( String, url );
DTO_FIELD( Int32, status );
};
class CUploadFileResp : public oatpp::DTO
{
DTO_INIT( CUploadFileResp, DTO );
DTO_FIELD( Int32, code );
DTO_FIELD( String, message );
DTO_FIELD( Object < COneFile >, data );
};
class CGetFileResp : public oatpp::DTO
{
DTO_INIT( CGetFileResp, DTO );
DTO_FIELD( Int32, code );
DTO_FIELD( String, message );
DTO_FIELD( String, data );
};
//{
//"deviceID": "F46QWSG-SYDYEUL-PVCODDC-QXMANDQ-VYP76DQ-L2CLSHN-LBQAJJE-XTK6VQV",
//"name": "centosyh1",
//"addresses": [
// "dynamic"
//],
//"compression": "metadata",
//"certName": "",
//"introducer": false,
//"skipIntroductionRemovals": false,
//"introducedBy": "",
//"paused": false,
//"allowedNetworks": [],
//"autoAcceptFolders": false,
//"maxSendKbps": 0,
//"maxRecvKbps": 0,
//"ignoredFolders": [],
//"maxRequestKiB": 0,
//"untrusted": false,
//"remoteGUIPort": 0
//}
class CDeviceDTO : public oatpp::DTO
{
DTO_INIT( CDeviceDTO, DTO );
DTO_FIELD( String, deviceID ) = "";
DTO_FIELD( String, name ) = "";
DTO_FIELD( List<String>, addresses ) = {"dynamic"};
DTO_FIELD( String, compression ) = "metadata";
DTO_FIELD( String, certName ) = "";
DTO_FIELD( Boolean, introducer ) = false;
DTO_FIELD( Boolean, skipIntroductionRemovals ) = false;
DTO_FIELD( String, introducedBy ) = "";
DTO_FIELD( Boolean, paused ) = false;
DTO_FIELD( List<String>, allowedNetworks ) = {};
DTO_FIELD( Boolean, autoAcceptFolders ) = false;
DTO_FIELD( Int32, maxSendKbps ) = 0;
DTO_FIELD( Int32, maxRecvKbps ) = 0;
DTO_FIELD( List<String>, ignoredFolders ) = {};
DTO_FIELD( Int32, maxRequestKiB ) = 0;
DTO_FIELD( Boolean, untrusted ) = false;
DTO_FIELD( Int32, remoteGUIPort ) = 0;
};
class CFolderDeivceDTO : public oatpp::DTO
{
DTO_INIT( CFolderDeivceDTO, DTO );
DTO_FIELD( String, deviceId ) = "";
DTO_FIELD( String, introducedBy ) = "";
DTO_FIELD( String, encryptionPassword ) = "";
};
// 其他属性忽略了,有需要再加
class CFolderDTO : public oatpp::DTO
{
DTO_INIT( CFolderDTO, DTO );
DTO_FIELD( String, id ) = "";
DTO_FIELD( String, path ) = "";
DTO_FIELD( List <Object<CFolderDeivceDTO>>, devices ) = {};
};
#include OATPP_CODEGEN_END( DTO )

View File

@ -0,0 +1,23 @@
#ifndef SYNCTHINGRESTOP_HPP
#define SYNCTHINGRESTOP_HPP
#include <SyncthingRestDTO.hpp>
#include "oatpp/web/client/ApiClient.hpp"
#include "oatpp/core/macro/codegen.hpp"
class CSynctingRestOp : public oatpp::web::client::ApiClient {
#include OATPP_CODEGEN_BEGIN(ApiClient)
API_CLIENT_INIT(CSynctingRestOp)
API_CALL("PUT", "rest/config/devices", putDevices,HEADER(String, guiApiKey, "X-API-Key"),BODY_STRING( String,devices) )
API_CALL("PUT", "rest/config/folders", putFolders,HEADER(String, guiApiKey, "X-API-Key"),BODY_STRING(String,folders) )
API_CALL("DELETE", "rest/config/devices/{deviceId}", deleteDevice,HEADER(String, guiApiKey, "X-API-Key"), PATH(String, deviceId))
#include OATPP_CODEGEN_END(ApiClient)
};
#endif // SYNCTHINGRESTOP_HPP

View File

@ -10,10 +10,14 @@ HEADERS += \
CController.h \ CController.h \
CDTO.h \ CDTO.h \
CModule.h \ CModule.h \
SyncthingMngThread.h \
SyncthingRestOp.hpp \
SyncthingRestDTO.hpp
SOURCES += \ SOURCES += \
CModule.cpp \ CModule.cpp \
CController.cpp \ CController.cpp \
SyncthingMngThread.cpp
#静态库不要连接统一在server中连接 #静态库不要连接统一在server中连接

View File

@ -563,7 +563,27 @@ CController::getPointsByDeviceCode( const String& deviceCode, const String& poin
// 查询测点信息 // 查询测点信息
QSqlQuery objQuery; QSqlQuery objQuery;
QString sSql = ""; QString sSql = QString("select t2.TAG_NAME from dev_info as t1 "
" left join sys_model_sub_system_info as t2 "
" on t1.SUB_SYSTEM = t2.SUB_SYSTEM_ID "
" where t1.TAG_NAME='%1';").arg(deviceCode.get()->c_str());
if ( !objDb.execute(sSql,objQuery) )
{
pPoint->code = 500;
pPoint->message = "查询关系库表 " + sTableName.toStdString() + " 失败";
LOGERROR("%s",pPoint->message->c_str());
return createDtoResponse( Status::CODE_200, pPoint );
}
QString sub_system_tag;
while ( objQuery.next() )
{
sub_system_tag = objQuery.value(0).toString();
}
QString location_tag = QString(deviceCode->c_str()).split('.')[0];
objQuery.clear();
sSql.clear();
if ( bDigital ) if ( bDigital )
sSql = QString("select tag_name,description,state_text_name from %1 where device='%2'").arg(sTableName).arg(deviceCode.get()->c_str()); sSql = QString("select tag_name,description,state_text_name from %1 where device='%2'").arg(sTableName).arg(deviceCode.get()->c_str());
else else
@ -582,6 +602,7 @@ CController::getPointsByDeviceCode( const String& deviceCode, const String& poin
pData->tagCode = sTableName.toStdString() + "." + objQuery.value(0).toString().toStdString() + ".value"; pData->tagCode = sTableName.toStdString() + "." + objQuery.value(0).toString().toStdString() + ".value";
//pData->tagCode = objQuery.value(0).toString().toStdString(); //pData->tagCode = objQuery.value(0).toString().toStdString();
pData->tagName = objQuery.value(1).toString().toStdString(); pData->tagName = objQuery.value(1).toString().toStdString();
pData->details = (location_tag + "." + sub_system_tag).toStdString();
pData->name = pData->tagName; pData->name = pData->tagName;
pData->coefficient = 1; pData->coefficient = 1;
pData->pointType = std::stoi(pointType.get()->c_str(),nullptr,0); pData->pointType = std::stoi(pointType.get()->c_str(),nullptr,0);

View File

@ -18,6 +18,7 @@ namespace module_page
//< 云平台中规则为config/租户id/文件类型我们不区分租户假定租户id为1 //< 云平台中规则为config/租户id/文件类型我们不区分租户假定租户id为1
const QString &cn_strJsonFileGrp = QStringLiteral( "config/1/json" ); const QString &cn_strJsonFileGrp = QStringLiteral( "config/1/json" );
const QString &cn_str3DFileGrp = QStringLiteral( "3D" );
//< 存数据库时将 full 换成 short响应前端时把 short 换成 full目的 //< 存数据库时将 full 换成 short响应前端时把 short 换成 full目的
//< 1、数据库中不存文件接口以防接口改名老工程无法兼容 //< 1、数据库中不存文件接口以防接口改名老工程无法兼容
@ -65,7 +66,18 @@ QString fillOnePrimitive( const QSqlQuery &objQuery, dto::COnePrimitive::Wrapper
strTemp = objQuery.value( WebPrimitiveCol::content_path ).toString(); strTemp = objQuery.value( WebPrimitiveCol::content_path ).toString();
if ( !strTemp.isEmpty()) if ( !strTemp.isEmpty())
spOut->contentPath = CFileApi::getUrl( cn_strJsonFileGrp, strTemp ).toStdString(); {
QString fileGrp;
if( spOut->category == 6)
{
fileGrp = cn_str3DFileGrp;
}
else
{
fileGrp = cn_strJsonFileGrp;
}
spOut->contentPath = CFileApi::getUrl( fileGrp, strTemp ).toStdString();
}
strTemp = objQuery.value( WebPrimitiveCol::icon_info ).toString(); strTemp = objQuery.value( WebPrimitiveCol::icon_info ).toString();
if ( !strTemp.isEmpty()) if ( !strTemp.isEmpty())

View File

@ -22,6 +22,7 @@ namespace module_page
{ {
extern const QString &cn_strJsonFileGrp; extern const QString &cn_strJsonFileGrp;
extern const QString &cn_str3DFileGrp;
extern const QString &cn_strIconPathShort; extern const QString &cn_strIconPathShort;
extern const QString cn_strIconPathFull; extern const QString cn_strIconPathFull;

View File

@ -465,7 +465,7 @@ CSimpleCtrlPage::selectList( const std::shared_ptr<IncomingRequest> &spRequest )
} }
//< 是否显示区域 //< 是否显示区域
if ( spRootPage->showArea.get() != nullptr && spRootPage->showArea != 0 ) if ( spRootPage->showArea.get() != nullptr && ( nReqPageType == 1 || spRootPage->showArea != 0 ) )
{ {
//< location //< location
strSql = "SELECT location_id,description,plocation_id FROM sys_model_location_info"; strSql = "SELECT location_id,description,plocation_id FROM sys_model_location_info";
@ -492,8 +492,12 @@ CSimpleCtrlPage::selectList( const std::shared_ptr<IncomingRequest> &spRequest )
mapAllPage.insert( strId, spOneData ); mapAllPage.insert( strId, spOneData );
//< todo 当前未判权限,只有有权限的才加入 spRespData //< todo 当前未判权限,只有有权限的才加入 spRespData
if( nReqPageType != 1 ) // 3d时跳过
{
spRespData->push_back( spOneData ); spRespData->push_back( spOneData );
} }
}
} }
else else
return createDtoResponse( Status::CODE_200, fillDbErrToResp( objDbConn, spResp )); return createDtoResponse( Status::CODE_200, fillDbErrToResp( objDbConn, spResp ));
@ -517,8 +521,12 @@ CSimpleCtrlPage::selectList( const std::shared_ptr<IncomingRequest> &spRequest )
mapAllPage.insert( strId, spOneData ); mapAllPage.insert( strId, spOneData );
//< todo 当前未判权限,只有有权限的才加入 spRespData //< todo 当前未判权限,只有有权限的才加入 spRespData
if( nReqPageType != 1 ) // 3d时跳过
{
spRespData->push_back( spOneData ); spRespData->push_back( spOneData );
} }
}
} }
else else
return createDtoResponse( Status::CODE_200, fillDbErrToResp( objDbConn, spResp )); return createDtoResponse( Status::CODE_200, fillDbErrToResp( objDbConn, spResp ));
@ -533,6 +541,9 @@ CSimpleCtrlPage::selectList( const std::shared_ptr<IncomingRequest> &spRequest )
const QString strId = objQuery.value( WebPageCol::id ).toString(); const QString strId = objQuery.value( WebPageCol::id ).toString();
const QString strAreaCode = objQuery.value( WebPageCol::area_code ).toString(); const QString strAreaCode = objQuery.value( WebPageCol::area_code ).toString();
LOGERROR("strId:%s,strAreaCode:%s",strId.toStdString().c_str(),strAreaCode.toStdString().c_str() );
auto itMap = mapAllPage.find( strAreaCode ); auto itMap = mapAllPage.find( strAreaCode );
if ( itMap == mapAllPage.end()) if ( itMap == mapAllPage.end())
@ -545,6 +556,7 @@ CSimpleCtrlPage::selectList( const std::shared_ptr<IncomingRequest> &spRequest )
} }
else if ( itMap.value()->pageId.get() != nullptr && !( itMap.value()->pageId->empty())) else if ( itMap.value()->pageId.get() != nullptr && !( itMap.value()->pageId->empty()))
{ {
auto &spOneData = itMap.value(); auto &spOneData = itMap.value();
QString strDelId, strDelPageName; QString strDelId, strDelPageName;
@ -573,6 +585,11 @@ CSimpleCtrlPage::selectList( const std::shared_ptr<IncomingRequest> &spRequest )
else else
{ {
fillOnePage( objQuery, itMap.value()); fillOnePage( objQuery, itMap.value());
if( nReqPageType == 1)
{
spRespData->push_back( itMap.value() );
}
} }
} }
} }
@ -610,6 +627,7 @@ CSimpleCtrlPage::selectList( const std::shared_ptr<IncomingRequest> &spRequest )
//< 查找游离页面 //< 查找游离页面
for ( auto const &spOneData:vecNonAreaPage ) for ( auto const &spOneData:vecNonAreaPage )
{ {
LOGERROR("check here");
if ( spOneData->parentCode.get() == nullptr || spOneData->parentCode->empty() if ( spOneData->parentCode.get() == nullptr || spOneData->parentCode->empty()
|| !mapAllPage.contains( spOneData->parentCode->c_str())) || !mapAllPage.contains( spOneData->parentCode->c_str()))
{ {

View File

@ -736,7 +736,19 @@ CSimpleCtrlPrimitive::updateById( const std::shared_ptr<IncomingRequest> &spRequ
spOneData->primitiveName = strCurPrimitiveName.toStdString(); spOneData->primitiveName = strCurPrimitiveName.toStdString();
if ( !strCurContentPath.isEmpty()) if ( !strCurContentPath.isEmpty())
spOneData->contentPath = CFileApi::getUrl( cn_strJsonFileGrp, strCurContentPath ).toStdString(); {
QString fileGrp;
if( nCurCategory == 6)
{
fileGrp = cn_str3DFileGrp;
}
else
{
fileGrp = cn_strJsonFileGrp;
}
spOneData->contentPath = CFileApi::getUrl( fileGrp, strCurContentPath ).toStdString();
}
if ( !strCurIconInfo.isEmpty()) if ( !strCurIconInfo.isEmpty())
//< 将iconPath内容还原详见常量定义注释 //< 将iconPath内容还原详见常量定义注释

View File

@ -184,6 +184,60 @@ QString CFileApi::uploadFile(const QString &strGroup, const QString &strOriginal
return strDestFileName; return strDestFileName;
} }
bool CFileApi::uploadModel(const QString &strParentCode, const QString &strGroup, const QString &strOriginalName, int nCategory, const QByteArray &baContent, iot_dbms::CDbApi *pDbApi )
{
// 其他参数检查交给uploadFile检查
iot_dbms::CDbApi * usefulDbApi;
std::shared_ptr<iot_dbms::CDbApi> ptrDbApi;
if( pDbApi != nullptr)
{
if( !pDbApi->isOpen())
{
return false;
}
usefulDbApi = pDbApi;
}
else
{
ptrDbApi = std::make_shared<iot_dbms::CDbApi>( DB_CONN_MODEL_WRITE );
usefulDbApi = ptrDbApi.get();
if( !usefulDbApi )
{
LOGERROR("cannot get useful DbApi");
return false;
}
if( !usefulDbApi->open() )
{
LOGERROR("cannot open database");
return false;
}
}
QString strFileName = CFileApi::uploadFile( strGroup, strOriginalName, baContent,
usefulDbApi );
if ( strFileName.isEmpty())
{
LOGERROR( "uploadModel():保存文件失败");
return false;
}
QByteArray baId = CFileApi::generateRandomId();
const qint64 nTimeNow = QDateTime::currentMSecsSinceEpoch();
bool ret = usefulDbApi->insert( "web_primitive",
{"id", "category", "primitive_name", "content_path", "icon_info",
"parent_code", "param", "create_time"},
{baId, nCategory, strOriginalName, strFileName,
//< 将iconPath内容缩短详见常量定义注释
"",
strParentCode, "", nTimeNow} );
return ret;
}
bool CFileApi::updateFileByPath( const QString &strPath, const QString *pOriginalName, bool CFileApi::updateFileByPath( const QString &strPath, const QString *pOriginalName,
const QByteArray *pContent, iot_dbms::CDbApi *pDbApi ) const QByteArray *pContent, iot_dbms::CDbApi *pDbApi )
{ {
@ -424,4 +478,47 @@ bool CFileApi::readFileByPath( const QString &strPath, QByteArray &baContent )
return true; return true;
} }
bool CFileApi::readFileByFileNameAndGroup(const QString &strFileName, const QString &strFileGroup, QByteArray &baContent)
{
// 从数据库查询组合文件组和文件的最大版本号如果查询到返回文件内容如果没有返回false
iot_dbms::CDbApi dbapi = iot_dbms::CDbApi(DB_CONN_MODEL_READ);
if(!dbapi.open())
{
LOGERROR("cannot open database");
}
QString sSql = QString("select max(revision),id,ext from web_files where name='%1' and file_group='%2' and status=0;")
.arg(strFileName).arg(strFileGroup);
QSqlQuery objQuery;
if ( !dbapi.execute(sSql,objQuery) )
{
LOGERROR("cannot query table web_files about max revision on name:%s, file_group:%s",strFileName.toStdString().c_str(), strFileGroup.toStdString().c_str());
return false;
}
if( !objQuery.next() )
{
return false;
}
else
{
if(!objQuery.isNull(0))
{
QString filePath = strFileGroup + "/" + objQuery.value(1).toString() + objQuery.value(2).toString();
if(!readFileByPath(filePath,baContent))
{
LOGERROR("readFileByFileNameAndGroup:cannot read file:%s",filePath.toStdString().c_str());
return false;
}
return true;
}
else
{
LOGERROR("sql result is null:%s",sSql.toStdString().c_str());
return false;
}
}
}
} //< namespace web_server_bi } //< namespace web_server_bi