[fix]修改转发写入数据库逻辑,改为定时写入

This commit is contained in:
shi_jq 2025-03-04 09:31:08 +08:00
parent 0227348b17
commit 82b8ffc88b
3 changed files with 148 additions and 66 deletions

View File

@ -9,13 +9,17 @@
#include "pub_utility_api/I18N.h" #include "pub_utility_api/I18N.h"
#include <ctime> #include <ctime>
#include <chrono> #include <chrono>
#include <QTime>
using namespace kbd_public; using namespace kbd_public;
extern bool g_SqlServerIsMainFes;
extern bool g_SqlServerChanelRun;
DataProcThread::DataProcThread(CFesBase *ptrCFesBase, DataProcThread::DataProcThread(CFesBase *ptrCFesBase,
CFesChanPtr ptrCFesChan, CFesChanPtr ptrCFesChan,
const vector<SServerAppConfigParam> vecAppParam): const vector<SServerAppConfigParam> vecAppParam):
CTimerThreadBase("DataProcThread", 500,0,true) CTimerThreadBase("DataProcThread", 100,0,true)
{ {
m_ptrCFesChan = ptrCFesChan; m_ptrCFesChan = ptrCFesChan;
m_ptrCFesBase = ptrCFesBase; m_ptrCFesBase = ptrCFesBase;
@ -51,6 +55,8 @@ DataProcThread::DataProcThread(CFesBase *ptrCFesBase,
{ {
m_AppData = vecAppParam[i]; m_AppData = vecAppParam[i];
found = 1; found = 1;
std::string strConfig=m_AppData.strHour+m_AppData.strMinute+m_AppData.strSecond;
LOGDEBUG("DataProcThread::DataProcThread() ChanNo=%d use config(%s)", m_ptrCFesChan->m_Param.ChanNo,strConfig.c_str());
break; break;
} }
} }
@ -81,19 +87,21 @@ int DataProcThread::beforeExecute()
*/ */
void DataProcThread::execute() void DataProcThread::execute()
{ {
//读取网络事件
if (m_timerCount++ >= m_timerCountReset)
m_timerCount = 0;// 1sec is ready
m_ptrCurrentChan = GetCurrentChanData(m_ptrCFesChan); m_ptrCurrentChan = GetCurrentChanData(m_ptrCFesChan);
if(m_ptrCurrentChan== NULL) if(m_ptrCurrentChan== NULL)
return; return;
//处理数据 //处理数据
handlData(); if(g_SqlServerIsMainFes)
{
handlData();
}
//LOGDEBUG("DataProcThread::execute() end");
//LOGTRACE("DataProcThread::execute() end");
} }
/* /*
@ -165,16 +173,15 @@ int DataProcThread::handlData()
//获取当前使用的rtu //获取当前使用的rtu
m_ptrCFesRtu=GetRtuDataByRtuNo(m_AppData.RtuNo); m_ptrCFesRtu=GetRtuDataByRtuNo(m_AppData.RtuNo);
//判断是否到了周期时间 //判断是否到了时间
if(m_mapLastUpateTime.contains(m_AppData.RtuNo))
if(!ifOnTimeAndRecord())
{ {
auto& lastTime=m_mapLastUpateTime[m_AppData.RtuNo]; return kbdSuccess;
if(getUTCTimeSec()-lastTime<m_AppData.interval_time)
{
return kbdSuccess;
}
} }
//到时间了才定时更新内存 //到时间了才定时更新内存
TimerProcess(); TimerProcess();
@ -200,7 +207,7 @@ int DataProcThread::handlData()
if(isHandle1 || isHandle2 || isHandle3 || isHandle4) if(isHandle1 || isHandle2 || isHandle3 || isHandle4)
{ {
m_mapLastUpateTime[m_AppData.RtuNo]=getUTCTimeSec(); //m_mapLastUpateTime[m_AppData.RtuNo]=getUTCTimeSec();
} }
return kbdSuccess; return kbdSuccess;
@ -212,7 +219,7 @@ bool DataProcThread::handleAiData(CFesRtuPtr ptrRtu,QSqlDatabase& db,QString& te
QSqlQuery query(db); QSqlQuery query(db);
SFesFwAi *pFwAi; SFesFwAi *pFwAi;
double fvalue; double fvalue;
auto fmtTime=getFormatTime(); auto fmtTime=m_strCurRecordTime;
int errorTime = 0; int errorTime = 0;
for (int aiPoint = 0; aiPoint < ptrRtu->m_MaxFwAiPoints; aiPoint++) for (int aiPoint = 0; aiPoint < ptrRtu->m_MaxFwAiPoints; aiPoint++)
{ {
@ -220,7 +227,7 @@ bool DataProcThread::handleAiData(CFesRtuPtr ptrRtu,QSqlDatabase& db,QString& te
//bool aivalNormalFlag = 1; //bool aivalNormalFlag = 1;
if((pFwAi->Status & CN_FesValueUpdate) != CN_FesValueUpdate) if((pFwAi->Status & CN_FesValueUpdate) != CN_FesValueUpdate)
{ {
//LOGDEBUG("DataProcThread data value[%d] status [%d]",pFwAi->Value, pFwAi->Status); //LOGTRACE("DataProcThread data value[%d] status [%d]",pFwAi->Value, pFwAi->Status);
continue; continue;
//aivalNormalFlag = 0; //aivalNormalFlag = 0;
} }
@ -267,7 +274,7 @@ bool DataProcThread::handleDiData(CFesRtuPtr ptrRtu,QSqlDatabase& db,QString& te
QSqlQuery query(db); QSqlQuery query(db);
SFesFwDi *pFwDi; SFesFwDi *pFwDi;
int yxbit; int yxbit;
auto fmtTime=getFormatTime(); auto fmtTime=m_strCurRecordTime;
int errorTime = 0; int errorTime = 0;
for (int diPoint = 0; diPoint < m_ptrCFesRtu->m_MaxFwDiPoints; diPoint++) for (int diPoint = 0; diPoint < m_ptrCFesRtu->m_MaxFwDiPoints; diPoint++)
{ {
@ -275,7 +282,7 @@ bool DataProcThread::handleDiData(CFesRtuPtr ptrRtu,QSqlDatabase& db,QString& te
//bool divalNormalFlag = 1; //bool divalNormalFlag = 1;
if((pFwDi->Status & CN_FesValueUpdate) != CN_FesValueUpdate) if((pFwDi->Status & CN_FesValueUpdate) != CN_FesValueUpdate)
{ {
//LOGDEBUG("DataProcThread data value[%d] status [%d]",pFwDi->Value, pFwDi->Status); //LOGTRACE("DataProcThread data value[%d] status [%d]",pFwDi->Value, pFwDi->Status);
continue; continue;
//divalNormalFlag = 0; //divalNormalFlag = 0;
} }
@ -319,7 +326,7 @@ bool DataProcThread::handleAccData(CFesRtuPtr ptrRtu,QSqlDatabase& db,QString& t
QSqlQuery query(db); QSqlQuery query(db);
double fvalue; double fvalue;
SFesFwAcc *pFwAcc; SFesFwAcc *pFwAcc;
auto fmtTime=getFormatTime(); auto fmtTime=m_strCurRecordTime;
int errorTime = 0; int errorTime = 0;
for (int accPoint = 0; accPoint < ptrRtu->m_MaxFwAccPoints; accPoint++) for (int accPoint = 0; accPoint < ptrRtu->m_MaxFwAccPoints; accPoint++)
{ {
@ -328,7 +335,7 @@ bool DataProcThread::handleAccData(CFesRtuPtr ptrRtu,QSqlDatabase& db,QString& t
//bool accvalNormalFlag = 1; //bool accvalNormalFlag = 1;
if((pFwAcc->Status & CN_FesValueUpdate) != CN_FesValueUpdate) if((pFwAcc->Status & CN_FesValueUpdate) != CN_FesValueUpdate)
{ {
//LOGDEBUG("DataProcThread data value[%d] status [%d]",pFwAcc->Value, pFwAcc->Status); //LOGTRACE("DataProcThread data value[%d] status [%d]",pFwAcc->Value, pFwAcc->Status);
return false; return false;
//accvalNormalFlag = 0; //accvalNormalFlag = 0;
} }
@ -372,7 +379,7 @@ bool DataProcThread::handleMixData(CFesRtuPtr ptrRtu,QSqlDatabase& db,QString& t
QSqlQuery query(db); QSqlQuery query(db);
double fvalue; double fvalue;
SFesFwMi *pFwMi; SFesFwMi *pFwMi;
auto fmtTime=getFormatTime(); auto fmtTime=m_strCurRecordTime;
int errorTime = 0; int errorTime = 0;
for (int miPoint = 0; miPoint < ptrRtu->m_MaxFwMiPoints; miPoint++) for (int miPoint = 0; miPoint < ptrRtu->m_MaxFwMiPoints; miPoint++)
{ {
@ -380,7 +387,7 @@ bool DataProcThread::handleMixData(CFesRtuPtr ptrRtu,QSqlDatabase& db,QString& t
//bool mivalNormalFlag = 1; //bool mivalNormalFlag = 1;
if((pFwMi->Status & CN_FesValueUpdate) != CN_FesValueUpdate) if((pFwMi->Status & CN_FesValueUpdate) != CN_FesValueUpdate)
{ {
//LOGDEBUG("DataProcThread data value[%d] status [%d]",pFwMi->Value, pFwMi->Status); //LOGTRACE("DataProcThread data value[%d] status [%d]",pFwMi->Value, pFwMi->Status);
continue; continue;
//mivalNormalFlag = 0; //mivalNormalFlag = 0;
} }
@ -458,26 +465,74 @@ void DataProcThread::ShowChanData(QString &sendData)
delete[] slog; delete[] slog;
} }
QString DataProcThread::getFormatTime()
bool DataProcThread::ifOnTimeAndRecord()
{ {
// 获取当前时间 QTime currentTime = QTime::currentTime();
auto now = std::chrono::system_clock::now(); QString dateFormattString=QDate::currentDate().toString("yyyy-MM-dd");
std::time_t now_c = std::chrono::system_clock::to_time_t(now); QString formattString=dateFormattString+QString(" %1:%2:%3");
std::string strHour = boost::lexical_cast<std::string>(currentTime.hour());
LOGTRACE("DataProcThread::DataProcThread() ChanNo=%d ifOnTimeAndRecord (%s)", m_ptrCFesChan->m_Param.ChanNo,QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss").toStdString().c_str());
// 转换为 tm 结构,便于操作时间字段 if(m_AppData.strHour!="*")
std::tm* currentTime = std::localtime(&now_c); {
if(m_AppData.strHour!=strHour)
{
return false;
}
// 将分钟和秒归零 }
currentTime->tm_min = 0;
currentTime->tm_sec = 0;
currentTime->tm_sec = currentTime->tm_sec+m_AppData.second_offset;
auto timeValue=std::mktime(currentTime);
std::ostringstream oss; std::string strMinute = boost::lexical_cast<std::string>(currentTime.minute());
oss << std::put_time(std::localtime(&timeValue), "%Y-%m-%d %H:%M:%S"); if(m_AppData.strMinute!="*")
std::string res=oss.str(); {
return QString::fromStdString(res);
if(m_AppData.strMinute!=strMinute)
{
return false;
}
}
std::string strSecond = boost::lexical_cast<std::string>(currentTime.second());
if(m_AppData.strSecond!="*")
{
if(m_AppData.strSecond!=strSecond)
{
return false;
}
}
QString tmpHourStr=QString::fromStdString(strHour);
tmpHourStr=tmpHourStr.rightJustified(2,'0');
QString tmpMinuteStr=QString::fromStdString(strMinute);
tmpMinuteStr=tmpMinuteStr.rightJustified(2,'0');
QString tmpSecondStr=QString::fromStdString(strSecond);
tmpSecondStr=tmpSecondStr.rightJustified(2,'0');
formattString=formattString.arg(tmpHourStr).arg(tmpMinuteStr).arg(tmpSecondStr);
QDateTime triggerTime=QDateTime ::fromString(formattString,"yyyy-MM-dd HH:mm:ss");
triggerTime=triggerTime.addSecs(m_AppData.second_offset);
QString curTriggerRecordTime=triggerTime.toString("yyyy-MM-dd HH:mm:ss");
if(m_strCurRecordTime!=curTriggerRecordTime)
{
m_strCurRecordTime=curTriggerRecordTime;
LOGDEBUG("DataProcThread.cpp time(%s) is time to record", curTriggerRecordTime.toStdString().c_str());
return true;
}
return false;
} }

View File

@ -21,7 +21,10 @@ typedef struct{
std::string user_name; //用户名 std::string user_name; //用户名
std::string password; //密码 std::string password; //密码
int interval_time; //间隔多久写入一次 (秒) int interval_time; //间隔多久写入一次 (秒)
int second_offset; int second_offset;
std::string strHour; //*为通配符
std::string strMinute;
std::string strSecond;
}SServerAppConfigParam; }SServerAppConfigParam;
class DataProcThread : public CTimerThreadBase,CProtocolBase class DataProcThread : public CTimerThreadBase,CProtocolBase
@ -48,11 +51,12 @@ public:
CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区, 每个通道对应一个RTU数据所以不需要轮询处理。 CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区, 每个通道对应一个RTU数据所以不需要轮询处理。
CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据
SServerAppConfigParam m_AppData; //内部应用数据结构 SServerAppConfigParam m_AppData; //内部应用数据结构
QMap<int,uint64> m_mapLastUpateTime; //<rtu,最近更新时间> QMap<int,std::string> m_mapLastUpateTime; //<rtu,最近更新时间>
private: private:
int m_timerCount; int m_timerCount;
int m_timerCountReset; int m_timerCountReset;
QString m_strCurRecordTime;
int InitConfigParam(); int InitConfigParam();
@ -72,7 +76,10 @@ private:
QString formatToPrecision(double dvalue); QString formatToPrecision(double dvalue);
void ShowChanData(QString& sendData); void ShowChanData(QString& sendData);
QString getFormatTime();
bool ifOnTimeAndRecord();
}; };

View File

@ -1,24 +1,13 @@
/* 
@file MdbTcpSer.cpp
@brief MdbTcpSer规约处理主程序
@author JACKYWU
@date 2019-05-07
@history
2020-01-19 thxiao ReadConfigParam()RTUNO的限制
2020-02-13 thxiao ReadConfigParam()使m_ptrCFesBaseSetBaseAddr()
2020-02-18 thxiao GetProtocolInfo()4
2020-03-31 thxiao 退
2023-02-24 thxiao
1modbus_tcp_s.xml便
2DI
*/
#include "SqlServer.h" #include "SqlServer.h"
#include "pub_utility_api/CommonConfigParse.h" #include "pub_utility_api/CommonConfigParse.h"
using namespace kbd_public; using namespace kbd_public;
CSqlServer server; CSqlServer server;
bool g_SqlServerIsMainFes = false;
bool g_SqlServerChanelRun = true;
int EX_SetBaseAddr(void *address) int EX_SetBaseAddr(void *address)
{ {
@ -55,6 +44,7 @@ int EX_ExitSystem(int flag)
LOGDEBUG("CSqlServer EX_ExitSystem() start"); LOGDEBUG("CSqlServer EX_ExitSystem() start");
server.ExitSystem(flag); server.ExitSystem(flag);
LOGDEBUG("CSqlServer EX_ExitSystem() end"); LOGDEBUG("CSqlServer EX_ExitSystem() end");
g_SqlServerChanelRun = false;//使所有的线程退出。
return kbdSuccess; return kbdSuccess;
} }
CSqlServer::CSqlServer() CSqlServer::CSqlServer()
@ -93,7 +83,7 @@ int CSqlServer::SetProperty(int IsMainFes)
} }
} }
g_SqlServerIsMainFes = (IsMainFes == 1);
LOGDEBUG("CSqlServer::SetProperty IsMainFes:%d",IsMainFes); LOGDEBUG("CSqlServer::SetProperty IsMainFes:%d",IsMainFes);
return kbdSuccess; return kbdSuccess;
} }
@ -275,8 +265,9 @@ int CSqlServer::ReadConfigParam()
if (config.getStringValue(strRtuNo, "db_name", strvalue) == kbdSuccess) if (config.getStringValue(strRtuNo, "db_name", strvalue) == kbdSuccess)
{ {
param.db_name = strvalue; param.db_name = strvalue;
items++;
} }
items++;
param.interval_time = 3000; param.interval_time = 3000;
if (config.getIntValue(strRtuNo, "interval_time", ivalue) == kbdSuccess) if (config.getIntValue(strRtuNo, "interval_time", ivalue) == kbdSuccess)
@ -284,15 +275,16 @@ int CSqlServer::ReadConfigParam()
param.interval_time = ivalue; param.interval_time = ivalue;
items++; items++;
} }
items++;
param.table_name = "HistoryGenerallyVariable"; param.table_name = "HistoryGenerallyVariable";
strvalue.clear(); strvalue.clear();
if (config.getStringValue(strRtuNo, "table_name", strvalue) == kbdSuccess) if (config.getStringValue(strRtuNo, "table_name", strvalue) == kbdSuccess)
{ {
param.table_name = strvalue; param.table_name = strvalue;
items++;
} }
items++;
@ -301,8 +293,9 @@ int CSqlServer::ReadConfigParam()
if (config.getStringValue(strRtuNo, "password", strvalue) == kbdSuccess) if (config.getStringValue(strRtuNo, "password", strvalue) == kbdSuccess)
{ {
param.password = strvalue; param.password = strvalue;
items++;
} }
items++;
param.user_name="sa"; param.user_name="sa";
@ -310,17 +303,44 @@ int CSqlServer::ReadConfigParam()
if (config.getStringValue(strRtuNo, "user_name", strvalue) == kbdSuccess) if (config.getStringValue(strRtuNo, "user_name", strvalue) == kbdSuccess)
{ {
param.user_name = strvalue; param.user_name = strvalue;
items++;
} }
items++;
param.second_offset=0; param.second_offset=0;
if (config.getIntValue(strRtuNo, "second_offset", ivalue) == kbdSuccess) if (config.getIntValue(strRtuNo, "second_offset", ivalue) == kbdSuccess)
{ {
param.second_offset = ivalue; param.second_offset = ivalue;
items++;
} }
items++;
param.strHour="0";
strvalue.clear();
if (config.getStringValue(strRtuNo, "strHour", strvalue) == kbdSuccess)
{
param.strHour = strvalue;
items++;
}
param.strMinute="0";
strvalue.clear();
if (config.getStringValue(strRtuNo, "strMinute", strvalue) == kbdSuccess)
{
param.strMinute = strvalue;
items++;
}
param.strSecond="0";
strvalue.clear();
if (config.getStringValue(strRtuNo, "strSecond", strvalue) == kbdSuccess)
{
param.strSecond = strvalue;
items++;
}
if (items > 0)//对应的RTU有配置项 if (items > 0)//对应的RTU有配置项
{ {