[ref]同步
This commit is contained in:
parent
174de94f65
commit
7b819bc781
@ -378,10 +378,14 @@ void CAppMsgProcThread::handleOneMbMsg()
|
||||
if (iot_idl::AS_DO_NOTHING == objAlmInfoSrc.alm_style())
|
||||
{
|
||||
//< 不处理
|
||||
std::string strPrint;
|
||||
google::protobuf::TextFormat::PrintToString(objAlmInfoSrc, &strPrint);
|
||||
|
||||
LOGINFO("alm_style值为AS_DO_NOTHING,不做任何处理,消息内容:\n%s", strPrint.c_str());
|
||||
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;
|
||||
google::protobuf::TextFormat::PrintToString( objAlmInfoSrc, &strPrint );
|
||||
LOGINFO( "alm_style值为AS_DO_NOTHING,不做任何处理,消息内容:\n%s", strPrint.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -95,7 +95,7 @@ int CAccProcess::procAccChange(const SFesChangePiPkg &stChgAccPkg)
|
||||
stChangeAccData.strTableName = stChgAccPkg.stpidata(nLoop).strapptablename(); //表名
|
||||
stChangeAccData.strPointName = stChgAccPkg.stpidata(nLoop).strapptagname(); //点名
|
||||
stChangeAccData.strColumnName = stChgAccPkg.stpidata(nLoop).strappcolumnname(); //列名
|
||||
stChangeAccData.dValue = stChgAccPkg.stpidata(nLoop).nvalue();
|
||||
stChangeAccData.dValue = stChgAccPkg.stpidata(nLoop).dvalue();
|
||||
stChangeAccData.lTime = stChgAccPkg.stpidata(nLoop).ultime();
|
||||
|
||||
nTmpStatus = 0xffff & stChgAccPkg.stpidata(nLoop).ustatus();
|
||||
@ -177,12 +177,11 @@ int CAccProcess::procOneAccChange(SChangeAccData &stChangeAccData,SAccNewValueSt
|
||||
nRetCode, m_stRunAppInfo.nAppId, stChangeAccData.strTableName.c_str(), stChangeAccData.strPointName.c_str());
|
||||
return -1;
|
||||
}
|
||||
stAccOldValueStatus.oldvalue = stAccPoint.value;
|
||||
stAccOldValueStatus.oldvalue = stAccPoint.value;
|
||||
stAccOldValueStatus.oldstatus = stAccPoint.status;
|
||||
|
||||
m_stChangeAccInfo.dValue = stAccOldValueStatus.oldvalue;
|
||||
m_stChangeAccInfo.uStatus = stAccOldValueStatus.oldstatus;
|
||||
|
||||
stChangeAccData.nLocation = stAccPoint.location_id;
|
||||
stChangeAccData.nSubSystem = stAccPoint.sub_system;
|
||||
|
||||
@ -356,7 +355,7 @@ int CAccProcess::procAccUpdate(const SFesUpdatePiPkg &stUpAccPkg)
|
||||
stChangeAccData.strTableName = stUpAccPkg.stpidata(nLoop).strapptablename(); //表名
|
||||
stChangeAccData.strPointName = stUpAccPkg.stpidata(nLoop).strapptagname(); //点名
|
||||
stChangeAccData.strColumnName = stUpAccPkg.stpidata(nLoop).strappcolumnname(); //列名
|
||||
stChangeAccData.dValue = stUpAccPkg.stpidata(nLoop).nvalue();
|
||||
stChangeAccData.dValue = stUpAccPkg.stpidata(nLoop).dvalue();
|
||||
stChangeAccData.lTime = m_lCurTime;
|
||||
nTmpStatus = 0xffff & stUpAccPkg.stpidata(nLoop).ustatus();
|
||||
m_ptrDataProcApi->changeAnaStatusRawToRipe(stChangeAccData.uStatus, nTmpStatus);
|
||||
@ -471,7 +470,7 @@ int CAccProcess::writeAccRdb(const string& strPointName ,
|
||||
m_stChangeAccInfo.dValue = stAccOldValueStatus.oldvalue;
|
||||
m_stChangeAccInfo.uStatus = stAccNewValueStatus.newstatus;
|
||||
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);
|
||||
return 2;
|
||||
|
||||
@ -495,6 +494,7 @@ int CAccProcess::writeAccRdb(const string& strPointName ,
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief 处理电度系数
|
||||
@param stOneAiLimit:变化数据
|
||||
|
||||
@ -81,7 +81,6 @@ struct SAccMapToFes
|
||||
char description[128] ;
|
||||
};
|
||||
|
||||
|
||||
struct SAccOldValueStatus
|
||||
{
|
||||
double oldvalue;
|
||||
|
||||
@ -190,7 +190,7 @@ int CAccWorkThread::processOptMessage()
|
||||
{
|
||||
SOptSetDataPkg &objOptCalSetPkg = *it ;
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -551,7 +551,7 @@ int CAnaProcess:: writeAnaRtdb(const string &strPointName, SOldValueStatus &stOl
|
||||
m_stChangeAiInfo.dValue = stOldValueStatus.oldvalue;
|
||||
m_stChangeAiInfo.uStatus = stNewValueStatus.newstatus;
|
||||
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.bIfLimitChange);
|
||||
return 2;
|
||||
@ -756,6 +756,7 @@ int CAnaProcess::writeRdbAndSendMsg(const SChangeAiData &stOneAiLimit, int /*sty
|
||||
//<< 实时值写入数据库中同时发布到 HMI
|
||||
//============================================================================================
|
||||
strKeyTagName.resize(64);
|
||||
|
||||
nRetCode = m_ptrRdbTableMng->updateRecordTwoValueByKey(stOneAiLimit.strTableName,strKeyTagName.c_str(),\
|
||||
"status",m_stChangeAiInfo.uStatus, "value", m_stChangeAiInfo.dValue);
|
||||
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,\
|
||||
stOneAiLimit.strColumnName, m_stChangeAiInfo.dValue, m_stChangeAiInfo.uStatus);
|
||||
stOneAiLimit.strColumnName, static_cast<float>(m_stChangeAiInfo.dValue), m_stChangeAiInfo.uStatus);
|
||||
|
||||
//LOGDEBUG( "CAnaProcess::writeRdbAndSendMsg,not optlock" );
|
||||
|
||||
|
||||
@ -219,7 +219,7 @@ void CSrvDataPublish::addOneChangeLong(const int nLocationId,const int nSubSyste
|
||||
const string strTagName, const string strColumnName,
|
||||
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();
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#include "pub_utility_api/TimeUtil.h"
|
||||
#include "common/Common.h"
|
||||
#include "pub_utility_api/CommonConfigParse.h"
|
||||
#include <bitset>
|
||||
|
||||
using namespace std;
|
||||
using namespace iot_service;
|
||||
@ -23,9 +24,7 @@ CDigProcess::CDigProcess(iot_public::SRunAppInfo stRunAppInfo,
|
||||
|
||||
m_ptrDataProcApi = ptrDataProcApi;
|
||||
m_ptrDataPublish = ptrDataPublish;
|
||||
m_nChgAlarmCount = 0 ;
|
||||
m_nSoeAlarmCount = 0 ;
|
||||
m_nChangeCount = 0 ;
|
||||
|
||||
}
|
||||
|
||||
bool CDigProcess::initialize()
|
||||
@ -351,11 +350,6 @@ bool CDigProcess::isUpdatedByValidData(const int nLastStatus,const SUpdateDiInfo
|
||||
map <string, int>::iterator pos;
|
||||
string strTagName = stUpdateDiInfo.tag_name;
|
||||
|
||||
if( (nLastStatus & (1 << m_nMenuStateDiInvalid)) ) //上次无效=4(未初始化)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int64 lCurTimes = getUTCTimeSec();
|
||||
if((lCurTimes - m_nStartupTimes) <= m_nStartAlarmDelay) return false; //大于启动延时,如果全数据有变化,才会产生告警(用于FES 启动比较慢的情况)
|
||||
|
||||
@ -364,8 +358,8 @@ bool CDigProcess::isUpdatedByValidData(const int nLastStatus,const SUpdateDiInfo
|
||||
if (pos == m_mapUpdatePackRecord.end()) //没找到
|
||||
{
|
||||
//实时库点状态不是工况退出且全数据状态不是工况退出
|
||||
if ( !(nLastStatus & (1 << m_nMenuStateDiInvalid)) //上次状态没有异常
|
||||
&& !(stUpdateDiInfo.status & (1 << m_nMenuStateDiInvalid )) ) //当前状态没有异常
|
||||
if ( !(nLastStatus & (1 << m_nMenuStateDiGkOff)) //
|
||||
&& !(stUpdateDiInfo.status & (1 << m_nMenuStateDiGkOff)) )
|
||||
{
|
||||
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);
|
||||
}
|
||||
@ -495,21 +489,20 @@ int CDigProcess::processDiUpdate(const SFesUpdateDiPkg &stUpdateDiPkg)
|
||||
@return 无
|
||||
@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 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,
|
||||
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,
|
||||
STATUS_ORI_RECV); //del DiAbnormal flag
|
||||
STATUS_ORI_RECV); //add DiAbnormal flag
|
||||
}
|
||||
|
||||
//LOGDEBUG("setAbnormalStatus: 标签点[%s] 未复归=[%d],旧状态=[%d],新状态=[%d].",stDigPoint.tag_name,
|
||||
@ -691,6 +684,27 @@ void CDigProcess::getStatusByStatusx(const SDigPointAll&stDigPointAll,int &nNewS
|
||||
@retval
|
||||
*/
|
||||
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 nResultValue;
|
||||
@ -817,6 +831,26 @@ void CDigProcess::checkDiChgBuf()
|
||||
@retval
|
||||
*/
|
||||
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;
|
||||
map <string, SDiChange>::iterator pos;
|
||||
@ -972,8 +1006,7 @@ int CDigProcess::processDiChange(const SFesChangeDiPkg &stChangeDiPkg)
|
||||
|
||||
if(nChangeNum>0)
|
||||
{
|
||||
m_nChangeCount = m_nChangeCount + nChangeNum;
|
||||
LOGDEBUG("ProcessDiChange:收到变化数据报文,数目[%d],总计收到数目[%d],时间[%" PRId64 "].",nChangeNum,m_nChangeCount,(int64)stChangeDiPkg.stdidata(0).ultime());
|
||||
LOGDEBUG("ProcessDiChange:收到变化数据报文,数目[%d],时间[%" PRId64 "].",nChangeNum,(int64)stChangeDiPkg.stdidata(0).ultime());
|
||||
}
|
||||
|
||||
for (nLoop = 0; nLoop < nChangeNum; ++nLoop)
|
||||
@ -1158,6 +1191,8 @@ int CDigProcess::processOneDiChange(SChangeDiInfo &stChangeInfo)
|
||||
if (stDigPointAll.input_delay_time > 0) //数据量报警延时处理
|
||||
{
|
||||
addDigPartToBuff(m_mapDiChgBuf, strKeyIdTag, nDigPartIndex,stDigPointAll,stChangeInfo);
|
||||
//如果多个分量都已经采集到,并且是合法值就会在处理的同时直接从缓存删除掉
|
||||
testAndProcessDiWithMultiVal(stDigPointAll);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@ -1320,14 +1355,6 @@ void CDigProcess::addOneDigAlarm(int nAlarmType,const SDigPointAll &stDigPointAl
|
||||
if(nAlarmType == ALM_TYPE_DI_CHANGE) //遥信变位
|
||||
{
|
||||
nAlarmStatus = ALM_STAT_DI_CHANGE ;
|
||||
m_nChgAlarmCount = m_nChgAlarmCount+1;
|
||||
LOGDEBUG( "addOneDigAlarm::ChgAlarmCount=%d!",m_nChgAlarmCount);
|
||||
}
|
||||
if(nAlarmType == ALM_TYPE_SOE)
|
||||
{
|
||||
nAlarmStatus = ALM_STAT_SOE ;
|
||||
m_nSoeAlarmCount = m_nSoeAlarmCount+1;
|
||||
LOGDEBUG( "addOneDigAlarm::SoeAlarmCount=%d!",m_nSoeAlarmCount);
|
||||
}
|
||||
|
||||
//初始化报警 故障值文本。。。。
|
||||
@ -1416,6 +1443,7 @@ int CDigProcess::processOneSoeEvent(SChangeDiInfo &stChangeInfo,const string &st
|
||||
stDigPointAll.input_delay_time = 1 ;
|
||||
|
||||
addDigPartToBuff(m_mapDiSoeBuf,strKeyIdTag, nDigPartIndex,stDigPointAll,stChangeInfo); //SOE分量加入队列,进行延时判断
|
||||
testAndProcessDiSOEWithMultiVal(stDigPointAll);
|
||||
/*
|
||||
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].times = stChangeInfo.lTimes;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1563,8 +1592,10 @@ void CDigProcess::initValuexStatusx(const SDigPointAll &stDigPoint,int *valuex,i
|
||||
@return DI值
|
||||
@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 nRetValue = 0;
|
||||
|
||||
@ -1662,7 +1693,7 @@ void CDigProcess::getTimeString(char *cTimeBuf, const int nSec, short sMsec,
|
||||
pCurTime->tm_sec);
|
||||
strcat(cTimeBuf, " ");
|
||||
}
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -1678,8 +1709,7 @@ void CDigProcess::stripWhiteSpace(char *des_str, const char *source_str)
|
||||
{
|
||||
int nLoop;
|
||||
int start_pos, end_pos;
|
||||
int source_str_len;
|
||||
source_str_len = strlen(source_str);
|
||||
int source_str_len = static_cast<int>(strlen(source_str));
|
||||
|
||||
start_pos = 0;
|
||||
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) //采集点
|
||||
{
|
||||
LOGDEBUG("processOperate::操作错误,对采集点[%s]人工置数,请检查配置!",stDigPoint.tag_name);
|
||||
return 1;
|
||||
LOGWARN("processOperate::操作错误,对采集点[%s]人工置数,请检查配置!",stDigPoint.tag_name);
|
||||
continue;
|
||||
// return 1;
|
||||
}
|
||||
nRetCode = checkTagStatus(stDigPoint.tag_name,stDigPoint.status,
|
||||
unSetValue,stDigPoint.last_update_time, POINT_TYPE_DIG);//禁止刷新 保存旧的值
|
||||
if (nRetCode == false)
|
||||
{
|
||||
LOGDEBUG("processOperate::checkTagStatus() tag_name = %s, newValue = %d, status = %d NewStatus = %d ! ",
|
||||
LOGWARN("processOperate::checkTagStatus() tag_name = %s, newValue = %d, status = %d NewStatus = %d ! ",
|
||||
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;
|
||||
}
|
||||
|
||||
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]);//初始化分量值到valuex,statusx
|
||||
|
||||
//获得最新报警时间
|
||||
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]);//初始化分量值到valuex,statusx
|
||||
|
||||
//获得最新报警时间 报警分量信息初始化到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;
|
||||
}
|
||||
|
||||
@ -31,10 +31,6 @@ public:
|
||||
|
||||
private:
|
||||
//系统启动全数据告警延时
|
||||
int m_nChangeCount;//变化次数统计
|
||||
int m_nChgAlarmCount;//产生的告警统计
|
||||
int m_nSoeAlarmCount;//产生SOE数量
|
||||
|
||||
int64 m_nStartupTimes; //单位秒
|
||||
int m_nStartAlarmDelay;
|
||||
//数字量状态
|
||||
@ -94,7 +90,9 @@ private:
|
||||
bool bUpdatedByValidDataFlag, int64 lUpdateTimes) ;
|
||||
|
||||
void checkDiChgBuf();
|
||||
void checkDiChgBuf_bak();
|
||||
void checkDiSoeBuf();
|
||||
void checkDiSoeBuf_bak();
|
||||
|
||||
bool isUpdatedByValidData(const int nLastStatus,const SUpdateDiInfo &stUpdateDiInfo );
|
||||
int processValueChange(const SDigPointAll &stDigPointAll, SDigAlarmPara &stDigAlmPara,
|
||||
@ -113,6 +111,16 @@ private:
|
||||
const std::string& strStatusText,const int nDescFlag= ALARM_DESC_POINT_FLAG);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ using namespace iot_service;
|
||||
using namespace std;
|
||||
|
||||
CMsgRecvThread::CMsgRecvThread(iot_public::SRunAppInfo stRunAppInfo,CPacketQueuePtr ptrPacketQueue):
|
||||
CTimerThreadBase("CMsgRecvThread",1)
|
||||
CTimerThreadBase("CMsgRecvThread",0)
|
||||
{
|
||||
m_ptrPacketQueue = ptrPacketQueue ;
|
||||
m_stRunAppInfo = stRunAppInfo;
|
||||
@ -131,7 +131,7 @@ int CMsgRecvThread::parseOptPackage(const iot_net::CMbMessage &objRecvMsg)
|
||||
int nMessageType = objRecvMsg.getMsgType();
|
||||
|
||||
SOptSetDataPkg objOptSetDataPkg;
|
||||
bRetCode = objOptSetDataPkg.ParseFromArray(objRecvMsg.getDataPtr(),objRecvMsg.getDataSize());
|
||||
bRetCode = objOptSetDataPkg.ParseFromArray(objRecvMsg.getDataPtr(),static_cast<int>(objRecvMsg.getDataSize()));
|
||||
if(bRetCode == false)
|
||||
{
|
||||
LOGWARN("parseOptPackage, objOptSetDataPkg.ParseFromArray fail ");
|
||||
@ -175,7 +175,7 @@ int CMsgRecvThread::parseFesPackage(const iot_net::CMbMessage &objRecvMsg)
|
||||
{
|
||||
SFesChangeDiPkg objFesChanageDiPkg;
|
||||
//t1 = getUTCTimeMsec() ;
|
||||
bRetCode = objFesChanageDiPkg.ParseFromArray(objRecvMsg.getDataPtr(), objRecvMsg.getDataSize());
|
||||
bRetCode = objFesChanageDiPkg.ParseFromArray(objRecvMsg.getDataPtr(), static_cast<int>(objRecvMsg.getDataSize()));
|
||||
//t2 = getUTCTimeMsec() ;
|
||||
//LOGINFO("parseFesPackage:解析变化数字量 num=%d,用时=%d(ms)",objFesChanageDiPkg.stdidata_size(),t2-t1);
|
||||
if(!bRetCode)
|
||||
@ -190,7 +190,7 @@ int CMsgRecvThread::parseFesPackage(const iot_net::CMbMessage &objRecvMsg)
|
||||
{
|
||||
SFesUpdateDiPkg objFesUpdateDiPkg;
|
||||
//t1 = getUTCTimeMsec() ;
|
||||
bRetCode = objFesUpdateDiPkg.ParseFromArray(objRecvMsg.getDataPtr(), objRecvMsg.getDataSize());
|
||||
bRetCode = objFesUpdateDiPkg.ParseFromArray(objRecvMsg.getDataPtr(), static_cast<int>(objRecvMsg.getDataSize()));
|
||||
//t2 = getUTCTimeMsec() ;
|
||||
//LOGINFO("parseFesPackage:解析数字量全数据 num=%d,用时=%d(ms)",objFesUpdateDiPkg.stdidata_size(),t2-t1);
|
||||
if(!bRetCode)
|
||||
@ -204,7 +204,7 @@ int CMsgRecvThread::parseFesPackage(const iot_net::CMbMessage &objRecvMsg)
|
||||
case MT_FES_AI_CHANGE://AI Change Data
|
||||
{
|
||||
SFesChangeAiPkg objFesChanageAiPkg;
|
||||
bRetCode = objFesChanageAiPkg.ParseFromArray(objRecvMsg.getDataPtr(), objRecvMsg.getDataSize());
|
||||
bRetCode = objFesChanageAiPkg.ParseFromArray(objRecvMsg.getDataPtr(), static_cast<int>(objRecvMsg.getDataSize()));
|
||||
if(!bRetCode)
|
||||
{
|
||||
LOGWARN("parseFesPackage::objFesChanageAiPkg解析错误!");
|
||||
@ -216,7 +216,7 @@ int CMsgRecvThread::parseFesPackage(const iot_net::CMbMessage &objRecvMsg)
|
||||
case MT_FES_AI_UPDATE://AI UPDATE Data
|
||||
{
|
||||
SFesUpdateAiPkg objFesUpdateAiPkg;
|
||||
bRetCode = objFesUpdateAiPkg.ParseFromArray(objRecvMsg.getDataPtr(), objRecvMsg.getDataSize());
|
||||
bRetCode = objFesUpdateAiPkg.ParseFromArray(objRecvMsg.getDataPtr(), static_cast<int>(objRecvMsg.getDataSize()));
|
||||
if(!bRetCode)
|
||||
{
|
||||
LOGWARN("parseFesPackage::objFesUpdateAiPkg解析错误!");
|
||||
@ -228,7 +228,7 @@ int CMsgRecvThread::parseFesPackage(const iot_net::CMbMessage &objRecvMsg)
|
||||
case MT_FES_MI_CHANGE://MI Change Data
|
||||
{
|
||||
SFesChangeMiPkg objFesChanageMiPkg;
|
||||
bRetCode = objFesChanageMiPkg.ParseFromArray(objRecvMsg.getDataPtr(), objRecvMsg.getDataSize());
|
||||
bRetCode = objFesChanageMiPkg.ParseFromArray(objRecvMsg.getDataPtr(), static_cast<int>(objRecvMsg.getDataSize()));
|
||||
if(!bRetCode)
|
||||
{
|
||||
LOGWARN("parseFesPackage::objFesChanageMiPkg解析错误!");
|
||||
@ -240,7 +240,7 @@ int CMsgRecvThread::parseFesPackage(const iot_net::CMbMessage &objRecvMsg)
|
||||
case MT_FES_MI_UPDATE://MI UPDATE Data
|
||||
{
|
||||
SFesUpdateMiPkg objFesUpdateMiPkg;
|
||||
bRetCode = objFesUpdateMiPkg.ParseFromArray(objRecvMsg.getDataPtr(), objRecvMsg.getDataSize());
|
||||
bRetCode = objFesUpdateMiPkg.ParseFromArray(objRecvMsg.getDataPtr(), static_cast<int>(objRecvMsg.getDataSize()));
|
||||
if(!bRetCode)
|
||||
{
|
||||
LOGWARN("parseFesPackage::objFesUpdateMiPkg解析错误!");
|
||||
@ -252,7 +252,7 @@ int CMsgRecvThread::parseFesPackage(const iot_net::CMbMessage &objRecvMsg)
|
||||
case MT_FES_PI_CHANGE://PI Change Data
|
||||
{
|
||||
SFesChangePiPkg objFesChangePiPkg;
|
||||
bRetCode = objFesChangePiPkg.ParseFromArray(objRecvMsg.getDataPtr(), objRecvMsg.getDataSize());
|
||||
bRetCode = objFesChangePiPkg.ParseFromArray(objRecvMsg.getDataPtr(), static_cast<int>(objRecvMsg.getDataSize()));
|
||||
if(!bRetCode)
|
||||
{
|
||||
LOGWARN("parseFesPackage::objFesChangePiPkg解析错误!");
|
||||
@ -264,7 +264,7 @@ int CMsgRecvThread::parseFesPackage(const iot_net::CMbMessage &objRecvMsg)
|
||||
case MT_FES_PI_UPDATE://PI UPDATE Data
|
||||
{
|
||||
SFesUpdatePiPkg objFesUpdatePiPkg;
|
||||
bRetCode = objFesUpdatePiPkg.ParseFromArray(objRecvMsg.getDataPtr(), objRecvMsg.getDataSize());
|
||||
bRetCode = objFesUpdatePiPkg.ParseFromArray(objRecvMsg.getDataPtr(), static_cast<int>(objRecvMsg.getDataSize()));
|
||||
if(!bRetCode)
|
||||
{
|
||||
LOGWARN("parseFesPackage::objFesUpdatePiPkg解析错误!");
|
||||
@ -276,7 +276,7 @@ int CMsgRecvThread::parseFesPackage(const iot_net::CMbMessage &objRecvMsg)
|
||||
case MT_FES_SOE_EVENT: //SOE事件信息
|
||||
{
|
||||
SFesSoeEventPkg objFesSoeEventPkg ;
|
||||
bRetCode = objFesSoeEventPkg.ParseFromArray(objRecvMsg.getDataPtr(), objRecvMsg.getDataSize());
|
||||
bRetCode = objFesSoeEventPkg.ParseFromArray(objRecvMsg.getDataPtr(), static_cast<int>(objRecvMsg.getDataSize()));
|
||||
if(!bRetCode)
|
||||
{
|
||||
LOGWARN("parseFesPackage::objFesSoeEventPkg解析错误!");
|
||||
@ -285,6 +285,11 @@ int CMsgRecvThread::parseFesPackage(const iot_net::CMbMessage &objRecvMsg)
|
||||
m_ptrPacketQueue->addFesSoeEventPkg(objFesSoeEventPkg);
|
||||
break;
|
||||
}
|
||||
case MT_FES_CHAN_UPDATE: //通道状态信息,暂不处理
|
||||
case MT_FES_RTU_UPDATE: //RTU状态信息,暂不处理
|
||||
{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
LOGWARN("parseFesPackage::MsgType = %d 消息类型不支持!",nMessageType);
|
||||
|
||||
@ -301,7 +301,7 @@ void CPacketQueue::addOptCalSetPkg(const SOptSetDataPkg &objOptCalSetPkg)//计
|
||||
deqCalSetPkg.clear();
|
||||
deqCalSetPkg.push_back(objOptCalSetPkg);
|
||||
m_mapOptCalSetPkg.insert(pair<int,deque <SOptSetDataPkg>>(nPointType,deqCalSetPkg));
|
||||
LOGINFO("addOptCalSetPkg::计算点map中未找到数据类型为[%d]的队列,insert!",nPointType);
|
||||
LOGDEBUG("addOptCalSetPkg::计算点map中未找到数据类型为[%d]的队列,insert!",nPointType);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -321,7 +321,8 @@ bool CPacketQueue::getOptCalSetPkg(const int nPointType,std::deque <SOptSetDataP
|
||||
deqOptCalSetPkg = pos->second;
|
||||
pos->second.clear();
|
||||
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
|
||||
{
|
||||
|
||||
@ -11,12 +11,12 @@
|
||||
#include "OptDataMessage.pb.h"
|
||||
#include <deque>
|
||||
|
||||
#define MAX_CHG_ANA_QUEUE_NUM 50 //变化数据最大队列数,如果超出,丢弃最老数据(50*1000 一秒变化数据5万,windwo 处理5秒左右,linux2秒左右)
|
||||
#define MAX_CHG_DIG_QUEUE_NUM 100 //变化数据最大队列数,最多保证不丢失 15万YX点,10%变化率,30秒持续,不丢失事件(1.5*10000*30 万点的容量)
|
||||
#define MAX_MAN_SET_QUEUE_NUM 500 //人工置数最大队列数(考虑对一个间隔,最多200个测点)
|
||||
#define MAX_CAL_SET_QUEUE_NUM 200 //计算公式最大队列数(考虑公式不会超时1000,变化率20%)
|
||||
#define MAX_UPD_QUEUE_NUM 20 //全数据最大队列数,如果超出,丢弃最老数据 (每种类型25*10000 20万点的容量)
|
||||
#define MAX_EVT_QUEUE_NUM 500000//变化事件,如果超出,丢弃最老数据(考虑15万YX点,10%变化率,30秒持续,共45万点不丢失事件)
|
||||
#define MAX_CHG_ANA_QUEUE_NUM 500 //变化数据最大队列数,如果超出,丢弃最老数据(50*1000 一秒变化数据5万,windwo 处理5秒左右,linux2秒左右)
|
||||
#define MAX_CHG_DIG_QUEUE_NUM 1000 //变化数据最大队列数,最多保证不丢失 15万YX点,10%变化率,30秒持续,不丢失事件(1.5*10000*30 万点的容量)
|
||||
#define MAX_MAN_SET_QUEUE_NUM 1000 //人工置数最大队列数(考虑对一个间隔,最多200个测点)
|
||||
#define MAX_CAL_SET_QUEUE_NUM 10000 //计算公式最大队列数(考虑公式不会超时1000,变化率20%)
|
||||
#define MAX_UPD_QUEUE_NUM 50 //全数据最大队列数,如果超出,丢弃最老数据 (每种类型25*10000 20万点的容量)
|
||||
#define MAX_EVT_QUEUE_NUM 500000 //变化事件,如果超出,丢弃最老数据(考虑15万YX点,10%变化率,30秒持续,共45万点不丢失事件)
|
||||
|
||||
namespace iot_service
|
||||
{
|
||||
|
||||
@ -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;
|
||||
}
|
||||
//得到模拟量状态字信息
|
||||
|
||||
@ -8,12 +8,15 @@
|
||||
#include "DataProcessImpl.h"
|
||||
#include "alarm_server_api/AlarmCommonDef.h"
|
||||
#include "public/pub_utility_api/TimeUtil.h"
|
||||
#include "public/pub_utility_api/CharUtil.h"
|
||||
|
||||
using namespace iot_dbms;
|
||||
using namespace iot_service;
|
||||
using namespace iot_public;
|
||||
using namespace std;
|
||||
|
||||
const std::string CN_STATETEXT_CACHE_DELIMITER = "_#@#_"; //用于拼接数字量文本标识+分隔符+动作值
|
||||
|
||||
CDataProcessImpl::CDataProcessImpl(std::string strAppName)
|
||||
{
|
||||
m_IsInit = false;
|
||||
@ -117,10 +120,10 @@ int CDataProcessImpl::initialize()
|
||||
|
||||
//数字量文本报警方式
|
||||
//==========================================================================
|
||||
nRetCode = getMenuMacToValMap("数字量文本报警方式", menu_map);
|
||||
nRetCode = getMenuMacToValMap("数字量文本告警方式", menu_map);
|
||||
if (nRetCode < 0)
|
||||
{
|
||||
LOGERROR( "CDataProcessImpl::Init(), getMenuMacToValMap(数字量文本报警方式) error!");
|
||||
LOGERROR( "CDataProcessImpl::Init(), getMenuMacToValMap(数字量文本告警方式) error!");
|
||||
return -1;
|
||||
}
|
||||
MENU_EVENT_ONLY = menu_map["MENU_EVENT_ONLY"];
|
||||
@ -656,6 +659,7 @@ int CDataProcessImpl::readAllStateText(map<string, vector<SStateText> > &mapStat
|
||||
}
|
||||
|
||||
mapStateText.clear();
|
||||
m_setStateTextAndValue.clear();
|
||||
|
||||
std::vector<SStateTextSelect> vecStateTextSelect ;
|
||||
vecStateTextSelect.clear();
|
||||
@ -691,6 +695,9 @@ int CDataProcessImpl::readAllStateText(map<string, vector<SStateText> > &mapStat
|
||||
{
|
||||
pos->second.push_back(stOneStateText);
|
||||
}
|
||||
|
||||
//缓存数字量文本+值
|
||||
m_setStateTextAndValue.insert(strStateTextName + CN_STATETEXT_CACHE_DELIMITER + IntToString(stOneStateText.actual_value));
|
||||
}
|
||||
m_LastReadStateText = getUTCTimeSec();
|
||||
|
||||
@ -890,3 +897,13 @@ int CDataProcessImpl::getDigAlarmPara(const SDigAlarmInfo &stDigAlmInfo,SDigAla
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -83,6 +83,7 @@ private:
|
||||
std::string m_strAppName;
|
||||
iot_dbms::CRdbTableMngPtr m_ptrRdbTableMng;
|
||||
std::map<std::string, std::vector<SStateText> > m_mapStateText;
|
||||
std::set<std::string> m_setStateTextAndValue; //用来缓存所有的数字量文本信息,有数字量文本+值组成
|
||||
|
||||
public:
|
||||
/**
|
||||
@ -204,6 +205,15 @@ public:
|
||||
@retval
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
@ -552,7 +552,7 @@ void CDpcdaForDpImpl::handle_MT_DPCDA_APP2DP_CHG(iot_net::CMbMessage &objMbMsg)
|
||||
{
|
||||
//< 反序列化
|
||||
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(): 反序列化失败,忽略消息!");
|
||||
return;
|
||||
@ -697,7 +697,7 @@ void CDpcdaForDpImpl::handle_MT_DPCDA_APP2DP_ALL(iot_net::CMbMessage &objMbMsg)
|
||||
{
|
||||
//< 反序列化
|
||||
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(): 反序列化失败,忽略消息!");
|
||||
return;
|
||||
@ -913,7 +913,7 @@ bool CDpcdaForDpImpl::getAiDataFromRtdb(const std::string &strTagName, iot_idl::
|
||||
{
|
||||
if (m_pRtdb_AI->getColumnValueByIndex(nRcdIndex, "value", objValue))
|
||||
{
|
||||
pRtd->set_fvalue(objValue.toDouble());
|
||||
pRtd->set_fvalue(static_cast<float>(objValue.toDouble()));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -10,8 +10,19 @@
|
||||
#include "boost/typeof/typeof.hpp"
|
||||
#include "boost/lexical_cast.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"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#include "pub_logger_api/logger.h"
|
||||
#include "pub_utility_api/FileUtil.h"
|
||||
|
||||
|
||||
@ -3,7 +3,19 @@
|
||||
#include "pub_logger_api/logger.h"
|
||||
#include "CRelativeCallback.h"
|
||||
#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"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#include "boost/typeof/typeof.hpp"
|
||||
#include "pub_utility_api/FileUtil.h"
|
||||
#include "pub_utility_api/CommonConfigParse.h"
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
# ARM板上资源有限,不会与云平台混用,不编译
|
||||
message("Compile only in x86 environment")
|
||||
# requires(contains(QMAKE_HOST.arch, x86_64))
|
||||
requires(!contains(QMAKE_HOST.arch, aarch64))
|
||||
requires(!contains(QMAKE_HOST.arch, aarch64) : !linux-aarch64*)
|
||||
|
||||
TEMPLATE = app
|
||||
CONFIG += console c++11
|
||||
|
||||
@ -6,6 +6,9 @@
|
||||
#include "OperateServerClass.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"
|
||||
|
||||
using namespace std;
|
||||
@ -30,6 +33,12 @@ COperateServerClass::~COperateServerClass()
|
||||
|
||||
bool COperateServerClass::initialize()
|
||||
{
|
||||
//读取配置文件
|
||||
if(!readConfig())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//data_process_api 实例
|
||||
//========================================================================================
|
||||
m_ptrDataProcApi = getDataProcInstance(m_stRunAppInfo.strAppName);
|
||||
@ -313,7 +322,7 @@ int COperateServerClass::getUserAndUserGroup(const int nUserId,const int nUsergI
|
||||
|
||||
/**
|
||||
@brief 通过标签点获取标签点的状态和值
|
||||
@return 成功返回iotSuccess,失败返回相应错误码
|
||||
@return 成功返回iotSucces,失败返回相应错误码
|
||||
*/
|
||||
int COperateServerClass::getValueStatus(const std::string &strTagName, SOptValueStatus &stValueStatus,\
|
||||
int nDomainId ,int nAppNo)
|
||||
@ -1077,6 +1086,17 @@ int COperateServerClass::addOperateEvent(const SOptCtrlInfoAll &stOptCtrlInfo,
|
||||
stOptCtrlInfo.table_name,stOptCtrlInfo.tag_name);
|
||||
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)
|
||||
@ -1140,7 +1160,14 @@ int COperateServerClass::addOperateEvent(const SOptCtrlInfoAll &stOptCtrlInfo,
|
||||
addAlarmKeyword(stAlarmInfo,ALM_KEY_OPT_HOST,stOptCtrlInfo.host_name); //报警内容关键字-操作主机名
|
||||
addAlarmKeyword(stAlarmInfo,ALM_KEY_CTRL_VAL,strCtrlValue); //报警内容关键字-设备控制值
|
||||
addAlarmKeyword(stAlarmInfo,ALM_KEY_DEV_OPT_VAL,strCtrlValue); //报警内容关键字-设备操作值
|
||||
addAlarmKeyword(stAlarmInfo,ALM_KEY_DEV_OPT_NAME,strCtrlOptName); //报警内容关键字-设备操作名
|
||||
if(strCtrlOptName.empty())
|
||||
{
|
||||
addAlarmKeyword(stAlarmInfo,ALM_KEY_DEV_OPT_NAME,strCtrlValue); //报警内容关键字-设备操作名为空时填充控制值
|
||||
}
|
||||
else
|
||||
{
|
||||
addAlarmKeyword(stAlarmInfo,ALM_KEY_DEV_OPT_NAME,strCtrlOptName); //报警内容关键字-设备操作名
|
||||
}
|
||||
addAlarmKeyword(stAlarmInfo,ALM_KEY_RTN_RESULT,strCtrlResult); //报警内容关键字-设备操作结果
|
||||
getTimeStrBySeconds(stOptCtrlInfo.opt_time/1000, strNameString);
|
||||
addAlarmKeyword(stAlarmInfo,ALM_KEY_DEV_OPT_TIME,strNameString); //报警内容关键字-设备操作时间
|
||||
@ -1702,3 +1729,16 @@ void COperateServerClass::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;
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
|
||||
#include <map>
|
||||
#include "string.h"
|
||||
#include "boost/unordered_map.hpp"
|
||||
|
||||
namespace iot_service
|
||||
{
|
||||
@ -79,6 +80,8 @@ private:
|
||||
map<string, SOptInternHandover> m_mapHandoverInfo;
|
||||
map<string, SOptCtrlResv> m_mapCtrlResvInfo;
|
||||
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_nAiInhibitCtlStatus;
|
||||
int m_nAiAlmRstStatus;
|
||||
|
||||
int m_nAlarmCtrlPrecision; //告警描述中的精度
|
||||
public:
|
||||
//初始化相关函数
|
||||
//======================================================================================================
|
||||
@ -135,6 +138,8 @@ public:
|
||||
//======================================================================================================
|
||||
int optAutoCtrl(const string &strJson);//标志牌同步、外部权限移交
|
||||
int doOptAutoCtrl();
|
||||
int optAutoCtrlWithoutResp(const std::string &strJson);
|
||||
int doOptAutoCtrlWithoutResp();
|
||||
|
||||
//挂牌/点标签/屏蔽相关函数
|
||||
//======================================================================================================
|
||||
@ -154,6 +159,15 @@ public:
|
||||
//======================================================================================================
|
||||
void sendChange();//MANSET 发送变化数据信息给HMI
|
||||
void sendAlarm();//向报警服务器发送报警信息
|
||||
|
||||
|
||||
private:
|
||||
//点控/单控相关函数
|
||||
//======================================================================================================
|
||||
int optCtrlRequest(const SOptCtrlRequest &stCtrlRequest, string &strResult);//HMI遥控请求处理
|
||||
int optCtrlSelect(const SOptCtrlRequest &stOptCtrlSelect);//HMI遥控选择处理
|
||||
int optCtrlExecute(const SOptCtrlRequest &stOptDoCtrlExecute);//HMI遥控执行处理
|
||||
|
||||
private:
|
||||
//公共内部接口函数
|
||||
//======================================================================================================
|
||||
@ -236,6 +250,9 @@ private:
|
||||
const bool bIsCtrlResv,const bool bCheckInterLock,string &strRequest);
|
||||
int getAnaCtrlValue(SOptCtrlInfoAll &stOptCtrlInfoAll );
|
||||
|
||||
//< 获取禁止控制的设备列表
|
||||
int getInhibitCtrlDevList(std::set<std::string> &setDev);
|
||||
|
||||
//点标签接口函数
|
||||
//======================================================================================================
|
||||
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 getTokenAlmStatus(int &nAlarmStatus, string &strOptDesc);
|
||||
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);
|
||||
int getShieldAlmStatus(const int &ShieldnMode,int &nAlarmStatus);
|
||||
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);
|
||||
int getHandoverAlmStatus(const int nOptType,int &nAlarmStatus,string &strOptDesc,const int nType);
|
||||
int addOneInternHandoverReply(const SOptInternHandover &stOptHandoverInfo, const int nType);
|
||||
|
||||
bool readConfig(); //读数据处理配置
|
||||
};
|
||||
typedef boost::shared_ptr<COperateServerClass> COperateServerClassPtr;
|
||||
}
|
||||
|
||||
@ -460,10 +460,12 @@ struct SPointCtrlInfo
|
||||
int is_tagt_state;
|
||||
int ctrl_timeout;
|
||||
int resv_timeout;
|
||||
char rtu_tag[64];
|
||||
char offset_no[48];
|
||||
SOptCtrlActAll stCtrlActInfo;//控制动作组信息;
|
||||
SPointCtrlInfo()
|
||||
{
|
||||
memset(rtu_tag,0,sizeof(rtu_tag));
|
||||
memset(offset_no,0,48);
|
||||
}
|
||||
};
|
||||
@ -652,7 +654,7 @@ struct SOptCtrlInfoAll
|
||||
int64 opt_local_time ;
|
||||
double target_value ;
|
||||
double ctrl_tolerance ;
|
||||
int ctrl_act_type ;
|
||||
int ctrl_act_type ; //< DO和MO经过控制动作组转换的对FES的控制值,对AO没有用
|
||||
char ctrl_act_name[64] ;
|
||||
char rtu_tag[64] ; //new
|
||||
char offset_no[48] ;
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#include "pub_utility_api/TimeUtil.h"
|
||||
#include "rdb_api/FuncForNet.h"
|
||||
#include "MessageChannel.h"
|
||||
#include "service/common/RdbTableDefine.h"
|
||||
|
||||
using namespace iot_service;
|
||||
using namespace iot_idl;
|
||||
@ -120,8 +121,9 @@ int COptCommand::sendDigCtrlToFes(const SOptCtrlInfoAll &stOptCtrlInfoAll, const
|
||||
stDoCtrlPkg.set_norder(atoi(stOptCtrlInfoAll.offset_no));
|
||||
stDoCtrlPkg.set_naction(stOptCtrlInfoAll.ctrl_act_type); //动作值
|
||||
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! ");
|
||||
return -1;
|
||||
@ -195,7 +197,7 @@ int COptCommand::sendSetCtrlToFes(const SOptCtrlInfoAll &stOptCtrlInfoAll,
|
||||
return 0;
|
||||
}
|
||||
|
||||
//发送AO控制信息给FES
|
||||
//发送MO控制信息给FES
|
||||
int COptCommand::sendMixCtrlToFes(const SOptCtrlInfoAll &stOptCtrlInfoAll, const string &strSrcTag)
|
||||
{
|
||||
string strSendMessage ="" ;
|
||||
@ -207,8 +209,12 @@ int COptCommand::sendMixCtrlToFes(const SOptCtrlInfoAll &stOptCtrlInfoAll, const
|
||||
stMoCtrlPkg.set_strappcolumnname("value");
|
||||
stMoCtrlPkg.set_strrtuname(stOptCtrlInfoAll.rtu_tag);
|
||||
stMoCtrlPkg.set_norder(atoi(stOptCtrlInfoAll.offset_no));
|
||||
stMoCtrlPkg.set_nvalue(stOptCtrlInfoAll.ctrl_act_type);
|
||||
stMoCtrlPkg.set_nctrltype(stOptCtrlInfoAll.ctrl_act_type);
|
||||
/* 原来的逻辑:nctrltype才是控制动作组转换后的值,但是对应FES的逻辑,此字段应该对应选择、控制、取消这些类型
|
||||
* 本次修正为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.SerializeToString(&strSendMessage);
|
||||
@ -242,8 +248,8 @@ int COptCommand::sendAnaCtrlToFes(const SOptCtrlInfoAll &stOptCtrlInfoAll,const
|
||||
stAoCtrlPkg.set_strappcolumnname("value");
|
||||
stAoCtrlPkg.set_strrtuname(stOptCtrlInfoAll.rtu_tag);
|
||||
stAoCtrlPkg.set_norder(atoi(stOptCtrlInfoAll.offset_no));
|
||||
stAoCtrlPkg.set_fvalue(stOptCtrlInfoAll.target_value);
|
||||
stAoCtrlPkg.set_nctrltype(stOptCtrlInfoAll.ctrl_act_type);
|
||||
stAoCtrlPkg.set_fvalue(static_cast<float>(stOptCtrlInfoAll.target_value));
|
||||
stAoCtrlPkg.set_nctrltype(stOptCtrlInfoAll.msg_type); //控制类型:选择、执行、取消
|
||||
stAoCtrlPkg.set_niftagtstate(stOptCtrlInfoAll.is_tagt_state);
|
||||
|
||||
stAoCtrlPkg.SerializeToString(&strSendMessage);
|
||||
@ -280,6 +286,7 @@ int COptCommand::sendRequestToFes(
|
||||
stFesCtrlReqPkg.set_norder(atoi(stOptCtrlInfoAll.offset_no));
|
||||
stFesCtrlReqPkg.set_naction(stOptCtrlInfoAll.ctrl_act_type); //动作值
|
||||
stFesCtrlReqPkg.set_niftagtstate(stOptCtrlInfoAll.is_tagt_state);//是否等待目标状态
|
||||
stFesCtrlReqPkg.set_nctrltype(stOptCtrlInfoAll.msg_type); //控制类型:选择、执行、取消
|
||||
|
||||
stFesCtrlReqPkg.SerializeToString(&strSendMessage);
|
||||
int nRetCode = m_ptrNetMsgBus->sendToHost(stOptCtrlInfoAll.msg_type,
|
||||
@ -462,6 +469,51 @@ int COptCommand::sendVirCtrlToApp(const SOptCtrlInfoAll &stOptCtrlInfoAll, const
|
||||
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
|
||||
int COptCommand::sendAlarm()
|
||||
{
|
||||
|
||||
@ -56,6 +56,9 @@ public:
|
||||
int sendRequestToFes(const SOptCtrlInfoAll &stOptCtrlInfo, const string &strSrcTag); //数据请求
|
||||
int sendVirCtrlToApp(const SOptCtrlInfoAll &stOptCtrlInfoAll, const iot_idl::SVariable &varValue);
|
||||
|
||||
//< 批量发送控制命令到FES,暂时仅处理了AO
|
||||
int batchSendCtrlToFes(const std::vector<SOptCtrlInfoAll> &vecCtrlInfo, const string &strSrcTag);
|
||||
|
||||
/*发送给HMI控制面板的反馈*/
|
||||
void initUpOptPanel(SOptCtrlReply &stOptCtrlReply, const string strSourceTag,int nAppID,int nDomainID,\
|
||||
const string strHostName,const string strstrInstName,const string strKeyIdTag,\
|
||||
|
||||
@ -8,6 +8,8 @@
|
||||
#include "operate_server_api/JsonOptCommand.h"
|
||||
#include "pub_utility_api/I18N.h"
|
||||
#include <cfloat>
|
||||
#include "boost/unordered_map.hpp"
|
||||
#include <set>
|
||||
|
||||
using namespace iot_service;
|
||||
using namespace iot_idl;
|
||||
@ -460,6 +462,7 @@ int COperateServerClass::getPointCtrlInfo(const std::string &strTableName,const
|
||||
stCtrlInfo.ctrl_timeout = stDigCtrlAll.ctrl_timeout;
|
||||
stCtrlInfo.is_tagt_state = stDigCtrlAll.is_tagt_state;
|
||||
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_no2));
|
||||
@ -511,7 +514,9 @@ int COperateServerClass::getPointCtrlInfo(const std::string &strTableName,const
|
||||
stCtrlInfo.ctrl_timeout = stOptMixCtrlAll.ctrl_timeout;
|
||||
stCtrlInfo.is_tagt_state = stOptMixCtrlAll.is_tagt_state;
|
||||
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);
|
||||
|
||||
for (int i = 0; i <5; ++i)
|
||||
{
|
||||
vecCtrlOffsetNo.push_back((stOptMixCtrlAll.offset_no));
|
||||
@ -561,6 +566,7 @@ int COperateServerClass::getPointCtrlInfo(const std::string &strTableName,const
|
||||
//获得控制动作组参数
|
||||
//================================================================================================
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@ -727,23 +733,23 @@ int COperateServerClass::checkCtrlRequest(SOptCtrlInfoAll &stOptCtrlInfo, const
|
||||
//遥控请求
|
||||
int COperateServerClass::optCtrlRequest(const string &strJson, string &strResult)
|
||||
{
|
||||
int nRetCode = -1 ;
|
||||
|
||||
//JSON解码到结构体
|
||||
//=================================================================================================
|
||||
COptCtrlRequest objCtrlRequest;
|
||||
SOptCtrlRequest stCtrlRequest;
|
||||
SOptCtrlInfoAll stOptCtrlInfo;
|
||||
|
||||
nRetCode = objCtrlRequest.parse(strJson, stCtrlRequest);
|
||||
int nRetCode = COptCtrlRequest::parse(strJson, stCtrlRequest);
|
||||
if ( nRetCode <= 0)
|
||||
{
|
||||
LOGWARN("OptCtrlRequest, GetJsonHead() error!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return optCtrlRequest(stCtrlRequest,strResult);
|
||||
}
|
||||
|
||||
int COperateServerClass::optCtrlRequest(const SOptCtrlRequest &stCtrlRequest, string &strResult)
|
||||
{
|
||||
//初始化控制请求信息到结构体
|
||||
//=================================================================================================
|
||||
SOptCtrlInfoAll stOptCtrlInfo;
|
||||
stOptCtrlInfo.src_domain = stCtrlRequest.stHead.nSrcDomainID;
|
||||
stOptCtrlInfo.domain_id = stCtrlRequest.stHead.nDstDomainID;
|
||||
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;
|
||||
|
||||
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 ;
|
||||
bool bIsDeviceOccupy = stCtrlRequest.vecOptCtrlQueue[nLoop].bIsDeviceOccupy; //是否设备占用
|
||||
bool bCheckInterLock = stCtrlRequest.vecOptCtrlQueue[nLoop].bCheckInterLock; //是否检查闭锁
|
||||
@ -766,10 +770,11 @@ int COperateServerClass::optCtrlRequest(const string &strJson, string &strResult
|
||||
strKeyIdTag.c_str(), bIsDeviceOccupy, bCheckInterLock);
|
||||
|
||||
//遥控请求;判断闭锁等;设备占用
|
||||
//=================================================================================================
|
||||
nRetCode = checkCtrlRequest(stOptCtrlInfo, strKeyIdTag,dTargValue,
|
||||
//===========================================================
|
||||
string strRequest="" ;
|
||||
int nRetCode = checkCtrlRequest(stOptCtrlInfo, strKeyIdTag,dTargValue,
|
||||
bIsDeviceOccupy,bCheckInterLock,strRequest);
|
||||
if (nRetCode <0 )
|
||||
if (nRetCode < 0 )
|
||||
{
|
||||
strResult = I18N("遥控请求失败!!!");
|
||||
strResult += strRequest;
|
||||
@ -799,8 +804,7 @@ int COperateServerClass::optCtrlRequest(const string &strJson, string &strResult
|
||||
stOptCtrlReply.stHead.strResultStr = strResult ;
|
||||
stOptCtrlReply.stHead.nOptTime = stCtrlRequest.stHead.nOptTime ;
|
||||
|
||||
COptCtrlReply objOptCtrlReply;
|
||||
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
|
||||
string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
|
||||
if(strJson.size()<=1)
|
||||
{
|
||||
LOGWARN("COperateServerClass::OptCtrlRequest(),json 命令编码失败! \n");
|
||||
@ -812,6 +816,7 @@ int COperateServerClass::optCtrlRequest(const string &strJson, string &strResult
|
||||
return nRetCode;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1091,23 +1096,24 @@ int COperateServerClass::sendCancelCtrl (SOptCtrlInfoAll &stOptCtrlInfoAll,cons
|
||||
//遥控选择
|
||||
int COperateServerClass::optCtrlSelect(const string &strJson)
|
||||
{
|
||||
string strResult="";
|
||||
string strCtrlResult="";
|
||||
|
||||
COptCtrlRequest objOptCtrlSelect;
|
||||
SOptCtrlRequest stOptCtrlSelect;
|
||||
|
||||
int nRetCode = objOptCtrlSelect.parse(strJson,stOptCtrlSelect);
|
||||
int nRetCode = COptCtrlRequest::parse(strJson,stOptCtrlSelect);
|
||||
if ( nRetCode <= 0)
|
||||
{
|
||||
LOGWARN("OptCtrlSelect, GetJsonHead() error!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return optCtrlSelect(stOptCtrlSelect);
|
||||
}
|
||||
|
||||
int COperateServerClass::optCtrlSelect(const SOptCtrlRequest &stOptCtrlSelect)
|
||||
{
|
||||
string strResult="";
|
||||
string strCtrlResult="";
|
||||
string strSourceTagSend = stOptCtrlSelect.stHead.strSrcTag + "#" + m_strSrcTagLocal + ":OptCtrlSelect";
|
||||
|
||||
SOptCtrlInfoAll stOptCtrlInfoAll;
|
||||
|
||||
stOptCtrlInfoAll.src_domain = stOptCtrlSelect.stHead.nSrcDomainID;
|
||||
stOptCtrlInfoAll.domain_id = stOptCtrlSelect.stHead.nDstDomainID;
|
||||
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;
|
||||
|
||||
string strKeyIdTag;
|
||||
int nFlag = (0); //1:获取控制参数出错 2:设备控制保留 3:发送给FES失败或者控制信息表中插入记录失败 4:工程配置错误
|
||||
int nFlag = 0; //1:获取控制参数出错 2:设备控制保留 3:发送给FES失败或者控制信息表中插入记录失败 4:工程配置错误
|
||||
bool bIsCalculate = false ;//是否计算量
|
||||
SOptValueStatus stCurValueStatus, stNewValueStatus;
|
||||
|
||||
@ -1239,8 +1245,7 @@ int COperateServerClass::optCtrlSelect(const string &strJson)
|
||||
stOptCtrlReply.stHead.nOptTime = stOptCtrlInfoAll.opt_time ;
|
||||
stOptCtrlReply.stHead.strResultStr = strCtrlResult ;
|
||||
|
||||
COptCtrlReply objOptCtrlReply;
|
||||
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
|
||||
string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
|
||||
if(strJson.size()<=1)
|
||||
{
|
||||
LOGWARN("OptCtrlSelect(),json 命令编码失败! \n");
|
||||
@ -1384,8 +1389,7 @@ int COperateServerClass::optVirtCtrlExeReply(const iot_idl::SOptVirtCtrlReply st
|
||||
stOptCtrlReply.stHead.strResultStr = I18N("遥控执行成功");
|
||||
}
|
||||
|
||||
COptCtrlReply objOptCtrlReply;
|
||||
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
|
||||
string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
|
||||
if(strJson.size()<=1)
|
||||
{
|
||||
LOGWARN("optVirtCtrlExeReply(),json 命令编码失败! \n");
|
||||
@ -1538,8 +1542,7 @@ int COperateServerClass::optVirtCtrlSelReply(const iot_idl::SOptVirtCtrlReply st
|
||||
stOptCtrlReply.stHead.strResultStr = I18N("遥控执行成功");
|
||||
}
|
||||
|
||||
COptCtrlReply objOptCtrlReply;
|
||||
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
|
||||
string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
|
||||
if(strJson.size()<=1)
|
||||
{
|
||||
LOGWARN("optVirtCtrlSelReply(),json 命令编码失败! \n");
|
||||
@ -1697,8 +1700,7 @@ int COperateServerClass::optCtrlSelectReply(const SFesCtrlReplyPkg &stReplyPkg)
|
||||
|
||||
stOptCtrlReply.stHead.strResultStr = strResult;
|
||||
|
||||
COptCtrlReply objOptCtrlReply;
|
||||
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
|
||||
string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
|
||||
if(strJson.size()<=1)
|
||||
{
|
||||
LOGWARN("COperateServerClass::OptCtrlSelectReply(),json 命令编码失败! \n");
|
||||
@ -1729,10 +1731,8 @@ int COperateServerClass::optCtrlClose(const string &strJson)
|
||||
int nRetCode =-1;
|
||||
string strResult="";
|
||||
|
||||
COptCtrlRequest objOptCtrlClose;
|
||||
SOptCtrlRequest stOptCtrlClose;
|
||||
|
||||
nRetCode = objOptCtrlClose.parse(strJson,stOptCtrlClose);
|
||||
nRetCode = COptCtrlRequest::parse(strJson,stOptCtrlClose);
|
||||
if ( nRetCode <= 0)
|
||||
{
|
||||
LOGWARN("OptCtrlClose, GetJsonHead() error!");
|
||||
@ -1801,9 +1801,8 @@ int COperateServerClass::optCtrlCustom(const string &strJson)
|
||||
string strResultStr ="";
|
||||
string strResult="";
|
||||
|
||||
COptCustCtrlRequest objOptCustCtrlRequest;
|
||||
SOptCustCtrlRequest stOptCustCtrlRequest;
|
||||
nRetCode = objOptCustCtrlRequest.parse(strJson,stOptCustCtrlRequest);
|
||||
nRetCode = COptCustCtrlRequest::parse(strJson,stOptCustCtrlRequest);
|
||||
if ( nRetCode <= 0)
|
||||
{
|
||||
LOGWARN("OptCtrlCustom, GetJsonHead() error!");
|
||||
@ -1922,8 +1921,7 @@ int COperateServerClass::optCtrlCustom(const string &strJson)
|
||||
stOptCtrlReply.stHead.nIsSuccess = false ;
|
||||
stOptCtrlReply.stHead.strResultStr = strResultStr ;
|
||||
|
||||
COptCustCtrlReply objOptCtrlReply;
|
||||
string strReplyJson = objOptCtrlReply.generate(stOptCtrlReply) ;
|
||||
string strReplyJson = COptCustCtrlReply::generate(stOptCtrlReply) ;
|
||||
if(strJson.size()<=1)
|
||||
{
|
||||
LOGWARN("OptCtrlCustom(),json 命令编码失败! \n");
|
||||
@ -2034,8 +2032,7 @@ int COperateServerClass::optCtrlCustomReply(const SFesCustCmdReplyPkg &stFesCust
|
||||
|
||||
//发送 SendUpOptPanel to Hmi
|
||||
//================================================================================
|
||||
COptCustCtrlReply objOptCtrlReply;
|
||||
string strReplyJson = objOptCtrlReply.generate(stOptCustCtrlReply) ;
|
||||
string strReplyJson = COptCustCtrlReply::generate(stOptCustCtrlReply) ;
|
||||
if(strReplyJson.size()<=1)
|
||||
{
|
||||
LOGWARN("OptCtrlCustCmdReply(),json 命令编码失败! \n");
|
||||
@ -2147,20 +2144,22 @@ int COperateServerClass::addSettingAlarm(const string &strKeyIdTag,const string
|
||||
//DO遥控执行
|
||||
int COperateServerClass::optCtrlExecute(const string &strJson)
|
||||
{
|
||||
int nRetCode =-1;
|
||||
string strResult="";
|
||||
string strCtrlResult ="";
|
||||
|
||||
COptCtrlRequest objOptDoCtrlExecute;
|
||||
SOptCtrlRequest stOptDoCtrlExecute;
|
||||
|
||||
nRetCode = objOptDoCtrlExecute.parse(strJson,stOptDoCtrlExecute);
|
||||
int nRetCode = COptCtrlRequest::parse(strJson,stOptDoCtrlExecute);
|
||||
if ( nRetCode <= 0)
|
||||
{
|
||||
LOGWARN("OptCtrlExecute, GetJsonHead() error!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return optCtrlExecute(stOptDoCtrlExecute);
|
||||
}
|
||||
|
||||
int COperateServerClass::optCtrlExecute(const SOptCtrlRequest &stOptDoCtrlExecute)
|
||||
{
|
||||
string strResult="";
|
||||
string strCtrlResult ="";
|
||||
|
||||
string strSrcTag = stOptDoCtrlExecute.stHead.strSrcTag;
|
||||
string strSourceTagSend = strSrcTag + "#" + m_strSrcTagLocal + ":OptCtrlExecute";
|
||||
|
||||
@ -2319,8 +2318,7 @@ int COperateServerClass::optCtrlExecute(const string &strJson)
|
||||
stOptCtrlReply.stHead.strResultStr = I18N("遥控执行成功") ;
|
||||
}
|
||||
|
||||
COptCtrlReply objOptCtrlReply;
|
||||
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
|
||||
string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
|
||||
if(strJson.size()<=1)
|
||||
{
|
||||
LOGWARN("COperateServerClass::OptCtrlExecute(),json 命令编码失败! \n");
|
||||
@ -2527,8 +2525,7 @@ int COperateServerClass::optCtrlExecuteReply(const SFesCtrlReplyPkg &stReplyPkg)
|
||||
stOptCtrlReply.stHead.strResultStr = I18N("遥控执行成功");
|
||||
}
|
||||
|
||||
COptCtrlReply objOptCtrlReply;
|
||||
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
|
||||
string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
|
||||
if(strJson.size()<=1)
|
||||
{
|
||||
LOGWARN("COperateServerClass::OptCtrlExecuteReply(),json 命令编码失败! \n");
|
||||
@ -2715,8 +2712,7 @@ int COperateServerClass::optCtrlCheckTargetVal()
|
||||
m_ptrOptComand->initUpOptPanel(stOptCtrlReply,strSourceTagSend,m_stRunAppInfo.nAppId,stOptCtrlInfoAll.domain_id,\
|
||||
stOptCtrlInfoAll.host_name,stOptCtrlInfoAll.instance_name,strKeyIdTag,strResult,true,stOptCtrlInfoAll.opt_time);
|
||||
|
||||
COptCtrlReply objOptCtrlReply;
|
||||
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
|
||||
string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
|
||||
if(strJson.size()<=1)
|
||||
{
|
||||
LOGWARN("COperateServerClass::OptCtrlCheckTargetVal(),json 命令编码失败! \n");
|
||||
@ -2743,10 +2739,9 @@ int COperateServerClass::optCtrlCancel(const string &strJson)
|
||||
{
|
||||
int nFlag = (0);
|
||||
bool bIsCalculate = false;
|
||||
COptCtrlRequest objOptCtrlCancel;
|
||||
SOptCtrlRequest stOptCtrlCancel;
|
||||
|
||||
int nRetCode = objOptCtrlCancel.parse(strJson,stOptCtrlCancel);
|
||||
SOptCtrlRequest stOptCtrlCancel;
|
||||
int nRetCode = COptCtrlRequest::parse(strJson,stOptCtrlCancel);
|
||||
if ( nRetCode <= 0)
|
||||
{
|
||||
LOGWARN("OptCtrlCancel, GetJsonHead() error!");
|
||||
@ -2844,8 +2839,7 @@ int COperateServerClass::optCtrlCancel(const string &strJson)
|
||||
stOptCtrlCancel.stHead.strHostName, stOptCtrlCancel.stHead.strInstName,strKeyIdTag,
|
||||
strCtrlResult,false,stOptCtrlInfoAll.opt_time);
|
||||
|
||||
COptCtrlReply objOptCtrlReply;
|
||||
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
|
||||
string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
|
||||
if(strJson.size()<=1)
|
||||
{
|
||||
LOGWARN("OptCtrlCancel(),json 命令编码失败! \n");
|
||||
@ -2957,8 +2951,7 @@ int COperateServerClass::optCtrlCancelReply(const SFesCtrlReplyPkg &stReplyPkg)
|
||||
stOptCtrlReply.stHead.strResultStr=I18N("遥控取消成功");
|
||||
}
|
||||
|
||||
COptCtrlReply objOptCtrlReply;
|
||||
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
|
||||
string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
|
||||
if(strJson.size()<=1)
|
||||
{
|
||||
LOGWARN("COperateServerClass::OptCtrlCancelReply(),json 命令编码失败! \n");
|
||||
@ -3129,8 +3122,7 @@ int COperateServerClass::checkTimeOutCtrlRec()
|
||||
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);
|
||||
|
||||
COptCtrlReply objOptCtrlReply;
|
||||
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
|
||||
string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
|
||||
if(strJson.size()<=1)
|
||||
{
|
||||
LOGWARN("COperateServerClass::CheckTimeOutCtrlRec(),json 命令编码失败! \n");
|
||||
@ -3178,7 +3170,6 @@ int COperateServerClass::doOptAutoCtrl()
|
||||
return 1;
|
||||
}
|
||||
|
||||
string strJson;
|
||||
string strResult;
|
||||
|
||||
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.source_tag.c_str());
|
||||
}
|
||||
COptCtrlRequest objOptAutoCtrl;
|
||||
|
||||
SOptCtrlRequest stOptAutoCtrl;
|
||||
|
||||
stOptAutoCtrl.stHead.strSrcTag = m_itLinkageMapPos->second.source_tag; //源标签(即发送端进程名)
|
||||
@ -3240,10 +3231,9 @@ int COperateServerClass::doOptAutoCtrl()
|
||||
stOptCtrlQueue.bCheckInterLock = m_itLinkageMapPos->second.is_interlock; //闭锁检查
|
||||
|
||||
stOptAutoCtrl.vecOptCtrlQueue.push_back(stOptCtrlQueue);
|
||||
strJson = objOptAutoCtrl.generate(stOptAutoCtrl) ;
|
||||
|
||||
m_itLinkageMapPos->second.opt_step = LINKAGE_CTRL_REQUEST;
|
||||
nRetCode = optCtrlRequest(strJson, strResult); //自动控制遥控请求命令
|
||||
nRetCode = optCtrlRequest(stOptAutoCtrl, strResult); //自动控制遥控请求命令
|
||||
if (nRetCode < 0)
|
||||
{
|
||||
bIsSendFeedback = true;
|
||||
@ -3301,9 +3291,8 @@ int COperateServerClass::doOptAutoCtrl()
|
||||
stOptCtrlQueue.bIsDeviceOccupy = false ;
|
||||
|
||||
stOptAutoCtrl.vecOptCtrlQueue.push_back(stOptCtrlQueue);
|
||||
strJson = objOptAutoCtrl.generate(stOptAutoCtrl) ;
|
||||
|
||||
nRetCode = optCtrlSelect(strJson);
|
||||
nRetCode = optCtrlSelect(stOptAutoCtrl);
|
||||
if (nRetCode < 0)
|
||||
{
|
||||
bIsSendFeedback = true;
|
||||
@ -3355,9 +3344,8 @@ int COperateServerClass::doOptAutoCtrl()
|
||||
stOptCtrlQueue.bIsDeviceOccupy = false ;
|
||||
|
||||
stOptAutoCtrl.vecOptCtrlQueue.push_back(stOptCtrlQueue);
|
||||
strJson = objOptAutoCtrl.generate(stOptAutoCtrl) ;
|
||||
|
||||
nRetCode = optCtrlExecute(strJson);
|
||||
nRetCode = optCtrlExecute(stOptAutoCtrl);
|
||||
if (nRetCode == -1)
|
||||
{
|
||||
bIsSendFeedback = true;
|
||||
@ -3513,8 +3501,7 @@ int COperateServerClass::doOptAutoCtrl()
|
||||
stOptCtrlReply.stHead.strResultStr+= m_itLinkageMapPos->second.ctrl_result; //FES控制返回结果
|
||||
stOptCtrlReply.stHead.nOptTime = m_itLinkageMapPos->second.opt_time ;
|
||||
|
||||
COptCtrlReply objOptCtrlReply;
|
||||
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
|
||||
string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
|
||||
if(strJson.size()<=1)
|
||||
{
|
||||
LOGWARN("COperateServerClass::OptCtrlSelectReply(),json 命令编码失败! \n");
|
||||
@ -3568,16 +3555,134 @@ int COperateServerClass::doOptAutoCtrl()
|
||||
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、尽快下发,一般不会做太多的校验和判断,所以现阶段仅做简单的是否禁止控制的判断
|
||||
* 4、暂时仅处理AO控制
|
||||
**********************************************/
|
||||
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 nRetCode =-1;
|
||||
|
||||
COptCtrlRequest objOptAutoCtrl;
|
||||
SOptCtrlRequest stOptAutoCtrl;
|
||||
|
||||
nRetCode = objOptAutoCtrl.parse(strJson,stOptAutoCtrl);
|
||||
nRetCode = COptCtrlRequest::parse(strJson,stOptAutoCtrl);
|
||||
if ( nRetCode <= 0)
|
||||
{
|
||||
LOGWARN("OptAutoCtrl, GetJsonHead() error!");
|
||||
@ -3615,15 +3720,21 @@ int COperateServerClass::optAutoCtrl(const string &strJson)
|
||||
|
||||
//得到是否需要遥控选择
|
||||
//============================================================================================
|
||||
nRetCode = getCtrlTableName(strTableName,strCtrlTableName) ;
|
||||
strKeyTagName.resize(64);
|
||||
nRetCode = m_ptrRdbTableMng->getRecordOneColumnByKey(strCtrlTableName, strKeyTagName.c_str(), "ctrl_type",nCtrlType);
|
||||
if (nRetCode == false)
|
||||
if(nPointType == POINT_TYPE_ANA)
|
||||
{
|
||||
LOGWARN("OptAutoCtrl, nRetCode = %d, strTableName = %s, strTagName = %s, getRecordOneColumnByKey(ctrl_type) error! ",
|
||||
nRetCode, strTableName.c_str(), strTagName.c_str() );
|
||||
nCtrlType = CTRL_TYPE_DIRECTEXE; //模拟量直接控制
|
||||
}
|
||||
else
|
||||
{
|
||||
nRetCode = getCtrlTableName(strTableName,strCtrlTableName) ;
|
||||
strKeyTagName.resize(64);
|
||||
nRetCode = m_ptrRdbTableMng->getRecordOneColumnByKey(strCtrlTableName, strKeyTagName.c_str(), "ctrl_type",nCtrlType);
|
||||
if (nRetCode == false)
|
||||
{
|
||||
LOGWARN("OptAutoCtrl, nRetCode = %d, strTableName = %s, strTagName = %s, getRecordOneColumnByKey(ctrl_type) error! ",
|
||||
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;
|
||||
}
|
||||
|
||||
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()
|
||||
|
||||
@ -26,12 +26,11 @@ using namespace std;
|
||||
int COperateServerClass::optInternHandover(const string &strJson)
|
||||
{
|
||||
int nRetCode = 0;
|
||||
CHandoverRequest objHandoverRequest;
|
||||
SHandoverRequest stHandoverRequest;
|
||||
|
||||
LOGINFO("OptInternHandover, json =%s !",strJson.c_str());
|
||||
|
||||
int bRetCode = objHandoverRequest.parse(strJson,stHandoverRequest) ;
|
||||
int bRetCode = CHandoverRequest::parse(strJson,stHandoverRequest) ;
|
||||
if ( bRetCode == false)
|
||||
{
|
||||
LOGWARN("OptInternHandover, objHandoverRequest.parse() error!");
|
||||
@ -605,8 +604,7 @@ int COperateServerClass::addOneInternHandoverReply(const SOptInternHandover &st
|
||||
stHandoverReply.stHead.nIsSuccess = bIsSucess ;
|
||||
stHandoverReply.stHead.strResultStr = strResultStr ;
|
||||
|
||||
CHandoverReply objHandoverReply ;
|
||||
string strJson = objHandoverReply.generate(stHandoverReply) ;
|
||||
string strJson = CHandoverReply::generate(stHandoverReply) ;
|
||||
if(strJson.size()<=1)
|
||||
{
|
||||
LOGWARN("COperateServerClass::AddOneInternHandoverReply(),json 命令编码失败! \n");
|
||||
|
||||
@ -97,7 +97,7 @@ void COptMainThread::processAppMessage(const iot_net::CMbMessage &recvMsg)
|
||||
case MT_APP2OPT_VIRT_CTRL_MIX_REPLY:
|
||||
{
|
||||
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 ",
|
||||
objAppVirtCtrlReply.str_tag_name().c_str(),objAppVirtCtrlReply.n_ctrl_result(),objAppVirtCtrlReply.str_err().c_str());
|
||||
m_ptrOperateServer->optVirtCtrlExeReply(objAppVirtCtrlReply);
|
||||
@ -130,7 +130,7 @@ void COptMainThread::processFesMessage(const iot_net::CMbMessage &recvMsg)
|
||||
case MT_FES_DO_SELECT_REPLY: // 遥控选择返校
|
||||
{
|
||||
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 ",
|
||||
objFesCtrlReplyPkg.strapptagname().c_str(),objFesCtrlReplyPkg.nresult(),objFesCtrlReplyPkg.strpara().c_str());
|
||||
m_ptrOperateServer->optCtrlSelectReply(objFesCtrlReplyPkg);
|
||||
@ -141,7 +141,7 @@ void COptMainThread::processFesMessage(const iot_net::CMbMessage &recvMsg)
|
||||
case MT_FES_MO_EXECUTE_REPLY:
|
||||
{
|
||||
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 ",
|
||||
objFesCtrlReplyPkg.strapptagname().c_str(),objFesCtrlReplyPkg.nresult(),objFesCtrlReplyPkg.strpara().c_str());
|
||||
m_ptrOperateServer->optCtrlExecuteReply(objFesCtrlReplyPkg);
|
||||
@ -150,7 +150,7 @@ void COptMainThread::processFesMessage(const iot_net::CMbMessage &recvMsg)
|
||||
case MT_FES_DO_CANCEL_REPLY: //遥控撤销返校
|
||||
{
|
||||
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 ",
|
||||
objFesCtrlReplyPkg.strapptagname().c_str(),objFesCtrlReplyPkg.nresult(),objFesCtrlReplyPkg.strpara().c_str());
|
||||
m_ptrOperateServer->optCtrlCancelReply(objFesCtrlReplyPkg);
|
||||
@ -159,7 +159,7 @@ void COptMainThread::processFesMessage(const iot_net::CMbMessage &recvMsg)
|
||||
case MT_FES_DEFINE_CMD_REPLAY://自定义控制命令
|
||||
{
|
||||
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 ",
|
||||
objFesCustCmdReplyPkg.strapptagname().c_str(),objFesCustCmdReplyPkg.nresult(),objFesCustCmdReplyPkg.strretresult().c_str());
|
||||
m_ptrOperateServer->optCtrlCustomReply(objFesCustCmdReplyPkg);
|
||||
@ -168,13 +168,13 @@ void COptMainThread::processFesMessage(const iot_net::CMbMessage &recvMsg)
|
||||
case MT_FES_VIRTUAL_CTRL: //前置发过来的虚拟控制
|
||||
{
|
||||
SFesChangeVirtualDataPkg objFesVirCtrlPkg;
|
||||
objFesVirCtrlPkg.ParseFromArray(recvMsg.getDataPtr(),recvMsg.getDataSize());
|
||||
objFesVirCtrlPkg.ParseFromArray(recvMsg.getDataPtr(),static_cast<int>(recvMsg.getDataSize()));
|
||||
m_ptrOperateServer->optFesCtrlExecute(objFesVirCtrlPkg);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
LOGINFO("processFesMessage, MsgType = %d, operate_server not support this message",nMessageType);
|
||||
LOGTRACE("processFesMessage, MsgType = %d, operate_server not support this message",nMessageType);
|
||||
break;
|
||||
}
|
||||
}// end switch
|
||||
@ -237,6 +237,11 @@ void COptMainThread::processHmiMessage(const iot_net::CMbMessage &recvMsg)
|
||||
m_ptrOperateServer->optAutoCtrl(strMessage);
|
||||
break;
|
||||
}
|
||||
case MT_OPT_AUTO_CTRL_WITHOUT_RESP: //无需等待反馈,主要用于功率控制的场景
|
||||
{
|
||||
m_ptrOperateServer->optAutoCtrlWithoutResp(strMessage);
|
||||
break;
|
||||
}
|
||||
case MT_OPT_PINHIBIT_REF: //静止刷新
|
||||
case MT_OPT_PINHIBIT_ALARM://静止报警
|
||||
case MT_OPT_PINHIBIT_CTRL: //静止控制
|
||||
@ -354,6 +359,7 @@ void COptMainThread::execute()
|
||||
//===============================================================================================
|
||||
//if (lCurTime - m_lLastAutoCtrlTime >= 10)
|
||||
{
|
||||
m_ptrOperateServer->doOptAutoCtrlWithoutResp(); //< 处理无需等待的缓存的控制命令
|
||||
m_ptrOperateServer->doOptAutoCtrl(); //读自动控制Map 并执行
|
||||
m_lLastAutoCtrlTime = lCurTime;
|
||||
}
|
||||
|
||||
@ -157,9 +157,8 @@ int COperateServerClass::optShieldSet(const string &strJson)
|
||||
{
|
||||
int nIsSet = 0 ;
|
||||
SOptShieldSet stOptShieldSet;
|
||||
COptShieldSet objOptShieldSet;
|
||||
|
||||
bool bRetCode = objOptShieldSet.parse(strJson,stOptShieldSet) ;
|
||||
bool bRetCode = COptShieldSet::parse(strJson,stOptShieldSet) ;
|
||||
if ( bRetCode == false)
|
||||
{
|
||||
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, \
|
||||
stHead.strHostName, stHead.strInstName, iterObj->key_id_tag, "屏蔽操作成功", true);
|
||||
|
||||
COptCtrlReply objOptCtrlReply;
|
||||
string strJson = objOptCtrlReply.generate(stOptCtrlReply);
|
||||
string strJson = COptCtrlReply::generate(stOptCtrlReply);
|
||||
if (strJson.size() <= 1)
|
||||
{
|
||||
LOGWARN("COperateServerClass::OptToken(),json 命令编码失败! \n");
|
||||
@ -821,3 +819,10 @@ int COperateServerClass::initShieldStatus()
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int COperateServerClass::getShieldDevWithInhibitCtrl(std::set<string> &setDev)
|
||||
{
|
||||
boost::ignore_unused_variable_warning(setDev);
|
||||
//LOGINFO("暂未实现获取禁止控制的设备屏蔽列表");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -59,9 +59,8 @@ bool COperateServerClass::checkIsOptTag(int &nIsSet,const string &strKeyIdTag,co
|
||||
int COperateServerClass::optPointTag(const string &strJson)
|
||||
{
|
||||
SOptTagSet stOptTagSet;
|
||||
COptTagSet objOptTagSet;
|
||||
|
||||
int bRetCode = objOptTagSet.parse(strJson,stOptTagSet) ;
|
||||
int bRetCode = COptTagSet::parse(strJson,stOptTagSet) ;
|
||||
if ( bRetCode == false)
|
||||
{
|
||||
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,\
|
||||
stOptTagSet.stHead.strHostName,stOptTagSet.stHead.strInstName ,stOptCtrlInfo.key_id_tag,I18N("点标签操作成功"),true);
|
||||
|
||||
COptCtrlReply objOptCtrlReply;
|
||||
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
|
||||
string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
|
||||
if(strJson.size()<=1)
|
||||
{
|
||||
LOGWARN("COperateServerClass::OptToken(),json 命令编码失败! \n");
|
||||
@ -413,7 +411,6 @@ int COperateServerClass::updateTagInfo(const SOptCtrlInfoAll &stOptTagInfo,const
|
||||
|
||||
// update rdb
|
||||
// ----------------------------------------------------------------------------------
|
||||
/*
|
||||
vector<iot_dbms::CONDINFO> vecCondInfo;
|
||||
CRdbPublic::addCondInfo(vecCondInfo,"tag_type", nTagType);
|
||||
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!",
|
||||
RT_OPT_TAG_INFO,nTagType,stOptTagInfo.key_id_tag);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -446,7 +443,6 @@ int COperateServerClass::updateTagInfo(const SOptCtrlInfoAll &stOptTagInfo,const
|
||||
|
||||
// update rdb
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
SOptTagInfoAll stTagInfo ;
|
||||
strcpy(stTagInfo.key_id_tag,stOptTagInfo.key_id_tag) ;
|
||||
stTagInfo.tag_type =nTagType;
|
||||
@ -538,10 +534,9 @@ int COperateServerClass::optAiLimitSet(const string &strJson)
|
||||
|
||||
//JSON解码到结构体
|
||||
//===========================================================================================================
|
||||
CAiLimitSet objAiLimitSet;
|
||||
SAiLimitSet stAiLimitSet;
|
||||
|
||||
bRetCode = objAiLimitSet.parse(strJson, stAiLimitSet);
|
||||
bRetCode = CAiLimitSet::parse(strJson, stAiLimitSet);
|
||||
if ( bRetCode == false)
|
||||
{
|
||||
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,\
|
||||
stAiLimitSet.stHead.strHostName,stAiLimitSet.stHead.strInstName,strkeyIdTag,strResult,nIsSucess);
|
||||
|
||||
COptCtrlReply objOptCtrlReply;
|
||||
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
|
||||
string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
|
||||
if(strJson.size()<=1)
|
||||
{
|
||||
LOGWARN("COperateServerClass::OptAiLimitSet(),json 命令编码失败! \n");
|
||||
|
||||
@ -322,10 +322,9 @@ int COperateServerClass::optToken(const string &strJson, const bool bIsSync /*=
|
||||
int nRetCode =0 ;
|
||||
int nIsSet = OPT_TOKEN_SET; //默认挂牌操作
|
||||
|
||||
CTokenSet objOptTkokenSet;
|
||||
STokenSet stOptTokenSet;
|
||||
|
||||
int bRetCode = objOptTkokenSet.parse(strJson,stOptTokenSet) ;
|
||||
int bRetCode = CTokenSet::parse(strJson,stOptTokenSet) ;
|
||||
if ( bRetCode == false)
|
||||
{
|
||||
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,\
|
||||
stOptTokenSet.stHead.strHostName,stOptTokenSet.stHead.strInstName ,stOptTokenInfo.key_id_tag,strResult,true);
|
||||
|
||||
COptCtrlReply objOptCtrlReply;
|
||||
string strJson = objOptCtrlReply.generate(stOptCtrlReply) ;
|
||||
string strJson = COptCtrlReply::generate(stOptCtrlReply) ;
|
||||
if(strJson.size()<=1)
|
||||
{
|
||||
LOGWARN("COperateServerClass::OptToken(),json 命令编码失败! \n");
|
||||
@ -606,3 +604,55 @@ int COperateServerClass::optTokenAlarm(const STokenInfoAll &stOptTokenInfo, cons
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1607,11 +1607,48 @@ int CPermMngImpl::getAllUsergID(std::vector <SUsergIdName> &vecUsergID)
|
||||
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,
|
||||
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->userg_id = userg_id;
|
||||
//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 &login_sec, string &instance_name)
|
||||
{
|
||||
boost::ignore_unused_variable_warning(os_uptime);
|
||||
|
||||
nUserId = m_spUserInfo->user_id;
|
||||
userg_id = m_spUserInfo->userg_id;
|
||||
//os_uptime = m_spUserInfo->os_uptime;
|
||||
|
||||
@ -306,6 +306,12 @@ public:
|
||||
*/
|
||||
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:
|
||||
class CBioIdentify
|
||||
{
|
||||
|
||||
@ -61,6 +61,7 @@ void CSampleThreadImpl::execute()
|
||||
|
||||
//1.所有点存盘周期为固定5分钟
|
||||
//=================================================================================================
|
||||
/* 暂时禁用掉
|
||||
int mMin = m_lCurTime/(60000) ;//转换为分钟
|
||||
if ( (mMin % (SAMPLE_CYC_MIN) == 0) && (m_lCurTime/60000 - m_lLastTime/60000) >0 )//每5 min判一次
|
||||
{
|
||||
@ -68,6 +69,7 @@ void CSampleThreadImpl::execute()
|
||||
saveAllPoint() ;
|
||||
LOGDEBUG("CSampleThreadImpl::execute, saveAllPoint() Time=[%" PRId64 "] ", m_lCurTime);
|
||||
}
|
||||
*/
|
||||
|
||||
//2.从消息缓存队列读取消息并处理
|
||||
//=================================================================================================
|
||||
@ -498,7 +500,7 @@ void CSampleThreadImpl::saveAllCfgPoint()
|
||||
int64 nTimeStamp = (getUTCTimeMsec()/(60*1000)) * 60000; //得到固定的分钟
|
||||
if(nPeriod<=0) nPeriod = 1;//
|
||||
|
||||
int mMin = m_lCurTime/(60*1000) ;//转换为分钟
|
||||
int64 mMin = m_lCurTime/(60*1000) ;//转换为分钟
|
||||
if( (mMin % nPeriod == 0))
|
||||
{
|
||||
if(POINT_TYPE_ANA == nPointType)
|
||||
@ -531,8 +533,9 @@ void CSampleThreadImpl::saveAllCfgPoint()
|
||||
void CSampleThreadImpl::saveAllPoint()
|
||||
{
|
||||
int64 nTimeStamp = (getUTCTimeMsec()/(60*1000)) * 60000; //得到固定的分钟
|
||||
LOCALTIME localTime = convertUTCMsecToLocalTime(nTimeStamp);
|
||||
|
||||
saveAllAnaPoint(nTimeStamp);
|
||||
saveAllAnaPoint(nTimeStamp,localTime.wMinute);
|
||||
|
||||
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;
|
||||
stTsdbData.Clear();
|
||||
@ -556,6 +559,13 @@ void CSampleThreadImpl::saveAllAnaPoint(const int64 nTimeStamp)
|
||||
pAnaPoint = (SAnaPointAll*)m_ptrRdbTableMng->getRecordAllColumnByIndex(RT_ANA_TBL,nIndex);
|
||||
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);
|
||||
}
|
||||
else
|
||||
|
||||
@ -50,7 +50,7 @@ private:
|
||||
//全数据存盘
|
||||
void saveAllCfgPoint(); //保存所有配置的点全数据
|
||||
void saveAllPoint(); //存盘全数据
|
||||
void saveAllAnaPoint(const int64 uTimeStamp);
|
||||
void saveAllAnaPoint(const int64 uTimeStamp,const int &minOfHour);
|
||||
void saveAllDigPoint(const int64 uTimeStamp);
|
||||
void saveAllAccPoint(const int64 uTimeStamp);
|
||||
void saveAllMixPoint(const int64 uTimeStamp);
|
||||
|
||||
@ -35,7 +35,8 @@ LIBS += \
|
||||
-lprotobuf \
|
||||
-ltsdb_save_api \
|
||||
-llog4cplus\
|
||||
-lboost_chrono
|
||||
-lboost_chrono \
|
||||
-lboost_date_time
|
||||
|
||||
include($$PWD/../../idl_files/idl_files.pri)
|
||||
|
||||
|
||||
@ -11,9 +11,9 @@ SUBDIRS+= interlock_api \
|
||||
operate_server \
|
||||
alarm_server \
|
||||
web_server \
|
||||
web_server_bi \
|
||||
# web_server_bi \
|
||||
alarm_system \
|
||||
iscs_wise_mnp \
|
||||
# iscs_wise_mnp \
|
||||
alarm_resource \
|
||||
|
||||
operate_server.depends = interlock_api perm_mng_api data_process_api
|
||||
|
||||
@ -47,6 +47,8 @@ oatpp::async::CoroutineStarter CAlmCntWsLsnr::onPing
|
||||
oatpp::async::CoroutineStarter CAlmCntWsLsnr::onPong
|
||||
( const std::shared_ptr<AsyncWebSocket> &spSocket, const oatpp::String &strMsg )
|
||||
{
|
||||
boost::ignore_unused_variable_warning(spSocket);
|
||||
|
||||
LOGINFO( "onPong(): message='%s'", strMsg->c_str());
|
||||
assert( spSocket == m_spHolder->m_spSocket );
|
||||
|
||||
@ -56,6 +58,8 @@ oatpp::async::CoroutineStarter CAlmCntWsLsnr::onPong
|
||||
oatpp::async::CoroutineStarter CAlmCntWsLsnr::onClose
|
||||
( 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());
|
||||
assert( spSocket == m_spHolder->m_spSocket );
|
||||
|
||||
@ -68,6 +72,8 @@ oatpp::async::CoroutineStarter CAlmCntWsLsnr::onClose
|
||||
oatpp::async::CoroutineStarter CAlmCntWsLsnr::readMessage
|
||||
( 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 );
|
||||
|
||||
if ( nSize > 0 )
|
||||
@ -77,8 +83,7 @@ oatpp::async::CoroutineStarter CAlmCntWsLsnr::readMessage
|
||||
else if ( nSize == 0 )
|
||||
{ //< size为0,表示消息传送完毕
|
||||
|
||||
if ( (oatpp::websocket::Frame::OPCODE_TEXT != nOpCode)
|
||||
&& (oatpp::websocket::Frame::OPCODE_CONTINUATION != nOpCode) )
|
||||
if ( oatpp::websocket::Frame::OPCODE_TEXT != nOpCode )
|
||||
{
|
||||
LOGERROR( "onMessage(): opcode=%d, not Text, 非预期!", nOpCode );
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
@ -61,6 +61,8 @@ oatpp::async::CoroutineStarter CAlmWsLsnr::onPing
|
||||
oatpp::async::CoroutineStarter CAlmWsLsnr::onPong
|
||||
( const std::shared_ptr<AsyncWebSocket> &spSocket, const oatpp::String &strMsg )
|
||||
{
|
||||
boost::ignore_unused_variable_warning(spSocket);
|
||||
|
||||
LOGINFO( "onPong(): message='%s'", strMsg->c_str());
|
||||
assert( spSocket == m_spHolder->m_spSocket );
|
||||
|
||||
@ -70,6 +72,8 @@ oatpp::async::CoroutineStarter CAlmWsLsnr::onPong
|
||||
oatpp::async::CoroutineStarter CAlmWsLsnr::onClose
|
||||
( 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());
|
||||
assert( spSocket == m_spHolder->m_spSocket );
|
||||
|
||||
@ -82,6 +86,8 @@ oatpp::async::CoroutineStarter CAlmWsLsnr::onClose
|
||||
oatpp::async::CoroutineStarter CAlmWsLsnr::readMessage
|
||||
( 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 );
|
||||
|
||||
if ( nSize > 0 )
|
||||
@ -91,8 +97,7 @@ oatpp::async::CoroutineStarter CAlmWsLsnr::readMessage
|
||||
else if ( nSize == 0 )
|
||||
{ //< size为0,表示消息传送完毕
|
||||
|
||||
if ( (oatpp::websocket::Frame::OPCODE_TEXT != nOpCode)
|
||||
&& (oatpp::websocket::Frame::OPCODE_CONTINUATION != nOpCode) )
|
||||
if ( oatpp::websocket::Frame::OPCODE_TEXT != nOpCode )
|
||||
{
|
||||
LOGERROR( "onMessage(): opcode=%d, not Text, 非预期!", nOpCode );
|
||||
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
|
||||
m_spHolder->m_setAlmType.clear();
|
||||
if ( !spReq->type->empty())
|
||||
@ -507,63 +534,72 @@ void CAlmWsLsnr::sendMessage()
|
||||
spRep->total = std::ceil( static_cast<double> ( spRep->records ) / spRep->pageSize );
|
||||
if ( spRep->total <= 0 ) spRep->total = 1;
|
||||
//< 前流程已保证 m_spHolder->m_nPageNo 大于 0
|
||||
spRep->pageNo = m_spHolder->m_nPageNo > spRep->total ?
|
||||
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;
|
||||
//< 使用std::min或者std::max的时候加上括号,避免与Windows.h中的min、max宏定义冲突
|
||||
const int nEndIdx = ( std::min )( nBeginIdx + spRep->pageSize, ( int ) m_pAlmTable->size());
|
||||
int nIdx = 0;
|
||||
auto &indexOrder = m_pAlmTable->get<LiveAlm_Order>();
|
||||
for ( auto it = indexOrder.cbegin(); it != indexOrder.cend() && nIdx < nEndIdx; ++it, ++nIdx )
|
||||
if(m_spHolder->m_nPageNo <= spRep->total)
|
||||
{
|
||||
if ( nIdx < nBeginIdx )
|
||||
continue;
|
||||
spRep->pageNo = m_spHolder->m_nPageNo > spRep->total ?
|
||||
spRep->total.getValue( 0 ) : m_spHolder->m_nPageNo;
|
||||
|
||||
const auto &spAlm = *it;
|
||||
auto spRepData = dto::CAlmRepData::createShared();
|
||||
const int nBeginIdx = ( spRep->pageNo - 1 ) * spRep->pageSize;
|
||||
//< 使用std::min或者std::max的时候加上括号,避免与Windows.h中的min、max宏定义冲突
|
||||
const int nEndIdx = ( std::min )( nBeginIdx + spRep->pageSize, ( int ) m_pAlmTable->size());
|
||||
int nIdx = 0;
|
||||
auto &indexOrder = m_pAlmTable->get<LiveAlm_Order>();
|
||||
for ( auto it = indexOrder.cbegin(); it != indexOrder.cend() && nIdx < nEndIdx; ++it, ++nIdx )
|
||||
{
|
||||
if ( nIdx < nBeginIdx )
|
||||
continue;
|
||||
|
||||
spRepData->content = spAlm->getContent();
|
||||
const auto &spAlm = *it;
|
||||
auto spRepData = dto::CAlmRepData::createShared();
|
||||
|
||||
spRepData->other = oatpp::Vector<oatpp::Any>::createShared();
|
||||
const auto &spOther = spRepData->other;
|
||||
spOther->emplace_back( oatpp::Int32( nIdx + 1 ));
|
||||
//< todo 建议前端把告警窗和事件窗统一成一样的
|
||||
if ( 0 == m_spHolder->m_nEndPointType )
|
||||
{//< 告警窗
|
||||
//< 前端按序号访问other,需注意顺序不能乱,示例如下:
|
||||
//< other: [136, "数字量变位", "状态变位", "未确认", 1643019095930, "EMS监控中心域", "EMS监控中心", "EMS监控", "高", "母线", "默认责任区"]
|
||||
spOther->emplace_back( oatpp::String( spAlm->getAlmTypeDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getAlmStatusDesc()));
|
||||
const char *szCfm = spAlm->isConfirmed() ? "已确认" : "未确认";
|
||||
spOther->emplace_back( oatpp::String( szCfm ));
|
||||
spOther->emplace_back( oatpp::Int64( spAlm->getTimeStamp()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getDomainDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getLocationDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getSubSystemDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getPriorityDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getDevTypeDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getRegionDesc()));
|
||||
}
|
||||
else
|
||||
{//< 事件窗
|
||||
//< 前端按序号访问other,需注意顺序不能乱,示例如下:
|
||||
//< other: [482, "母线", "状态变位", 1645008132566, "EMS监控中心域", "EMS监控中心", "EMS监控", "高", "数字量变位", "默认责任区"]
|
||||
spOther->emplace_back( oatpp::String( spAlm->getDevTypeDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getAlmStatusDesc()));
|
||||
spOther->emplace_back( oatpp::Int64( spAlm->getTimeStamp()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getDomainDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getLocationDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getSubSystemDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getPriorityDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getAlmTypeDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getRegionDesc()));
|
||||
spRepData->content = spAlm->getContent();
|
||||
spRepData->keyIdTag = oatpp::String( spAlm->getKeyIdTag());
|
||||
|
||||
spRepData->other = oatpp::Vector<oatpp::Any>::createShared();
|
||||
const auto &spOther = spRepData->other;
|
||||
spOther->emplace_back( oatpp::Int32( nIdx + 1 ));
|
||||
//< todo 建议前端把告警窗和事件窗统一成一样的
|
||||
if ( 0 == m_spHolder->m_nEndPointType )
|
||||
{//< 告警窗
|
||||
//< 前端按序号访问other,需注意顺序不能乱,示例如下:
|
||||
//< 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->getAlmStatusDesc()));
|
||||
const char *szCfm = spAlm->isConfirmed() ? "已确认" : "未确认";
|
||||
spOther->emplace_back( oatpp::String( szCfm ));
|
||||
spOther->emplace_back( oatpp::Int64( spAlm->getTimeStamp()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getDomainDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getLocationDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getSubSystemDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getPriorityDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getDevTypeDesc()));
|
||||
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
|
||||
{//< 事件窗
|
||||
//< 前端按序号访问other,需注意顺序不能乱,示例如下:
|
||||
//< other: [482, "母线", "状态变位", 1645008132566, "EMS监控中心域", "EMS监控中心", "EMS监控", "高", "数字量变位", "默认责任区"]
|
||||
spOther->emplace_back( oatpp::String( spAlm->getDevTypeDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getAlmStatusDesc()));
|
||||
spOther->emplace_back( oatpp::Int64( spAlm->getTimeStamp()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getDomainDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getLocationDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getSubSystemDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getPriorityDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getAlmTypeDesc()));
|
||||
spOther->emplace_back( oatpp::String( spAlm->getRegionDesc()));
|
||||
}
|
||||
|
||||
spRep->data->emplace_back( std::move( spRepData ));
|
||||
}
|
||||
|
||||
spRep->data->emplace_back( std::move( spRepData ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OATPP_COMPONENT( std::shared_ptr<oatpp::data::mapping::ObjectMapper>, spMapper );
|
||||
return oatpp::async::synchronize( &m_spHolder->m_lockWrite,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
/**********************************************************************************
|
||||
* @file AlmWsLsnr.hpp
|
||||
* @brief 告警内容WebSocket的监听类
|
||||
@ -105,9 +105,8 @@ private:
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
else
|
||||
{//< 事件窗
|
||||
@ -115,6 +114,9 @@ private:
|
||||
return 9;
|
||||
}
|
||||
|
||||
if ( !m_setKeyIdTag.empty() && m_setKeyIdTag.count( spAlm->getKeyIdTag()) <= 0 )
|
||||
return 10;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -128,6 +130,7 @@ private:
|
||||
int64_t m_nStartTime{-1}; //< 小于等于0表示不过滤
|
||||
int64_t m_nEndTime{-1}; //< 小于等于0表示不过滤
|
||||
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_setLocationID;
|
||||
std::unordered_set<int> m_setPriority;
|
||||
|
||||
@ -200,6 +200,7 @@ class CAlmReq : public oatpp::DTO
|
||||
DTO_FIELD( Any, endTime );
|
||||
//todo 是否已确认 前端传过来的是"almStatus",不符合我们的命名,可以考虑让前端修改
|
||||
DTO_FIELD( String, almStatus );
|
||||
DTO_FIELD( String, keyIdTag );
|
||||
DTO_FIELD( String, type );
|
||||
//< json里有,但没用,界面就没有按内容过滤的的功能
|
||||
//DTO_FIELD( String, content );
|
||||
@ -222,7 +223,7 @@ class CAlmRepData : public oatpp::DTO
|
||||
DTO_FIELD( String, content );
|
||||
//< 前端并没有使用
|
||||
//DTO_FIELD( String, graphName );
|
||||
//DTO_FIELD( String, keyIdTag );
|
||||
DTO_FIELD( String, keyIdTag );
|
||||
//DTO_FIELD( Vector < String > , soundFile );
|
||||
|
||||
//< 前端按序号访问other,需注意顺序不能乱
|
||||
@ -252,6 +253,107 @@ class CAlmRep : public oatpp::DTO
|
||||
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 module_alarm
|
||||
} //namespace web_server
|
||||
|
||||
@ -179,7 +179,7 @@ public:
|
||||
//< 是否流水账告警
|
||||
inline bool isWaterAlm() const
|
||||
{
|
||||
return m_spAlmInfo->if_water_alm();
|
||||
return (m_spAlmInfo->if_water_alm() != 0);
|
||||
}
|
||||
|
||||
//< 本条告警信息的唯一标识,使用base64编码缩短后的uuid
|
||||
|
||||
@ -14,11 +14,14 @@
|
||||
|
||||
#include "pub_logger_api/logger.h"
|
||||
#include "pub_utility_api/TimeUtil.h"
|
||||
#include "pub_utility_api/I18N.h"
|
||||
#include "db_api_ex/CDbApi.h"
|
||||
#include "rdb_api/CRdbAccess.h"
|
||||
//#include "alarm_server_api/AlarmCommonDef.h"
|
||||
|
||||
#include "../include/SessionApi.h"
|
||||
#include "../module_alarm/DataMngThread.hpp"
|
||||
|
||||
#include "DTOs.hpp"
|
||||
#include "SimpleCtrl.hpp"
|
||||
|
||||
@ -265,9 +268,9 @@ std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> CSimpleCtrl::que
|
||||
nStartTimeMsec = nTemp;
|
||||
}
|
||||
|
||||
if ( content != "" || regionId != "" )
|
||||
if ( regionId != "" )
|
||||
{
|
||||
const char *szMsg = "请求错误:按内容或者按区域搜索未启用";
|
||||
const char *szMsg = "请求错误:按区域搜索未启用";
|
||||
LOGERROR( "%s", 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( vecType, "alm_type" );
|
||||
|
||||
if( content != "" )
|
||||
{
|
||||
strCondition += QString(" content like '%%1%'").arg(urldecode(*content).c_str());
|
||||
strCondition += " and ";
|
||||
|
||||
}
|
||||
|
||||
if ( 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());
|
||||
return createResponse( Status::CODE_500, "数据库查询错误" );
|
||||
}
|
||||
LOGDEBUG( "SQL语句如下:\n%s", strSql.toUtf8().constData());
|
||||
//LOGDEBUG( "SQL语句如下:\n%s", strSql.toUtf8().constData());
|
||||
|
||||
|
||||
auto spResp = dto::EventMsDto::createShared();
|
||||
@ -937,6 +947,428 @@ CSimpleCtrl::queryEventConditionMs( /*const oatpp::Int32 &type, const oatpp::Int
|
||||
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 web_server
|
||||
|
||||
@ -46,6 +46,28 @@ public:
|
||||
|
||||
ENDPOINT( "GET", "queryEventConditionMs", queryEventConditionMs,
|
||||
/*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
|
||||
|
||||
1946
platform/src/service/web_server/module_app/CtrlApp.cpp
Normal file
1946
platform/src/service/web_server/module_app/CtrlApp.cpp
Normal file
File diff suppressed because it is too large
Load Diff
157
platform/src/service/web_server/module_app/CtrlApp.h
Normal file
157
platform/src/service/web_server/module_app/CtrlApp.h
Normal 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
|
||||
|
||||
|
||||
379
platform/src/service/web_server/module_app/DTOs.hpp
Normal file
379
platform/src/service/web_server/module_app/DTOs.hpp
Normal 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 )
|
||||
51
platform/src/service/web_server/module_app/ModuleApp.cpp
Normal file
51
platform/src/service/web_server/module_app/ModuleApp.cpp
Normal 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>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
28
platform/src/service/web_server/module_app/ModuleApp.h
Normal file
28
platform/src/service/web_server/module_app/ModuleApp.h
Normal 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
|
||||
30
platform/src/service/web_server/module_app/module_app.pro
Normal file
30
platform/src/service/web_server/module_app/module_app.pro
Normal 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")
|
||||
}
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
|
||||
#include "CtrlGeneral.hpp"
|
||||
#include "../include/ServerApi.h"
|
||||
#include <QtSql/QSql>
|
||||
#include "db_api_ex/CDbApi.h"
|
||||
|
||||
|
||||
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 )
|
||||
{
|
||||
LOGERROR( "wropng size of results of the safe_day" );
|
||||
LOGERROR( "wrong size of results of the safe_day" );
|
||||
return createResponse( Status::CODE_500, "查询失败" );
|
||||
}
|
||||
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 web_server
|
||||
|
||||
@ -70,6 +70,14 @@ public:
|
||||
,QUERY(String, content)
|
||||
,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
|
||||
|
||||
@ -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 web_server
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
|
||||
#module.pri中已指定编译为静态库,生成路径在编译的临时目录
|
||||
QT += sql
|
||||
TEMPLATE = lib
|
||||
TARGET = module_general
|
||||
|
||||
|
||||
43
platform/src/service/web_server/module_operate/CModule.cpp
Normal file
43
platform/src/service/web_server/module_operate/CModule.cpp
Normal 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>();
|
||||
}
|
||||
|
||||
21
platform/src/service/web_server/module_operate/CModule.h
Normal file
21
platform/src/service/web_server/module_operate/CModule.h
Normal 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();
|
||||
};
|
||||
|
||||
}}
|
||||
155
platform/src/service/web_server/module_operate/CMsgDeal.cpp
Normal file
155
platform/src/service/web_server/module_operate/CMsgDeal.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}}
|
||||
|
||||
|
||||
50
platform/src/service/web_server/module_operate/CMsgDeal.h
Normal file
50
platform/src/service/web_server/module_operate/CMsgDeal.h
Normal 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
|
||||
@ -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 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -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 )
|
||||
114
platform/src/service/web_server/module_operate/DTOs.hpp
Normal file
114
platform/src/service/web_server/module_operate/DTOs.hpp
Normal 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 )
|
||||
@ -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")
|
||||
}
|
||||
|
||||
@ -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>();
|
||||
}
|
||||
21
platform/src/service/web_server/module_statistics/CModule.h
Normal file
21
platform/src/service/web_server/module_statistics/CModule.h
Normal 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();
|
||||
};
|
||||
|
||||
}}
|
||||
@ -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-miss,SQL语句如下:\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-miss,SQL语句如下:\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 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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 )
|
||||
197
platform/src/service/web_server/module_statistics/CTsdbQuery.cpp
Normal file
197
platform/src/service/web_server/module_statistics/CTsdbQuery.cpp
Normal 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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
167
platform/src/service/web_server/module_statistics/DTOs.hpp
Normal file
167
platform/src/service/web_server/module_statistics/DTOs.hpp
Normal 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 )
|
||||
@ -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")
|
||||
}
|
||||
@ -254,7 +254,7 @@ bool CController::getDeviceGroupInfoByLocationId( iot_dbms::CDbApi& objDb, oatpp
|
||||
auto pData = CDto_response_stationLocationMS::createShared();
|
||||
pData->code = objQuery.value(0).toString().toStdString();
|
||||
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->type = objQuery.value(3).toString().toStdString();
|
||||
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();
|
||||
pData->code = objQuery.value(0).toString().toStdString();
|
||||
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->type = objQuery.value(3).toString().toStdString();
|
||||
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();
|
||||
pData->code = objQuery.value(0).toString().toStdString();
|
||||
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->type = objQuery.value(3).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();
|
||||
pData->code = objQuery.value(0).toString().toStdString();
|
||||
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->type = objQuery.value(3).toString().toStdString();
|
||||
pData->sname = objQuery.value(4).toString().toStdString();
|
||||
|
||||
@ -20,6 +20,9 @@
|
||||
#include "../module_general/ModuleGeneral.hpp"
|
||||
#include "../module_realTimeData/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"
|
||||
|
||||
@ -146,6 +149,33 @@ bool CGlobalMng::init( const std::string &strAppName )
|
||||
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 其他组件
|
||||
}
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
#include "pub_logger_api/logger.h"
|
||||
#include "pub_utility_api/SingleProcInstance.h"
|
||||
#include "pub_utility_api/FileUtil.h"
|
||||
#include "pub_utility_api/I18N.h"
|
||||
#include "net_msg_bus_api/MsgBusApi.h"
|
||||
#include "tsdb_api/TsdbApi.h"
|
||||
|
||||
@ -115,6 +116,16 @@ bool CWebServer::start( int argc, char *argv[], int & /*nStatus*/)
|
||||
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 ))
|
||||
{
|
||||
|
||||
@ -4,14 +4,15 @@
|
||||
#include "oatpp/core/macro/component.hpp"
|
||||
#include "oatpp/web/protocol/http/outgoing/ResponseFactory.hpp"
|
||||
#include "oatpp/network/tcp/server/ConnectionProvider.hpp"
|
||||
#include "pub_utility_api/FileUtil.h"
|
||||
#include "pub_utility_api/CommonConfigParse.h"
|
||||
|
||||
#include "AuthInterceptor.h"
|
||||
|
||||
#include "boost/uuid/random_generator.hpp"
|
||||
#include "boost/regex.hpp"
|
||||
#include <regex>
|
||||
|
||||
#include <sstream>
|
||||
#include <QDateTime>
|
||||
|
||||
using namespace web_server::auth;
|
||||
|
||||
@ -56,65 +57,45 @@ static void generateUuidBase64(std::string &strOut)
|
||||
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 alarmWsRegex("^\\/alarmWebsocket$");
|
||||
// std::regex hisEvtWsRegex("^\\/historyEvent$");
|
||||
// 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(hisEvtWsRegex))
|
||||
// || 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++)
|
||||
{
|
||||
LOGDEBUG("isPathAlwaysAllow::path=[%s] .\n",path.c_str());
|
||||
return true;
|
||||
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)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
// TODO 结束测试后该行改为false
|
||||
return 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)
|
||||
{
|
||||
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 port = request->getConnection()->getInputStreamContext().getProperties().get(oatpp::network::tcp::server::ConnectionProvider::ExtendedConnection::PROPERTY_PEER_PORT);
|
||||
|
||||
// << 地址白名单判断,白名单内IP不判断权限。但是不能影响正常的WEB访问
|
||||
if( isAddrAlwayAllow(address) && !isPathAlwaysAllow(routes)) //在白名单内 && 不是登录操作,直接返回,不校验权限
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
// 配置文件允许的连接不拦截
|
||||
// if( isPathAlwaysAllow(routes) )
|
||||
// {
|
||||
// return nullptr;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// throw oatpp::web::protocol::http::HttpError(oatpp::web::protocol::http::Status::CODE_401, "Unauthorized", {});
|
||||
// }
|
||||
|
||||
if( isPathAlwaysBlock(routes) )
|
||||
{
|
||||
@ -188,6 +208,22 @@ std::shared_ptr<oatpp::web::server::interceptor::RequestInterceptor::OutgoingRes
|
||||
auto username = queryParams.get("username");
|
||||
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();
|
||||
|
||||
bool ret = m_rdbUtil.isPermOk(username,password);
|
||||
@ -199,6 +235,9 @@ std::shared_ptr<oatpp::web::server::interceptor::RequestInterceptor::OutgoingRes
|
||||
else
|
||||
{
|
||||
rdbRet = false;
|
||||
|
||||
mapLockedDb[username].first += 1;
|
||||
mapLockedDb[username].second = QDateTime::currentMSecsSinceEpoch();
|
||||
}
|
||||
|
||||
bool loginRet = true;
|
||||
@ -211,6 +250,7 @@ std::shared_ptr<oatpp::web::server::interceptor::RequestInterceptor::OutgoingRes
|
||||
std::string id;
|
||||
generateUuidBase64(id);
|
||||
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]))
|
||||
{
|
||||
@ -249,7 +289,6 @@ std::shared_ptr<oatpp::web::server::interceptor::RequestInterceptor::OutgoingRes
|
||||
LOGERROR("cannot get sessionid from cookie");
|
||||
throw oatpp::web::protocol::http::HttpError(oatpp::web::protocol::http::Status::CODE_401, "Unauthorized", {});
|
||||
}
|
||||
|
||||
// 注销处理
|
||||
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\"}");
|
||||
|
||||
response->putHeader("Set-Cookie", "");
|
||||
response->putHeader("token", "");
|
||||
LOGINFO("Logout address:[%s], port:[%s]",address.c_str(), port.c_str());
|
||||
return response;
|
||||
|
||||
@ -298,7 +338,11 @@ bool AuthInterceptor::init()
|
||||
LOGERROR("rdbUtil failed to init!");
|
||||
return false;
|
||||
}
|
||||
if (confirm.load("../../data/config/", "pathallow.xml") == iotFailed)
|
||||
{
|
||||
LOGDEBUG("pathallow.xml error");
|
||||
return true;
|
||||
}
|
||||
LOGDEBUG("pathallow.xml ok");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -9,6 +9,8 @@
|
||||
#include "SesssionApiImpl.h"
|
||||
#include "pub_logger_api/logger.h"
|
||||
#include "AuthRdbUtil.h"
|
||||
#include "pub_utility_api/CommonConfigParse.h"
|
||||
using namespace iot_public;
|
||||
namespace web_server
|
||||
{
|
||||
namespace auth
|
||||
@ -22,9 +24,11 @@ public:
|
||||
std::shared_ptr<OutgoingResponse> intercept(const std::shared_ptr<IncomingRequest>& request) override;
|
||||
|
||||
bool init();
|
||||
bool isPathAlwaysAllow(const std::string& path );
|
||||
|
||||
|
||||
private:
|
||||
|
||||
CCommonConfigParse confirm;
|
||||
CSesssionApiImplPtr m_ptrSessionApiImpl = getSessionApiImplInstance();
|
||||
CAuthRdbUtil m_rdbUtil;
|
||||
};
|
||||
|
||||
@ -406,12 +406,6 @@ iot_service::CPermMngApiPtr CSesssionApiImpl::getCurPermApi(const std::shared_pt
|
||||
|
||||
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);
|
||||
if( nullptr == pPermMngApi )
|
||||
{
|
||||
|
||||
@ -17,7 +17,7 @@ TEMPLATE = app
|
||||
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之前,否则连接器报错
|
||||
LIBS += -loatpp-websocket -loatpp
|
||||
@ -26,12 +26,13 @@ if(CONFIG(enable_oatpp_zlib)) {
|
||||
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 \
|
||||
-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 \
|
||||
-ldb_his_query_api
|
||||
|
||||
|
||||
win32{
|
||||
LIBS += -lbcrypt
|
||||
}
|
||||
|
||||
@ -1,13 +1,17 @@
|
||||
|
||||
TEMPLATE = subdirs
|
||||
|
||||
WEB_MODULES = module_alarm \
|
||||
WEB_MODULES = \
|
||||
module_alarm \
|
||||
module_general \
|
||||
module_realTimeData \
|
||||
module_user \
|
||||
module_trend
|
||||
module_trend \
|
||||
module_app
|
||||
|
||||
SUBDIRS += $$WEB_MODULES server
|
||||
SUBDIRS += $$WEB_MODULES server \
|
||||
module_statistics \
|
||||
module_operate
|
||||
|
||||
#不用CONFIG += ordered方案,改为depends,模块可以并行编译
|
||||
server.depends = $$WEB_MODULES
|
||||
|
||||
@ -83,6 +83,19 @@ public:
|
||||
const QByteArray &baContent, iot_dbms::CDbApi *pDbApi = nullptr,qint64 *nUploadTime = nullptr);
|
||||
|
||||
|
||||
/**
|
||||
* 上传3D模型接口:保存文件,记录数据库
|
||||
* 接口使用QT的数据类型:1、方便使用;2、依托QT的COW机制,带来更好的性能
|
||||
* @param [in] strParentCode 父节点编码,前端传入,22位随机ID
|
||||
* @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更新文件
|
||||
@ -130,6 +143,9 @@ public:
|
||||
*/
|
||||
static bool readFileByPath( const QString &strPath, QByteArray &baContent );
|
||||
|
||||
|
||||
static bool readFileByFileNameAndGroup(const QString &strFileName,const QString &strFileGroup, QByteArray &baContent );
|
||||
|
||||
};
|
||||
|
||||
} //< namespace web_server_bi
|
||||
|
||||
@ -11,22 +11,21 @@ using namespace oatpp;
|
||||
using namespace web_server_bi::module_file;
|
||||
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
|
||||
const QString &cn_fileGroupImage = QStringLiteral ( "config/1/image" );
|
||||
const QString &cn_fileGroupJSON = QStringLiteral ( "config/1/json" );
|
||||
const QString &cn_fileGroupDefault = QStringLiteral ( "config/1" );
|
||||
|
||||
|
||||
const char* cn_contentTypeJPEG = "image/jpeg";
|
||||
const char* cn_contentTypePNG = "image/png";
|
||||
const char* cn_contentTypeGIF = "image/gif";
|
||||
const char* cn_contentTypeJSON = "application/json";
|
||||
const QString &cn_fileGroupImage = QStringLiteral("config/1/image");
|
||||
const QString &cn_fileGroupJSON = QStringLiteral("config/1/json");
|
||||
const QString &cn_fileGroupDefault = QStringLiteral("config/1");
|
||||
|
||||
const char *cn_contentTypeJPEG = "image/jpeg";
|
||||
const char *cn_contentTypePNG = "image/png";
|
||||
const char *cn_contentTypeGIF = "image/gif";
|
||||
const char *cn_contentTypeJSON = "application/json";
|
||||
const char *cn_contentTypeOctetSteam = "application/octet-stream";
|
||||
|
||||
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)
|
||||
{
|
||||
/* Prepare multipart container. */
|
||||
auto multipart = std::make_shared<multipart::PartList>(request->getHeaders());
|
||||
@ -35,7 +34,7 @@ web_server_bi::module_file::CController::uploadFile( const std::shared_ptr<Incom
|
||||
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 */));
|
||||
multipartReader.setPartReader("file", multipart::createInMemoryPartReader(MAX_FILE_SIZE /* max-data-size */));
|
||||
|
||||
/* Read multipart body */
|
||||
request->transferBody(&multipartReader);
|
||||
@ -44,65 +43,61 @@ web_server_bi::module_file::CController::uploadFile( const std::shared_ptr<Incom
|
||||
auto file = multipart->getNamedPart("file");
|
||||
|
||||
auto spResp = CUploadFileResp::createShared();
|
||||
if(!file)
|
||||
if (!file)
|
||||
{
|
||||
const std::string strMsg = I18N( "无效的请求参数,文件为空" );
|
||||
const std::string strMsg = I18N("无效的请求参数,文件为空");
|
||||
spResp->code = 400;
|
||||
LOGERROR( "uploadFile():%s", strMsg.c_str());
|
||||
LOGERROR("uploadFile():%s", strMsg.c_str());
|
||||
spResp->message = strMsg;
|
||||
return createDtoResponse( Status::CODE_400, spResp );
|
||||
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,strFileName = file->getFilename()->c_str();
|
||||
QString strFileGroup, strFileName = file->getFilename()->c_str();
|
||||
qint64 uploadTime;
|
||||
if( file->getHeader(Header::CONTENT_TYPE) == cn_contentTypeJPEG
|
||||
|| file->getHeader(Header::CONTENT_TYPE) == cn_contentTypePNG
|
||||
|| file->getHeader(Header::CONTENT_TYPE) == cn_contentTypeGIF )
|
||||
if (file->getHeader(Header::CONTENT_TYPE) == cn_contentTypeJPEG || file->getHeader(Header::CONTENT_TYPE) == cn_contentTypePNG || file->getHeader(Header::CONTENT_TYPE) == cn_contentTypeGIF)
|
||||
{
|
||||
strFileGroup = cn_fileGroupImage;
|
||||
}
|
||||
if( file->getHeader(Header::CONTENT_TYPE ) == cn_contentTypeJSON )
|
||||
if (file->getHeader(Header::CONTENT_TYPE) == cn_contentTypeJSON)
|
||||
{
|
||||
strFileGroup = cn_fileGroupJSON;
|
||||
}
|
||||
|
||||
|
||||
strFileName = CFileApi::uploadFile( strFileGroup ,
|
||||
strFileName,
|
||||
QByteArray(file->getPayload()->getInMemoryData()->c_str(),(int)( file->getPayload()->getInMemoryData()->size() ) ),
|
||||
nullptr,
|
||||
&uploadTime);
|
||||
if ( strFileName.isEmpty())
|
||||
strFileName = CFileApi::uploadFile(strFileGroup,
|
||||
strFileName,
|
||||
QByteArray(file->getPayload()->getInMemoryData()->c_str(), (int)(file->getPayload()->getInMemoryData()->size())),
|
||||
nullptr,
|
||||
&uploadTime);
|
||||
if (strFileName.isEmpty())
|
||||
{
|
||||
const std::string strMsg = I18N( "保存文件失败" );
|
||||
LOGERROR( "uploadFile():%s", strMsg.c_str());
|
||||
const std::string strMsg = I18N("保存文件失败");
|
||||
LOGERROR("uploadFile():%s", strMsg.c_str());
|
||||
spResp->code = 500;
|
||||
spResp->message = strMsg;
|
||||
return createDtoResponse( Status::CODE_500, spResp );
|
||||
return createDtoResponse(Status::CODE_500, spResp);
|
||||
}
|
||||
|
||||
spResp->data = COneFile::createShared();
|
||||
|
||||
QString strExt,strId;
|
||||
QString strExt, strId;
|
||||
int extIndex;
|
||||
if( ( extIndex = strFileName.lastIndexOf(".")) != -1)
|
||||
if ((extIndex = strFileName.lastIndexOf(".")) != -1)
|
||||
{
|
||||
strId = strFileName.left( extIndex );
|
||||
strExt = strFileName.mid(extIndex,-1);
|
||||
strId = strFileName.left(extIndex);
|
||||
strExt = strFileName.mid(extIndex, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::string strMsg = I18N( "服务器内部错误,文件名错误" );
|
||||
const std::string strMsg = I18N("服务器内部错误,文件名错误");
|
||||
spResp->code = 502;
|
||||
LOGERROR( "uploadFile():%s", strMsg.c_str());
|
||||
LOGERROR("uploadFile():%s", strMsg.c_str());
|
||||
spResp->message = strMsg;
|
||||
return createDtoResponse( Status::CODE_502, spResp );
|
||||
return createDtoResponse(Status::CODE_502, spResp);
|
||||
}
|
||||
|
||||
spResp->data->ext = strExt.toStdString();
|
||||
@ -112,161 +107,360 @@ web_server_bi::module_file::CController::uploadFile( const std::shared_ptr<Incom
|
||||
spResp->data->id = strId.toStdString();
|
||||
spResp->data->fileGroup = strFileGroup.toStdString();
|
||||
spResp->data->uploadTime = uploadTime;
|
||||
spResp->data->url = CFileApi::getUrl(strFileGroup,strFileName).toStdString();
|
||||
spResp->data->url = CFileApi::getUrl(strFileGroup, strFileName).toStdString();
|
||||
spResp->data->status = 0;
|
||||
|
||||
spResp->code = 200;
|
||||
spResp->message = cn_strSuccess;
|
||||
LOGINFO("upload file:%s,fileSize:%zu",file->getFilename()->c_str(), file->getPayload()->getInMemoryData()->size() );
|
||||
return createDtoResponse( Status::CODE_200, spResp );
|
||||
LOGINFO("upload file:%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::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::getFileByPath( const std::shared_ptr<IncomingRequest> &request )
|
||||
web_server_bi::module_file::CController::uploadByString(const std::shared_ptr<IncomingRequest> &request)
|
||||
{
|
||||
String strPath = request->getQueryParameter( "path" );
|
||||
if ( strPath.get() == nullptr || strPath->empty())
|
||||
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( "无效的请求参数" );
|
||||
LOGERROR( "getFileByPath():%s", strMsg.c_str());
|
||||
return createResponse( Status::CODE_400, strMsg );
|
||||
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>
|
||||
web_server_bi::module_file::CController::getFileByPath(const std::shared_ptr<IncomingRequest> &request)
|
||||
{
|
||||
String strPath = request->getQueryParameter("path");
|
||||
if (strPath.get() == nullptr || strPath->empty())
|
||||
{
|
||||
const std::string strMsg = I18N("无效的请求参数");
|
||||
LOGERROR("getFileByPath():%s", strMsg.c_str());
|
||||
return createResponse(Status::CODE_400, strMsg);
|
||||
}
|
||||
strPath = QUrl::fromPercentEncoding(strPath->c_str()).toStdString();
|
||||
|
||||
//TODO 图片特殊处理
|
||||
// String strWidth = request->getQueryParameter( "w" );
|
||||
// String strHeight = request->getQueryParameter( "h" );
|
||||
// String strQuality = request->getQueryParameter( "q" );
|
||||
// TODO 图片特殊处理
|
||||
// String strWidth = request->getQueryParameter( "w" );
|
||||
// String strHeight = request->getQueryParameter( "h" );
|
||||
// String strQuality = request->getQueryParameter( "q" );
|
||||
|
||||
QByteArray baContent;
|
||||
if( !CFileApi::readFileByPath(strPath->c_str(),baContent ) )
|
||||
if (!CFileApi::readFileByPath(strPath->c_str(), baContent))
|
||||
{
|
||||
const std::string strMsg = I18N( "读取文件失败" );
|
||||
LOGERROR( "getFileByPath():%s", strMsg.c_str());
|
||||
return createResponse( Status::CODE_500, strMsg );
|
||||
const std::string strMsg = I18N("读取文件失败");
|
||||
LOGERROR("getFileByPath():%s", strMsg.c_str());
|
||||
return createResponse(Status::CODE_500, strMsg);
|
||||
}
|
||||
|
||||
// Content-Type 处理
|
||||
QString strExt,strFilePath = strPath->c_str();
|
||||
QString strExt, strFilePath = strPath->c_str();
|
||||
int extIndex;
|
||||
if( ( extIndex = strFilePath.lastIndexOf(".")) != -1)
|
||||
if ((extIndex = strFilePath.lastIndexOf(".")) != -1)
|
||||
{
|
||||
strExt = strFilePath.right(extIndex + 1);
|
||||
}
|
||||
|
||||
auto response = createResponse( Status::CODE_200, baContent.toStdString() );
|
||||
if( strExt == "json")
|
||||
auto response = createResponse(Status::CODE_200, baContent.toStdString());
|
||||
if (strExt == "json")
|
||||
{
|
||||
response->putHeader("Content-Type",cn_contentTypeJSON);
|
||||
response->putHeader("Content-Type", cn_contentTypeJSON);
|
||||
}
|
||||
else if( strExt == "png"
|
||||
|| strExt == "gif"
|
||||
|| strExt == "jpg"
|
||||
|| strExt == "jpeg")
|
||||
else if (strExt == "png" || 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());
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
|
||||
web_server_bi::module_file::CController::getFileByNameAndGroup( const std::shared_ptr<IncomingRequest> &request )
|
||||
web_server_bi::module_file::CController::getFileByNameAndGroup(const std::shared_ptr<IncomingRequest> &request)
|
||||
{
|
||||
String strFileGroup = request->getQueryParameter( "fileGroup" );
|
||||
if ( strFileGroup.get() == nullptr || strFileGroup->empty())
|
||||
String strFileGroup = request->getQueryParameter("fileGroup");
|
||||
if (strFileGroup.get() == nullptr || strFileGroup->empty())
|
||||
{
|
||||
strFileGroup = "others";
|
||||
}
|
||||
strFileGroup = QUrl::fromPercentEncoding(strFileGroup->c_str()).toStdString();
|
||||
|
||||
|
||||
String strFileName = request->getQueryParameter( "fileName" );
|
||||
if ( strFileName.get() == nullptr || strFileName->empty())
|
||||
String strFileName = request->getQueryParameter("fileName");
|
||||
if (strFileName.get() == nullptr || strFileName->empty())
|
||||
{
|
||||
const std::string strMsg = I18N( "无效的请求参数" );
|
||||
LOGERROR( "getFileByNameAndGroup():%s", strMsg.c_str());
|
||||
return createResponse( Status::CODE_400, strMsg );
|
||||
const std::string strMsg = I18N("无效的请求参数");
|
||||
LOGERROR("getFileByNameAndGroup():%s", strMsg.c_str());
|
||||
return createResponse(Status::CODE_400, strMsg);
|
||||
}
|
||||
strFileName = QUrl::fromPercentEncoding(strFileName->c_str()).toStdString();
|
||||
|
||||
|
||||
String strPath = strFileGroup + "/" + strFileName;
|
||||
|
||||
//TODO 图片特殊处理
|
||||
// String strWidth = request->getQueryParameter( "w" );
|
||||
// String strHeight = request->getQueryParameter( "h" );
|
||||
// String strQuality = request->getQueryParameter( "q" );
|
||||
// TODO 图片特殊处理
|
||||
// String strWidth = request->getQueryParameter( "w" );
|
||||
// String strHeight = request->getQueryParameter( "h" );
|
||||
// String strQuality = request->getQueryParameter( "q" );
|
||||
|
||||
QByteArray baContent;
|
||||
if( !CFileApi::readFileByPath(strPath->c_str(),baContent ) )
|
||||
if (!CFileApi::readFileByPath(strPath->c_str(), baContent))
|
||||
{
|
||||
const std::string strMsg = I18N( "读取文件失败" );
|
||||
LOGERROR( "getFileByNameAndGroup():%s", strMsg.c_str());
|
||||
return createResponse( Status::CODE_500, strMsg );
|
||||
if (!CFileApi::readFileByFileNameAndGroup(strFileName->c_str(),strFileGroup->c_str(), baContent))
|
||||
{
|
||||
const std::string strMsg = I18N("读取文件失败");
|
||||
LOGERROR("getFileByNameAndGroup():%s", strMsg.c_str());
|
||||
return createResponse(Status::CODE_500, strMsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Content-Type 处理
|
||||
QString strExt,strFilePath = strPath->c_str();
|
||||
QString strExt, strFilePath = strPath->c_str();
|
||||
int extIndex;
|
||||
if( ( extIndex = strFilePath.lastIndexOf(".")) != -1)
|
||||
if ((extIndex = strFilePath.lastIndexOf(".")) != -1)
|
||||
{
|
||||
strExt = strFilePath.right(extIndex + 1);
|
||||
}
|
||||
|
||||
auto response = createResponse( Status::CODE_200, baContent.toStdString() );
|
||||
if( strExt == "json")
|
||||
auto response = createResponse(Status::CODE_200, baContent.toStdString());
|
||||
if (strExt == "json")
|
||||
{
|
||||
response->putHeader("Content-Type",cn_contentTypeJSON);
|
||||
response->putHeader("Content-Type", cn_contentTypeJSON);
|
||||
}
|
||||
else if( strExt == "png"
|
||||
|| strExt == "gif"
|
||||
|| strExt == "jpg"
|
||||
|| strExt == "jpeg")
|
||||
else if (strExt == "png" || 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());
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
|
||||
web_server_bi::module_file::CController::getContentByPath( const std::shared_ptr<IncomingRequest> &request )
|
||||
web_server_bi::module_file::CController::getContentByPath(const std::shared_ptr<IncomingRequest> &request)
|
||||
{
|
||||
String strPath = request->getQueryParameter( "path" );
|
||||
String strPath = request->getQueryParameter("path");
|
||||
auto spResp = CGetFileResp::createShared();
|
||||
|
||||
if ( strPath.get() == nullptr || strPath->empty())
|
||||
if (strPath.get() == nullptr || strPath->empty())
|
||||
{
|
||||
const std::string strMsg = I18N( "无效的请求参数" );
|
||||
LOGERROR( "getFileByPath():%s", strMsg.c_str());
|
||||
const std::string strMsg = I18N("无效的请求参数");
|
||||
LOGERROR("getFileByPath():%s", strMsg.c_str());
|
||||
spResp->message = strMsg;
|
||||
spResp->code = 400;
|
||||
return createDtoResponse( Status::CODE_400, spResp );
|
||||
return createDtoResponse(Status::CODE_400, spResp);
|
||||
}
|
||||
strPath = QUrl::fromPercentEncoding(strPath->c_str()).toStdString();
|
||||
|
||||
//TODO 图片特殊处理
|
||||
// String strWidth = request->getQueryParameter( "w" );
|
||||
// String strHeight = request->getQueryParameter( "h" );
|
||||
// String strQuality = request->getQueryParameter( "q" );
|
||||
// TODO 图片特殊处理
|
||||
// String strWidth = request->getQueryParameter( "w" );
|
||||
// String strHeight = request->getQueryParameter( "h" );
|
||||
// String strQuality = request->getQueryParameter( "q" );
|
||||
|
||||
QByteArray baContent;
|
||||
if( !CFileApi::readFileByPath(strPath->c_str(),baContent ) )
|
||||
if (!CFileApi::readFileByPath(strPath->c_str(), baContent))
|
||||
{
|
||||
const std::string strMsg = I18N( "读取文件失败" );
|
||||
LOGERROR( "getContentFileByPath():%s", strMsg.c_str());
|
||||
const std::string strMsg = I18N("读取文件失败");
|
||||
LOGERROR("getContentFileByPath():%s", strMsg.c_str());
|
||||
spResp->message = strMsg;
|
||||
spResp->code = 500;
|
||||
return createDtoResponse( Status::CODE_500, spResp );
|
||||
return createDtoResponse(Status::CODE_500, spResp);
|
||||
}
|
||||
|
||||
// Content-Type 处理
|
||||
QString strExt,strFilePath = strPath->c_str();
|
||||
QString strExt, strFilePath = strPath->c_str();
|
||||
int extIndex;
|
||||
if( ( extIndex = strFilePath.lastIndexOf(".")) != -1)
|
||||
if ((extIndex = strFilePath.lastIndexOf(".")) != -1)
|
||||
{
|
||||
strExt = strFilePath.right(extIndex + 1);
|
||||
}
|
||||
@ -275,17 +469,14 @@ web_server_bi::module_file::CController::getContentByPath( const std::shared_ptr
|
||||
spResp->message = cn_strSuccess;
|
||||
spResp->data = baContent.toStdString();
|
||||
|
||||
auto response = createDtoResponse( Status::CODE_200, spResp );
|
||||
if( strExt == "json")
|
||||
auto response = createDtoResponse(Status::CODE_200, spResp);
|
||||
if (strExt == "json")
|
||||
{
|
||||
response->putHeader("Content-Type",cn_contentTypeJSON);
|
||||
response->putHeader("Content-Type", cn_contentTypeJSON);
|
||||
}
|
||||
else if( strExt == "png"
|
||||
|| strExt == "gif"
|
||||
|| strExt == "jpg"
|
||||
|| strExt == "jpeg")
|
||||
else if (strExt == "png" || 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());
|
||||
}
|
||||
|
||||
return response;
|
||||
@ -295,8 +486,8 @@ std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
|
||||
web_server_bi::module_file::CController::getSystemTime()
|
||||
{
|
||||
QString resp = QString("{\"code\":200,\"message\":\"%1\",\"data\":%2}")
|
||||
.arg(cn_strSuccess.c_str())
|
||||
.arg(QDateTime::currentMSecsSinceEpoch());
|
||||
.arg(cn_strSuccess.c_str())
|
||||
.arg(QDateTime::currentMSecsSinceEpoch());
|
||||
|
||||
return createResponse( Status::CODE_200, resp.toStdString());
|
||||
return createResponse(Status::CODE_200, resp.toStdString());
|
||||
}
|
||||
|
||||
@ -28,18 +28,45 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief 上传文件
|
||||
*/
|
||||
ENDPOINT( "POST", "/api-common/config/uploadFile",uploadFile,
|
||||
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,
|
||||
REQUEST( std::shared_ptr<IncomingRequest>, request ) );
|
||||
|
||||
/**
|
||||
* @brief 通过分组和文件名获取文件
|
||||
*/
|
||||
ENDPOINT( "GET", "/api-file/file/get/getFileByNameAndGroup", getFileByNameAndGroup,
|
||||
REQUEST( std::shared_ptr<IncomingRequest>, request ) );
|
||||
|
||||
/**
|
||||
* @brief 通过路径获取文件内容
|
||||
*/
|
||||
ENDPOINT( "GET", "/api-file/file/get/getContentByPath", getContentByPath,
|
||||
REQUEST( std::shared_ptr<IncomingRequest>, request ) );
|
||||
|
||||
/**
|
||||
* @brief 获取系统时间
|
||||
*/
|
||||
ENDPOINT( "GET", "/api-sys/getSystemTime", getSystemTime );
|
||||
|
||||
};
|
||||
|
||||
@ -35,6 +35,14 @@ class CUploadFileResp : public oatpp::DTO
|
||||
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
|
||||
{
|
||||
DTO_INIT( CGetFileResp, DTO );
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "oatpp/web/server/HttpRouter.hpp"
|
||||
#include "CController.h"
|
||||
#include "CModule.h"
|
||||
#include "SyncthingMngThread.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" );
|
||||
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;
|
||||
}
|
||||
|
||||
@ -39,6 +80,12 @@ bool CModule::clean()
|
||||
//< todo 貌似没有 addController 的逆操作
|
||||
//< todo 清理业务资源
|
||||
|
||||
if ( m_ptrSyncthingMngThread != nullptr )
|
||||
{
|
||||
m_ptrSyncthingMngThread->quit();
|
||||
m_ptrSyncthingMngThread.reset();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
|
||||
#include "../include/BaseModule.h"
|
||||
|
||||
class SyncthingMngThread;
|
||||
typedef boost::shared_ptr<SyncthingMngThread> SyncthingMngThreadPtr;
|
||||
namespace web_server_bi { namespace module_file
|
||||
{
|
||||
|
||||
@ -16,6 +18,7 @@ public:
|
||||
bool redundantSwitch( bool bMaster, bool bSlave ) override;
|
||||
bool clean() override;
|
||||
static boost::shared_ptr<CModule> create();
|
||||
SyncthingMngThreadPtr m_ptrSyncthingMngThread = nullptr;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -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 )
|
||||
@ -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
|
||||
@ -10,10 +10,14 @@ HEADERS += \
|
||||
CController.h \
|
||||
CDTO.h \
|
||||
CModule.h \
|
||||
SyncthingMngThread.h \
|
||||
SyncthingRestOp.hpp \
|
||||
SyncthingRestDTO.hpp
|
||||
|
||||
SOURCES += \
|
||||
CModule.cpp \
|
||||
CController.cpp \
|
||||
SyncthingMngThread.cpp
|
||||
|
||||
|
||||
#静态库,不要连接,统一在server中连接
|
||||
|
||||
@ -563,7 +563,27 @@ CController::getPointsByDeviceCode( const String& deviceCode, const String& poin
|
||||
|
||||
// 查询测点信息
|
||||
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 )
|
||||
sSql = QString("select tag_name,description,state_text_name from %1 where device='%2'").arg(sTableName).arg(deviceCode.get()->c_str());
|
||||
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 = objQuery.value(0).toString().toStdString();
|
||||
pData->tagName = objQuery.value(1).toString().toStdString();
|
||||
pData->details = (location_tag + "." + sub_system_tag).toStdString();
|
||||
pData->name = pData->tagName;
|
||||
pData->coefficient = 1;
|
||||
pData->pointType = std::stoi(pointType.get()->c_str(),nullptr,0);
|
||||
|
||||
@ -18,6 +18,7 @@ namespace module_page
|
||||
|
||||
//< 云平台中规则为config/租户id/文件类型,我们不区分租户,假定租户id为1
|
||||
const QString &cn_strJsonFileGrp = QStringLiteral( "config/1/json" );
|
||||
const QString &cn_str3DFileGrp = QStringLiteral( "3D" );
|
||||
|
||||
//< 存数据库时将 full 换成 short,响应前端时把 short 换成 full,目的:
|
||||
//< 1、数据库中不存文件接口,以防接口改名,老工程无法兼容
|
||||
@ -65,7 +66,18 @@ QString fillOnePrimitive( const QSqlQuery &objQuery, dto::COnePrimitive::Wrapper
|
||||
|
||||
strTemp = objQuery.value( WebPrimitiveCol::content_path ).toString();
|
||||
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();
|
||||
if ( !strTemp.isEmpty())
|
||||
|
||||
@ -22,6 +22,7 @@ namespace module_page
|
||||
{
|
||||
|
||||
extern const QString &cn_strJsonFileGrp;
|
||||
extern const QString &cn_str3DFileGrp;
|
||||
|
||||
extern const QString &cn_strIconPathShort;
|
||||
extern const QString cn_strIconPathFull;
|
||||
|
||||
@ -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
|
||||
strSql = "SELECT location_id,description,plocation_id FROM sys_model_location_info";
|
||||
@ -492,7 +492,11 @@ CSimpleCtrlPage::selectList( const std::shared_ptr<IncomingRequest> &spRequest )
|
||||
mapAllPage.insert( strId, spOneData );
|
||||
|
||||
//< todo 当前未判权限,只有有权限的才加入 spRespData
|
||||
spRespData->push_back( spOneData );
|
||||
if( nReqPageType != 1 ) // 3d时跳过
|
||||
{
|
||||
spRespData->push_back( spOneData );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -517,7 +521,11 @@ CSimpleCtrlPage::selectList( const std::shared_ptr<IncomingRequest> &spRequest )
|
||||
mapAllPage.insert( strId, spOneData );
|
||||
|
||||
//< todo 当前未判权限,只有有权限的才加入 spRespData
|
||||
spRespData->push_back( spOneData );
|
||||
if( nReqPageType != 1 ) // 3d时跳过
|
||||
{
|
||||
spRespData->push_back( spOneData );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -533,6 +541,9 @@ CSimpleCtrlPage::selectList( const std::shared_ptr<IncomingRequest> &spRequest )
|
||||
const QString strId = objQuery.value( WebPageCol::id ).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 );
|
||||
|
||||
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()))
|
||||
{
|
||||
|
||||
auto &spOneData = itMap.value();
|
||||
QString strDelId, strDelPageName;
|
||||
|
||||
@ -573,6 +585,11 @@ CSimpleCtrlPage::selectList( const std::shared_ptr<IncomingRequest> &spRequest )
|
||||
else
|
||||
{
|
||||
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 )
|
||||
{
|
||||
LOGERROR("check here");
|
||||
if ( spOneData->parentCode.get() == nullptr || spOneData->parentCode->empty()
|
||||
|| !mapAllPage.contains( spOneData->parentCode->c_str()))
|
||||
{
|
||||
|
||||
@ -736,7 +736,19 @@ CSimpleCtrlPrimitive::updateById( const std::shared_ptr<IncomingRequest> &spRequ
|
||||
spOneData->primitiveName = strCurPrimitiveName.toStdString();
|
||||
|
||||
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())
|
||||
//< 将iconPath内容还原,详见常量定义注释
|
||||
|
||||
@ -184,6 +184,60 @@ QString CFileApi::uploadFile(const QString &strGroup, const QString &strOriginal
|
||||
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,
|
||||
const QByteArray *pContent, iot_dbms::CDbApi *pDbApi )
|
||||
{
|
||||
@ -424,4 +478,47 @@ bool CFileApi::readFileByPath( const QString &strPath, QByteArray &baContent )
|
||||
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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user