1585 lines
40 KiB
C++
1585 lines
40 KiB
C++
#include "PQDIF.h"
|
||
#include "pqdsupport.h"
|
||
#include "cjson.h"
|
||
#include <ctime>
|
||
#include <sstream>
|
||
#include <iostream>
|
||
#include <fstream>
|
||
#include <string>
|
||
|
||
CPQDIF::CPQDIF()
|
||
{
|
||
// Init
|
||
m_percont = (CPQDIF_PC_FlatFile*)theFactory.NewPersistController(PFPC_FlatFile);
|
||
}
|
||
|
||
CPQDIF::~CPQDIF()
|
||
{
|
||
// Destroy
|
||
delete m_percont;
|
||
}
|
||
|
||
void CPQDIF::GetTime(DATE dt, time_t* tm)
|
||
{
|
||
*tm = (time_t)((double)(dt - EXCEL_DAYCOUNT_ADJUST + 1) * (double)SECONDS_PER_DAY - 8 * 60 * 60);//EXCEL_DAYCOUNT_ADJUST为1970年和1900年的天差 8*60*60为UTC时间差
|
||
|
||
}
|
||
|
||
void CPQDIF::put_FlatFileName(string strFileName)
|
||
{
|
||
// // AFX_MANAGE_STATE(AfxGetStaticModuleState())
|
||
|
||
m_percont->SetFileName(strFileName.c_str());
|
||
|
||
}
|
||
|
||
bool CPQDIF::Read()
|
||
{
|
||
// QT 版核心库 ReadHeaders() 返回 int 状态码
|
||
// 0 表示成功,负数表示失败
|
||
int rc = m_percont->ReadHeaders();
|
||
|
||
#ifdef __linux__
|
||
printf("[PQDIF] ReadHeaders rc=%d\n", rc);
|
||
#endif
|
||
|
||
return (rc == 0);
|
||
}
|
||
|
||
bool CPQDIF::Close()
|
||
{
|
||
// AFX_MANAGE_STATE(AfxGetStaticModuleState())
|
||
|
||
return New();
|
||
}
|
||
|
||
bool CPQDIF::New()
|
||
{
|
||
// AFX_MANAGE_STATE(AfxGetStaticModuleState())
|
||
bool ret = false;
|
||
// Destroy & re-create
|
||
if (m_percont)
|
||
delete m_percont;
|
||
|
||
m_percont = (CPQDIF_PC_FlatFile*)theFactory.NewPersistController(PFPC_FlatFile);
|
||
|
||
if (m_percont)
|
||
ret = true;
|
||
else
|
||
ret = false;
|
||
|
||
return ret;
|
||
}
|
||
|
||
long CPQDIF::RecordGetCount()
|
||
{
|
||
// AFX_MANAGE_STATE(AfxGetStaticModuleState())
|
||
|
||
return (long)m_percont->GetRecordCount();
|
||
|
||
}
|
||
|
||
|
||
bool CPQDIF::RecordGetInfo
|
||
(
|
||
long index,
|
||
GUID* tagRecordType,
|
||
string& nameRecordType
|
||
)
|
||
{
|
||
// AFX_MANAGE_STATE(AfxGetStaticModuleState())
|
||
|
||
bool status = false;
|
||
|
||
CPQDIFRecord* prec;
|
||
GUID tagRecord;
|
||
string nameTag;
|
||
|
||
try
|
||
{
|
||
prec = m_percont->GetRecord(index);
|
||
if (prec)
|
||
{
|
||
//ASSERT_VALID(prec);
|
||
|
||
// Get header info
|
||
prec->HeaderGetTag(tagRecord);
|
||
|
||
// Return the data...
|
||
// The GUID itself
|
||
*tagRecordType = tagRecord;
|
||
|
||
// The GUID name
|
||
nameTag = theInfo.GetNameOfTag(tagRecord);
|
||
nameRecordType = nameTag;
|
||
|
||
|
||
status = true;
|
||
}
|
||
}
|
||
// catch( ... )
|
||
catch (...)
|
||
{
|
||
// // e->Delete();
|
||
status = false;
|
||
}
|
||
|
||
return status;
|
||
}
|
||
|
||
bool CPQDIF::RecordRequestRecord(long index, long* pRecord)
|
||
{
|
||
if (pRecord == nullptr)
|
||
return false;
|
||
|
||
bool status = false;
|
||
try
|
||
{
|
||
CPQDIFRecord* prec = m_percont->GetRecordFull(index);
|
||
if (prec)
|
||
{
|
||
*pRecord = (long)prec;
|
||
status = true;
|
||
}
|
||
}
|
||
catch (...)
|
||
{
|
||
status = false;
|
||
}
|
||
return status;
|
||
}
|
||
|
||
|
||
bool CPQDIF::RecordRequestObservation(long index, long* pRecordObserv)
|
||
{
|
||
|
||
bool status = false;
|
||
CPQDIFRecord* precBase;
|
||
CPQDIFRecord* precCurrent = NULL;
|
||
CPQDIFRecord* precDS = NULL;
|
||
CPQDIFRecord* precSett = NULL;
|
||
CPQDIF_R_Observation* pobs = NULL;
|
||
|
||
GUID tagRecord;
|
||
long idxRec;
|
||
|
||
try
|
||
{
|
||
// Find the observation and associated data source
|
||
precBase = m_percont->GetRecordFull(index);
|
||
if (precBase)
|
||
{
|
||
// Is this an observation?
|
||
precBase->HeaderGetTag(tagRecord);
|
||
if (PQDIF_IsEqualGUID(tagRecord, tagRecObservation))
|
||
{
|
||
// Find its data source...
|
||
// Search backward through the record list.
|
||
for (idxRec = index - 1; idxRec >= 0; idxRec--)
|
||
{
|
||
|
||
// Are we still looking for the DS?
|
||
if (!precDS)
|
||
{
|
||
precCurrent = m_percont->GetRecord(idxRec);
|
||
precCurrent->HeaderGetTag(tagRecord);
|
||
if (PQDIF_IsEqualGUID(tagRecord, tagRecDataSource))
|
||
{
|
||
// Found it!
|
||
precDS = m_percont->GetRecordFull(idxRec);
|
||
status = true;
|
||
// We're cool even if we just find this one. We should break at this point,
|
||
// because we won't find any valid settings records *before* it!
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Are we still looking for the settings?
|
||
if (!precSett)
|
||
{
|
||
precCurrent = m_percont->GetRecord(idxRec);
|
||
precCurrent->HeaderGetTag(tagRecord);
|
||
if (PQDIF_IsEqualGUID(tagRecord, tagRecMonitorSettings))
|
||
{
|
||
// Found it!
|
||
precSett = m_percont->GetRecordFull(idxRec);
|
||
// precSett is not required, so we don't change
|
||
// the value of status.
|
||
}
|
||
}
|
||
} // for( records )
|
||
}
|
||
} // if( found obs record )
|
||
|
||
if (status && precBase && precDS)
|
||
{
|
||
pobs = theFactory.NewObservationWrapper2(precBase, precDS, precSett);
|
||
if (pobs)
|
||
{
|
||
*pRecordObserv = (long)pobs;
|
||
status = true;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (precBase)
|
||
{
|
||
pobs = theFactory.NewObservationWrapper2(precBase, precDS, precSett);
|
||
if (pobs)
|
||
{
|
||
*pRecordObserv = (long)pobs;
|
||
status = true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (...)
|
||
{
|
||
// e->Delete();
|
||
status = false;
|
||
}
|
||
|
||
return status;
|
||
}
|
||
|
||
|
||
bool CPQDIF::ObservationGetInfo(long pRecordObserv, DATE& timeStart, string& name, long& countChannels)
|
||
{
|
||
// AFX_MANAGE_STATE(AfxGetStaticModuleState())
|
||
|
||
bool status = false;
|
||
CPQDIF_R_Observation* pobs;
|
||
TIMESTAMPPQDIF timeStartLocal;
|
||
TIMESTAMPPQDIF timeCreateLocal;
|
||
// string nameLocal;
|
||
string nameLocal;
|
||
|
||
countChannels = 0;
|
||
timeStart = -1;
|
||
try
|
||
{
|
||
pobs = ValidateObservation(pRecordObserv);
|
||
if (pobs)
|
||
{
|
||
// Get channel count
|
||
countChannels = pobs->GetCountChannels();
|
||
|
||
// Get time & name
|
||
status = pobs->GetInfo(timeStartLocal, timeCreateLocal, nameLocal);
|
||
|
||
// Transfer info over
|
||
if (status)
|
||
{
|
||
status = SetDateFromTimeStamp(timeStart, timeStartLocal);
|
||
//status = theSupport.SetDateFromTimeStamp( *timeCreate, timeCreateLocal );
|
||
|
||
name = nameLocal;
|
||
}
|
||
|
||
}
|
||
|
||
|
||
}
|
||
catch (...)
|
||
{
|
||
// e->Delete();
|
||
status = false;
|
||
}
|
||
|
||
|
||
return status;
|
||
}
|
||
|
||
bool CPQDIF::ObservationGetTriggerInfo(long pRecordObserv, long* idTriggerMethod, DATE* timeTriggered)
|
||
{
|
||
// AFX_MANAGE_STATE(AfxGetStaticModuleState())
|
||
|
||
bool status = false;
|
||
CPQDIF_R_Observation* pobs;
|
||
|
||
UINT4 idTriggerMethodLocal;
|
||
CPQDIF_E_Vector* pvectTriggerChanIdx = NULL;
|
||
TIMESTAMPPQDIF timeTriggeredLocal;
|
||
|
||
*idTriggerMethod = -1;
|
||
try
|
||
{
|
||
pobs = ValidateObservation(pRecordObserv);
|
||
if (pobs)
|
||
{
|
||
status = pobs->GetTriggerInfo(idTriggerMethodLocal, &pvectTriggerChanIdx, timeTriggeredLocal);
|
||
if (status)
|
||
{
|
||
status = SetDateFromTimeStamp(*timeTriggered, timeTriggeredLocal);
|
||
}
|
||
|
||
// Copy this one anyway...
|
||
*idTriggerMethod = (long)idTriggerMethodLocal;
|
||
}
|
||
|
||
|
||
}
|
||
catch (...)
|
||
{
|
||
// e->Delete();
|
||
status = false;
|
||
}
|
||
|
||
return status;
|
||
}
|
||
|
||
bool CPQDIF::ObservationGetChannelInfo(long pRecordObserv, long idxChannel, string& name, long* countSeries)
|
||
{
|
||
// AFX_MANAGE_STATE(AfxGetStaticModuleState())
|
||
|
||
bool status = false;
|
||
CPQDIF_R_Observation* pobs;
|
||
|
||
string nameLocal;
|
||
UINT4 idPhaseLocal;
|
||
GUID idQuantityTypeLocal;
|
||
UINT4 idQuantityMeasuredLocal;
|
||
|
||
try
|
||
{
|
||
pobs = ValidateObservation(pRecordObserv);
|
||
if (pobs)
|
||
{
|
||
// Make sure we're in the right range.
|
||
if (idxChannel >= 0 && idxChannel < pobs->GetCountChannels())
|
||
{
|
||
*countSeries = pobs->GetCountSeries(idxChannel);
|
||
|
||
// Get full channel info
|
||
status = pobs->GetChannelInfo(idxChannel, nameLocal, idPhaseLocal, idQuantityTypeLocal, idQuantityMeasuredLocal);
|
||
if (status)
|
||
{
|
||
name = nameLocal;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
catch (...)
|
||
{
|
||
// e->Delete();
|
||
status = false;
|
||
}
|
||
|
||
|
||
return status;
|
||
}
|
||
|
||
bool CPQDIF::ObservationGetSeriesInfo3(long pRecordObserv, long idxChannel, long idxSeries, long* idQuantityUnits, GUID* idQuantityCharacteristic, GUID* idValueType)
|
||
{
|
||
bool status = false;
|
||
CPQDIF_R_Observation* pobs;
|
||
|
||
UINT4 idQuantityUnitsLocal;
|
||
GUID idValueTypeLocal;
|
||
GUID idQuantityCharacteristicLocal;
|
||
|
||
try
|
||
{
|
||
pobs = ValidateObservation(pRecordObserv);
|
||
if (pobs)
|
||
{
|
||
status = pobs->GetSeriesInfo(idxChannel, idxSeries, idQuantityUnitsLocal, idQuantityCharacteristicLocal, idValueTypeLocal);
|
||
if (status)
|
||
{
|
||
// Translate information
|
||
*idQuantityUnits = (long)idQuantityUnitsLocal;
|
||
*idValueType = idValueTypeLocal;
|
||
*idQuantityCharacteristic = idQuantityCharacteristicLocal;
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
catch (...)
|
||
{
|
||
// e->Delete();
|
||
status = false;
|
||
}
|
||
|
||
return status;
|
||
}
|
||
|
||
//注意需要清理double* ,因为是内部动态开辟了内存,使用完需要释放
|
||
bool CPQDIF::ObservationGetSeriesData(long pRecordObserv, long idxChannel, long idxSeries, double** values, long* varCount)
|
||
{
|
||
// AFX_MANAGE_STATE(AfxGetStaticModuleState())
|
||
|
||
bool status = false;
|
||
CPQDIF_R_Observation* pobs;
|
||
double* pvalues;
|
||
long countPoints;
|
||
|
||
try
|
||
{
|
||
pobs = ValidateObservation(pRecordObserv);
|
||
if (pobs)
|
||
{
|
||
pvalues = pobs->NewResolvedSeries(idxChannel, idxSeries, countPoints);
|
||
if (pvalues)
|
||
{
|
||
*values = pvalues;
|
||
status = true;
|
||
*varCount = countPoints;
|
||
//delete[] pvalues;
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
catch (...)
|
||
{
|
||
// e->Delete();
|
||
status = false;
|
||
}
|
||
|
||
return status;
|
||
}
|
||
|
||
bool CPQDIF::ObservationGetChannelFreq(long pRecObs, long idxChannel, double* freq)
|
||
{
|
||
bool status = false;
|
||
|
||
CPQDIF_R_Observation* pobs;
|
||
|
||
try
|
||
{
|
||
pobs = ValidateObservation(pRecObs);
|
||
if (pobs)
|
||
{
|
||
CPQDIF_E_Collection* pcol = pobs->GetOneChannel(idxChannel);
|
||
|
||
if (pcol)
|
||
{
|
||
CPQDIF_E_Scalar* psc = pobs->FindScalarInCollection(pcol, tagChannelFrequency);
|
||
if (psc)
|
||
{
|
||
double val;
|
||
psc->GetValueREAL8(val);
|
||
if (freq)
|
||
{
|
||
*freq = val;
|
||
status = true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (...)
|
||
{
|
||
// e->Delete();
|
||
status = false;
|
||
}
|
||
|
||
return status;
|
||
}
|
||
|
||
bool CPQDIF::ObservationGetChannelGroupID(long pRecObs, long idxChannel, int* GroupID)
|
||
{
|
||
|
||
bool status = false;
|
||
|
||
CPQDIF_R_Observation* pobs;
|
||
|
||
try
|
||
{
|
||
pobs = ValidateObservation(pRecObs);
|
||
if (pobs)
|
||
{
|
||
CPQDIF_E_Collection* pcol = pobs->GetOneChannel(idxChannel);
|
||
|
||
if (pcol)
|
||
{
|
||
CPQDIF_E_Scalar* psc = pobs->FindScalarInCollection(pcol, tagChannelGroupID);
|
||
if (psc)
|
||
{
|
||
INT2 val = 0;
|
||
bool bOk = psc->GetValueINT2(val);
|
||
if (bOk == true)
|
||
{
|
||
if (GroupID)
|
||
{
|
||
*GroupID = val;
|
||
status = true;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
UINT2 val = 0;
|
||
psc->GetValueUINT2(val);
|
||
if (GroupID)
|
||
{
|
||
*GroupID = val;
|
||
status = true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (...)
|
||
{
|
||
// e->Delete();
|
||
status = false;
|
||
}
|
||
|
||
|
||
return status;
|
||
}
|
||
|
||
|
||
bool CPQDIF::ObservationGetSeriesPhasicType(long pRecordObserv, long idxChannel, long idxSeries, long* valuetypes)
|
||
{
|
||
|
||
bool status = false;
|
||
CPQDIF_R_Observation* pobs;
|
||
|
||
try
|
||
{
|
||
pobs = ValidateObservation(pRecordObserv);
|
||
if (pobs)
|
||
{
|
||
long lvalue = 0;
|
||
status = pobs->GetSeriesBaseType(idxChannel, idxSeries, lvalue);
|
||
if (status)
|
||
*valuetypes = lvalue;
|
||
|
||
}
|
||
|
||
|
||
}
|
||
catch (...)
|
||
{
|
||
// e->Delete();
|
||
status = false;
|
||
}
|
||
|
||
return status;
|
||
}
|
||
|
||
|
||
bool CPQDIF::ObservationGetSeriesScale(long pRecObs, long idxChannel, long idxSeries, double* scale, double* offset)
|
||
{
|
||
// AFX_MANAGE_STATE(AfxGetStaticModuleState())
|
||
|
||
bool status = false;
|
||
|
||
CPQDIF_R_Observation* pobs;
|
||
|
||
try
|
||
{
|
||
pobs = ValidateObservation(pRecObs);
|
||
if (pobs)
|
||
{
|
||
status = pobs->GetSeriesScale(idxChannel, idxSeries, *scale, *offset);
|
||
}
|
||
}
|
||
catch (...)
|
||
{
|
||
// e->Delete();
|
||
status = false;
|
||
}
|
||
|
||
|
||
return status;
|
||
}
|
||
|
||
|
||
bool CPQDIF::RecordReleaseObservation(long pRecordObserv)
|
||
{
|
||
// AFX_MANAGE_STATE(AfxGetStaticModuleState())
|
||
|
||
bool status = false;
|
||
CPQDIF_R_Observation* pobs;
|
||
|
||
pobs = ValidateObservation(pRecordObserv);
|
||
if (pobs)
|
||
{
|
||
delete pobs;
|
||
status = true;
|
||
}
|
||
|
||
return status;
|
||
}
|
||
//protected 函数
|
||
|
||
bool CPQDIF::SetDateFromTimeStamp(DATE& date, const TIMESTAMPPQDIF& ts)
|
||
{
|
||
date = (double)ts.day
|
||
+ ((double)ts.sec / (double)SECONDS_PER_DAY);
|
||
|
||
return true;
|
||
}
|
||
|
||
CPQDIF_Element* CPQDIF::ValidateElement(long pElement)
|
||
{
|
||
// AFX_MANAGE_STATE(AfxGetStaticModuleState())
|
||
|
||
CPQDIF_Element* pel;
|
||
|
||
pel = (CPQDIF_Element*)pElement;
|
||
//ASSERT_VALID(pel);
|
||
|
||
return pel;
|
||
}
|
||
|
||
|
||
CPQDIF_E_Collection* CPQDIF::ValidateCollection(long pElement)
|
||
{
|
||
// AFX_MANAGE_STATE(AfxGetStaticModuleState())
|
||
|
||
CPQDIF_Element* pel;
|
||
CPQDIF_E_Collection* pcoll = NULL;
|
||
|
||
pel = (CPQDIF_Element*)pElement;
|
||
//ASSERT_VALID(pel);
|
||
if (pel)
|
||
{
|
||
if (pel->GetElementType() == ID_ELEMENT_TYPE_COLLECTION)
|
||
{
|
||
pcoll = (CPQDIF_E_Collection*)pel;
|
||
//ASSERT_VALID(pcoll);
|
||
}
|
||
}
|
||
|
||
return pcoll;
|
||
}
|
||
|
||
|
||
// Validates a scalar handle and returns the object pointer.
|
||
// For internal use.
|
||
//
|
||
// Returns
|
||
// -------
|
||
// Valid object pointer The object is valid and of the correct type
|
||
// NULL The object is invalid or has an incorrect type
|
||
//
|
||
CPQDIF_E_Scalar* CPQDIF::ValidateScalar(long pElement)
|
||
{
|
||
// AFX_MANAGE_STATE(AfxGetStaticModuleState())
|
||
|
||
CPQDIF_Element* pel;
|
||
CPQDIF_E_Scalar* pscalar = NULL;
|
||
|
||
pel = (CPQDIF_Element*)pElement;
|
||
//ASSERT_VALID(pel);
|
||
if (pel)
|
||
{
|
||
if (pel->GetElementType() == ID_ELEMENT_TYPE_SCALAR)
|
||
{
|
||
pscalar = (CPQDIF_E_Scalar*)pel;
|
||
//ASSERT_VALID(pscalar);
|
||
}
|
||
}
|
||
|
||
return pscalar;
|
||
}
|
||
|
||
|
||
// Validates a vector handle and returns the object pointer.
|
||
// For internal use.
|
||
//
|
||
// Returns
|
||
// -------
|
||
// Valid object pointer The object is valid and of the correct type
|
||
// NULL The object is invalid or has an incorrect type
|
||
//
|
||
CPQDIF_E_Vector* CPQDIF::ValidateVector(long pElement)
|
||
{
|
||
// AFX_MANAGE_STATE(AfxGetStaticModuleState())
|
||
|
||
CPQDIF_Element* pel;
|
||
CPQDIF_E_Vector* pvector = NULL;
|
||
|
||
pel = (CPQDIF_Element*)pElement;
|
||
//ASSERT_VALID(pel);
|
||
if (pel)
|
||
{
|
||
if (pel->GetElementType() == ID_ELEMENT_TYPE_VECTOR)
|
||
{
|
||
pvector = (CPQDIF_E_Vector*)pel;
|
||
//ASSERT_VALID(pvector);
|
||
}
|
||
}
|
||
|
||
return pvector;
|
||
}
|
||
|
||
|
||
// Validates a observation record handle and returns the object pointer.
|
||
// For internal use.
|
||
//
|
||
// Returns
|
||
// -------
|
||
// Valid object pointer The object is valid and of the correct type
|
||
// NULL The object is invalid or has an incorrect type
|
||
//
|
||
CPQDIF_R_Observation* CPQDIF::ValidateObservation(long pRecObserv)
|
||
{
|
||
// AFX_MANAGE_STATE(AfxGetStaticModuleState())
|
||
|
||
CPQDIFRecord* prec;
|
||
CPQDIF_R_Observation* pobs = NULL;
|
||
GUID tagThisRecord;
|
||
|
||
prec = (CPQDIFRecord*)pRecObserv;
|
||
//ASSERT_VALID(prec);
|
||
if (prec)
|
||
{
|
||
prec->HeaderGetTag(tagThisRecord);
|
||
if (PQDIF_IsEqualGUID(tagThisRecord, tagRecObservation))
|
||
{
|
||
pobs = (CPQDIF_R_Observation*)prec;
|
||
//ASSERT_VALID(pobs);
|
||
}
|
||
}
|
||
|
||
return pobs;
|
||
}
|
||
|
||
void testjson()
|
||
{
|
||
//{ "emspq1":[{ "type":1,"min":"{str}" },{ "type":2,"min":"{str2}" }],"emspq2":[{ "type":3,"min":"{str3}" },{ "type":4,"min":"{str4}" }] }
|
||
// 创建根对象
|
||
cJSON* root = cJSON_CreateObject();
|
||
|
||
// 创建emspq1数组
|
||
cJSON* emspq1_array = cJSON_CreateArray();
|
||
cJSON_AddItemToObject(root, "emspq1", emspq1_array);
|
||
|
||
// 向emspq1数组中添加对象
|
||
cJSON* emspq1_obj1 = cJSON_CreateObject();
|
||
cJSON_AddNumberToObject(emspq1_obj1, "type", 1);
|
||
cJSON_AddStringToObject(emspq1_obj1, "min", "{str}");
|
||
cJSON_AddItemToArray(emspq1_array, emspq1_obj1);
|
||
|
||
cJSON* emspq1_obj2 = cJSON_CreateObject();
|
||
cJSON_AddNumberToObject(emspq1_obj2, "type", 2);
|
||
cJSON_AddStringToObject(emspq1_obj2, "min", "{str2}");
|
||
cJSON_AddItemToArray(emspq1_array, emspq1_obj2);
|
||
|
||
// 创建emspq2数组
|
||
cJSON* emspq2_array = cJSON_CreateArray();
|
||
cJSON_AddItemToObject(root, "emspq2", emspq2_array);
|
||
|
||
// 向emspq2数组中添加对象
|
||
cJSON* emspq2_obj1 = cJSON_CreateObject();
|
||
cJSON_AddNumberToObject(emspq2_obj1, "type", 3);
|
||
cJSON_AddStringToObject(emspq2_obj1, "min", "{str3}");
|
||
cJSON_AddItemToArray(emspq2_array, emspq2_obj1);
|
||
|
||
cJSON* emspq2_obj2 = cJSON_CreateObject();
|
||
cJSON_AddNumberToObject(emspq2_obj2, "type", 4);
|
||
cJSON_AddStringToObject(emspq2_obj2, "min", "{str4}");
|
||
cJSON_AddItemToArray(emspq2_array, emspq2_obj2);
|
||
|
||
// 序列化JSON对象为字符串
|
||
char* json_string = cJSON_Print(root);
|
||
printf("%s\n", json_string);
|
||
|
||
// 释放内存
|
||
free(json_string); // 释放 JSON 字符串占用的内存
|
||
cJSON_Delete(root); // 释放 cJSON 对象占用的内存
|
||
|
||
printf("testjson \n");
|
||
|
||
|
||
}
|
||
|
||
char* CDeal::AssJson(char* Id) //组装json结构
|
||
{
|
||
// 创建根对象
|
||
cJSON* root = cJSON_CreateObject();
|
||
|
||
for (std::list<CTable*>::iterator tableIt = DataTableList.begin(); tableIt != DataTableList.end(); ++tableIt) {
|
||
CTable* table = *tableIt;
|
||
//printf("TableName = %s || table->DateSeqList siez = %d\n", table->TableName.c_str(), table->DateSeqList.size());
|
||
// 创建emspq1数组
|
||
cJSON* emspq1_array = cJSON_CreateArray();
|
||
cJSON_AddItemToObject(root, table->TableName.c_str(), emspq1_array);
|
||
|
||
// 遍历相别列表
|
||
for (std::list<CSeq*>::iterator seqIt = table->DateSeqList.begin(); seqIt != table->DateSeqList.end(); ++seqIt) {
|
||
CSeq* seq = *seqIt;
|
||
//printf("telemetryType = %s || seq->DateItemList siez = %d\n", seq->telemetryType.c_str(), seq->DateItemList.size());
|
||
|
||
// 向emspq1数组中添加对象
|
||
cJSON* emspq1_obj1 = cJSON_CreateObject();
|
||
cJSON_AddStringToObject(emspq1_obj1, seq->jsonname.c_str(), seq->telemetryType.c_str());
|
||
// 遍历属性列表
|
||
for (std::list<CItem*>::iterator itemIt = seq->DateItemList.begin(); itemIt != seq->DateItemList.end(); ++itemIt) {
|
||
CItem* item = *itemIt;
|
||
//printf("KeyName = %s || DateName = %s\n", item->KeyName.c_str(), item->DateName.c_str());
|
||
|
||
if (item->Type == "Avg")
|
||
{
|
||
std::map< std::string, std::list<double> >::iterator it = AvgData.find(item->DateName);
|
||
if (it != AvgData.end())
|
||
{
|
||
int i = 1;
|
||
if (stringToTimeT(dataDate) != -1) {
|
||
std::map< std::string, int >::iterator it = aggCydeMinList.find(item->DateName);
|
||
if (it != aggCydeMinList.end())
|
||
{
|
||
i = getCurrentGroup(stringToTimeT(dataDate), it->second);
|
||
}
|
||
else
|
||
{
|
||
i = getCurrentGroup(stringToTimeT(dataDate), aggCydeMin);
|
||
}
|
||
}
|
||
bool isFirst = true; // 标记是否是第一个元素
|
||
std::ostringstream count;
|
||
count << "{";
|
||
for (std::list<double>::iterator itm = it->second.begin(); itm != it->second.end(); ++itm) {
|
||
if (!isFirst) {
|
||
// 如果不是第一个元素,输出逗号
|
||
count << ",";
|
||
}
|
||
count << "\"P" << i++ << "\":" << *itm;
|
||
isFirst = false; // 标记已经不是第一个元素了
|
||
}
|
||
count << "}";
|
||
std::string count_str = count.str();
|
||
cJSON_AddStringToObject(emspq1_obj1, item->KeyName.c_str(), count_str.c_str());
|
||
}
|
||
}
|
||
if (item->Type == "Max")
|
||
{
|
||
std::map< std::string, std::list<double> >::iterator it = MaxData.find(item->DateName);
|
||
if (it != MaxData.end())
|
||
{
|
||
int i = 1;
|
||
if (stringToTimeT(dataDate) != -1) {
|
||
std::map< std::string, int >::iterator it = aggCydeMinList.find(item->DateName);
|
||
if (it != aggCydeMinList.end())
|
||
{
|
||
i = getCurrentGroup(stringToTimeT(dataDate), it->second);
|
||
}
|
||
else
|
||
{
|
||
i = getCurrentGroup(stringToTimeT(dataDate), aggCydeMin);
|
||
}
|
||
}
|
||
bool isFirst = true; // 标记是否是第一个元素
|
||
std::ostringstream count;
|
||
count << "{";
|
||
for (std::list<double>::iterator itm = it->second.begin(); itm != it->second.end(); ++itm) {
|
||
if (!isFirst) {
|
||
// 如果不是第一个元素,输出逗号
|
||
count << ",";
|
||
}
|
||
count << "\"P" << i++ << "\":" << *itm;
|
||
isFirst = false; // 标记已经不是第一个元素了
|
||
}
|
||
count << "}";
|
||
std::string count_str = count.str();
|
||
cJSON_AddStringToObject(emspq1_obj1, item->KeyName.c_str(), count_str.c_str());
|
||
}
|
||
}
|
||
if (item->Type == "Min")
|
||
{
|
||
std::map< std::string, std::list<double> >::iterator it = MinData.find(item->DateName);
|
||
if (it != MinData.end())
|
||
{
|
||
int i = 1;
|
||
if (stringToTimeT(dataDate) != -1) {
|
||
std::map< std::string, int >::iterator it = aggCydeMinList.find(item->DateName);
|
||
if (it != aggCydeMinList.end())
|
||
{
|
||
i = getCurrentGroup(stringToTimeT(dataDate), it->second);
|
||
}
|
||
else
|
||
{
|
||
i = getCurrentGroup(stringToTimeT(dataDate), aggCydeMin);
|
||
}
|
||
}
|
||
bool isFirst = true; // 标记是否是第一个元素
|
||
std::ostringstream count;
|
||
count << "{";
|
||
for (std::list<double>::iterator itm = it->second.begin(); itm != it->second.end(); ++itm) {
|
||
if (!isFirst) {
|
||
// 如果不是第一个元素,输出逗号
|
||
count << ",";
|
||
}
|
||
count << "\"P" << i++ << "\":" << *itm;
|
||
isFirst = false; // 标记已经不是第一个元素了
|
||
}
|
||
count << "}";
|
||
std::string count_str = count.str();
|
||
cJSON_AddStringToObject(emspq1_obj1, item->KeyName.c_str(), count_str.c_str());
|
||
}
|
||
}
|
||
if (item->Type == "CP95")
|
||
{
|
||
std::map< std::string, std::list<double> >::iterator it = CP95Data.find(item->DateName);
|
||
if (it != CP95Data.end())
|
||
{
|
||
int i = 1;
|
||
if (stringToTimeT(dataDate) != -1) {
|
||
std::map< std::string, int >::iterator it = aggCydeMinList.find(item->DateName);
|
||
if (it != aggCydeMinList.end())
|
||
{
|
||
i = getCurrentGroup(stringToTimeT(dataDate), it->second);
|
||
}
|
||
else
|
||
{
|
||
i = getCurrentGroup(stringToTimeT(dataDate), aggCydeMin);
|
||
}
|
||
}
|
||
bool isFirst = true; // 标记是否是第一个元素
|
||
std::ostringstream count;
|
||
count << "{";
|
||
for (std::list<double>::iterator itm = it->second.begin(); itm != it->second.end(); ++itm) {
|
||
if (!isFirst) {
|
||
// 如果不是第一个元素,输出逗号
|
||
count << ",";
|
||
}
|
||
count << "\"P" << i++ << "\":" << *itm;
|
||
isFirst = false; // 标记已经不是第一个元素了
|
||
}
|
||
count << "}";
|
||
std::string count_str = count.str();
|
||
cJSON_AddStringToObject(emspq1_obj1, item->KeyName.c_str(), count_str.c_str());
|
||
}
|
||
}
|
||
if (item->Type == "Val")
|
||
{
|
||
std::map< std::string, std::list<double> >::iterator it = ValData.find(item->DateName);
|
||
if (it != ValData.end())
|
||
{
|
||
int i = 1;
|
||
if (stringToTimeT(dataDate) != -1) {
|
||
std::map< std::string, int >::iterator it = aggCydeMinList.find(item->DateName);
|
||
if (it != aggCydeMinList.end())
|
||
{
|
||
i = getCurrentGroup(stringToTimeT(dataDate), it->second);
|
||
}
|
||
else
|
||
{
|
||
i = getCurrentGroup(stringToTimeT(dataDate), aggCydeMin);
|
||
}
|
||
}
|
||
bool isFirst = true; // 标记是否是第一个元素
|
||
std::ostringstream count;
|
||
count << "{";
|
||
for (std::list<double>::iterator itm = it->second.begin(); itm != it->second.end(); ++itm) {
|
||
if (!isFirst) {
|
||
// 如果不是第一个元素,输出逗号
|
||
count << ",";
|
||
}
|
||
count << "\"P" << i++ << "\":" << *itm;
|
||
isFirst = false; // 标记已经不是第一个元素了
|
||
}
|
||
count << "}";
|
||
std::string count_str = count.str();
|
||
cJSON_AddStringToObject(emspq1_obj1, item->KeyName.c_str(), count_str.c_str());
|
||
}
|
||
}
|
||
if (item->Type == "Null")
|
||
{
|
||
if (item->DateName == "monitorId") //填入 ID
|
||
{
|
||
cJSON_AddStringToObject(emspq1_obj1, item->KeyName.c_str(), Id);
|
||
}
|
||
|
||
// 查找子字符串在原始字符串中的位置
|
||
size_t pos = item->DateName.find("-dataDate-pt");
|
||
// 如果找到了子字符串
|
||
if (pos != std::string::npos) {
|
||
cJSON_AddStringToObject(emspq1_obj1, item->KeyName.c_str(), convertToDateOnly(dataDatePT).c_str());
|
||
continue;
|
||
}
|
||
pos = item->DateName.find("-dataDate-all");
|
||
// 如果找到了子字符串
|
||
if (pos != std::string::npos) {
|
||
cJSON_AddStringToObject(emspq1_obj1, item->KeyName.c_str(), convertToDateOnly(dataDate).c_str());
|
||
continue;
|
||
}
|
||
pos = item->DateName.find("-aggCydeMin-pst");
|
||
// 如果找到了子字符串
|
||
if (pos != std::string::npos && ShortFlag == 1) {
|
||
std::ostringstream count;
|
||
count << aggCycleMinShort;
|
||
std::string count_str = count.str();
|
||
cJSON_AddStringToObject(emspq1_obj1, item->KeyName.c_str(), count_str.c_str());
|
||
continue;
|
||
}
|
||
pos = item->DateName.find("-aggCydeMin-plt");
|
||
// 如果找到了子字符串
|
||
if (pos != std::string::npos && LongFlag == 1) {
|
||
std::ostringstream count;
|
||
count << aggCycleMinLong;
|
||
std::string count_str = count.str();
|
||
cJSON_AddStringToObject(emspq1_obj1, item->KeyName.c_str(), count_str.c_str());
|
||
continue;
|
||
}
|
||
pos = item->DateName.find("-aggCydeMin-flu");
|
||
// 如果找到了子字符串
|
||
if (pos != std::string::npos && FluFlag == 1) {
|
||
std::ostringstream count;
|
||
count << fluCydeMin;
|
||
std::string count_str = count.str();
|
||
cJSON_AddStringToObject(emspq1_obj1, item->KeyName.c_str(), count_str.c_str());
|
||
continue;
|
||
}
|
||
pos = item->DateName.find("-aggCydeMin-all");
|
||
// 如果找到了子字符串
|
||
if (pos != std::string::npos) {
|
||
std::ostringstream count;
|
||
count << aggCydeMin;
|
||
std::string count_str = count.str();
|
||
cJSON_AddStringToObject(emspq1_obj1, item->KeyName.c_str(), count_str.c_str());
|
||
continue;
|
||
}
|
||
}
|
||
}
|
||
cJSON_AddItemToArray(emspq1_array, emspq1_obj1);
|
||
}
|
||
}
|
||
|
||
// 序列化JSON对象为字符串
|
||
char* json_string = cJSON_Print(root);
|
||
//printf("%s\n", json_string);
|
||
|
||
// 释放内存
|
||
//free(json_string); // 释放 JSON 字符串占用的内存
|
||
cJSON_Delete(root); // 释放 cJSON 对象占用的内存
|
||
return json_string;
|
||
}
|
||
|
||
bool CDeal::ExtractNumbersBetweenPercent(const std::string& str, int& start, int& end) {
|
||
size_t pos_start = str.find('%');
|
||
if (pos_start == std::string::npos) {
|
||
// 没有找到'%'字符
|
||
return false;
|
||
}
|
||
|
||
size_t pos_end = str.find('%', pos_start + 1);
|
||
if (pos_end == std::string::npos) {
|
||
// 没有找到第二个'%'字符
|
||
return false;
|
||
}
|
||
|
||
std::istringstream iss(str.substr(pos_start + 1, pos_end - pos_start - 1));
|
||
char comma;
|
||
if (!(iss >> start >> comma >> end)) {
|
||
// 无法从字符串流中提取数字
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
void CDeal::CheckDataTableList()
|
||
{
|
||
for (std::list<CTable*>::iterator tableIt = DataTableList.begin(); tableIt != DataTableList.end(); ++tableIt) {
|
||
CTable* table = *tableIt;
|
||
// 遍历相别列表
|
||
for (std::list<CSeq*>::iterator seqIt = table->DateSeqList.begin(); seqIt != table->DateSeqList.end(); ++seqIt) {
|
||
CSeq* seq = *seqIt;
|
||
// 遍历属性列表
|
||
for (std::list<CItem*>::iterator itemIt = seq->DateItemList.begin(); itemIt != seq->DateItemList.end(); ++itemIt) {
|
||
CItem* item = *itemIt;
|
||
if (item->Type == "Null")
|
||
{
|
||
{
|
||
std::string str = item->DateName;
|
||
std::string substr = "-dataDate-pt";
|
||
|
||
// 查找子字符串在原始字符串中的位置
|
||
size_t pos = str.find(substr);
|
||
|
||
// 如果找到了子字符串
|
||
if (pos != std::string::npos) {
|
||
// 从找到的位置开始,删除子字符串长度的字符
|
||
str.erase(pos, substr.length());
|
||
std::map< std::string, std::string >::iterator it = DateData.find(str);
|
||
if (it != DateData.end())
|
||
{
|
||
std::ostringstream count;
|
||
count << it->second;
|
||
std::string count_str = count.str();
|
||
dataDatePT = count_str;
|
||
}
|
||
continue;
|
||
}
|
||
}
|
||
{
|
||
std::string str = item->DateName;
|
||
std::string substr = "-dataDate-all";
|
||
|
||
// 查找子字符串在原始字符串中的位置
|
||
size_t pos = str.find(substr);
|
||
|
||
// 如果找到了子字符串
|
||
if (pos != std::string::npos) {
|
||
// 从找到的位置开始,删除子字符串长度的字符
|
||
str.erase(pos, substr.length());
|
||
std::map< std::string, std::string >::iterator it = DateData.find(str);
|
||
if (it != DateData.end())
|
||
{
|
||
std::ostringstream count;
|
||
count << it->second;
|
||
std::string count_str = count.str();
|
||
dataDate = count_str;
|
||
}
|
||
continue;
|
||
}
|
||
}
|
||
{
|
||
std::string str = item->DateName;
|
||
std::string substr = "-aggCydeMin-pst";
|
||
|
||
// 查找子字符串在原始字符串中的位置
|
||
size_t pos = str.find(substr);
|
||
|
||
// 如果找到了子字符串
|
||
if (pos != std::string::npos) {
|
||
// 从找到的位置开始,删除子字符串长度的字符
|
||
str.erase(pos, substr.length());
|
||
std::map< std::string, std::list<double> >::iterator it = TimeData.find(str);
|
||
if (it != TimeData.end())
|
||
{
|
||
ShortFlag = 1;//配置存在短闪
|
||
// 获取与键相关联的list的引用
|
||
const std::list<double>& list_values = it->second;
|
||
|
||
// 获取list的个数
|
||
std::list<double>::size_type list_size = list_values.size();
|
||
|
||
// 如果list至少有两个元素,取前两个值
|
||
if (list_size >= 2) {
|
||
// 使用迭代器访问第一个元素
|
||
std::list<double>::const_iterator it_first = list_values.begin();
|
||
// 使用迭代器递增访问第二个元素
|
||
std::list<double>::const_iterator it_second = it_first;
|
||
++it_second; // 递增迭代器以指向第二个元素
|
||
|
||
aggCycleMinShort = *it_second - *it_first;
|
||
aggCycleMinShort = aggCycleMinShort / 60;
|
||
}
|
||
aggCydeMinList[str] = aggCycleMinShort;
|
||
}
|
||
continue;
|
||
}
|
||
}
|
||
{
|
||
std::string str = item->DateName;
|
||
std::string substr = "-aggCydeMin-plt";
|
||
|
||
// 查找子字符串在原始字符串中的位置
|
||
size_t pos = str.find(substr);
|
||
|
||
// 如果找到了子字符串
|
||
if (pos != std::string::npos) {
|
||
// 从找到的位置开始,删除子字符串长度的字符
|
||
str.erase(pos, substr.length());
|
||
std::map< std::string, std::list<double> >::iterator it = TimeData.find(str);
|
||
if (it != TimeData.end())
|
||
{
|
||
LongFlag = 1;//配置存在短闪
|
||
// 获取与键相关联的list的引用
|
||
const std::list<double>& list_values = it->second;
|
||
|
||
// 获取list的个数
|
||
std::list<double>::size_type list_size = list_values.size();
|
||
|
||
// 如果list至少有两个元素,取前两个值
|
||
if (list_size >= 2) {
|
||
// 使用迭代器访问第一个元素
|
||
std::list<double>::const_iterator it_first = list_values.begin();
|
||
// 使用迭代器递增访问第二个元素
|
||
std::list<double>::const_iterator it_second = it_first;
|
||
++it_second; // 递增迭代器以指向第二个元素
|
||
|
||
aggCycleMinLong = *it_second - *it_first;
|
||
aggCycleMinLong = aggCycleMinLong / 60;
|
||
}
|
||
aggCydeMinList[str] = aggCycleMinLong;
|
||
}
|
||
continue;
|
||
}
|
||
}
|
||
{
|
||
std::string str = item->DateName;
|
||
std::string substr = "-aggCydeMin-flu";
|
||
|
||
// 查找子字符串在原始字符串中的位置
|
||
size_t pos = str.find(substr);
|
||
|
||
// 如果找到了子字符串
|
||
if (pos != std::string::npos) {
|
||
// 从找到的位置开始,删除子字符串长度的字符
|
||
str.erase(pos, substr.length());
|
||
std::map< std::string, std::list<double> >::iterator it = TimeData.find(str);
|
||
if (it != TimeData.end())
|
||
{
|
||
FluFlag = 1;//配置存在短闪
|
||
// 获取与键相关联的list的引用
|
||
const std::list<double>& list_values = it->second;
|
||
|
||
// 获取list的个数
|
||
std::list<double>::size_type list_size = list_values.size();
|
||
|
||
// 如果list至少有两个元素,取前两个值
|
||
if (list_size >= 2) {
|
||
// 使用迭代器访问第一个元素
|
||
std::list<double>::const_iterator it_first = list_values.begin();
|
||
// 使用迭代器递增访问第二个元素
|
||
std::list<double>::const_iterator it_second = it_first;
|
||
++it_second; // 递增迭代器以指向第二个元素
|
||
|
||
fluCydeMin = *it_second - *it_first;
|
||
fluCydeMin = fluCydeMin / 60;
|
||
}
|
||
aggCydeMinList[str] = fluCydeMin;
|
||
}
|
||
continue;
|
||
}
|
||
}
|
||
{
|
||
std::string str = item->DateName;
|
||
std::string substr = "-aggCydeMin-all";
|
||
|
||
// 查找子字符串在原始字符串中的位置
|
||
size_t pos = str.find(substr);
|
||
|
||
// 如果找到了子字符串
|
||
if (pos != std::string::npos) {
|
||
// 从找到的位置开始,删除子字符串长度的字符
|
||
str.erase(pos, substr.length());
|
||
std::map< std::string, std::list<double> >::iterator it = TimeData.find(str);
|
||
if (it != TimeData.end())
|
||
{
|
||
// 获取与键相关联的list的引用
|
||
const std::list<double>& list_values = it->second;
|
||
|
||
// 获取list的个数
|
||
std::list<double>::size_type list_size = list_values.size();
|
||
|
||
// 如果list至少有两个元素,取前两个值
|
||
if (list_size >= 2) {
|
||
// 使用迭代器访问第一个元素
|
||
std::list<double>::const_iterator it_first = list_values.begin();
|
||
// 使用迭代器递增访问第二个元素
|
||
std::list<double>::const_iterator it_second = it_first;
|
||
++it_second; // 递增迭代器以指向第二个元素
|
||
|
||
aggCydeMin = *it_second - *it_first;
|
||
aggCydeMin = aggCydeMin / 60;
|
||
}
|
||
|
||
}
|
||
continue;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDeal::ResJsonCfg(char* json)
|
||
{
|
||
// 文件路径
|
||
std::ifstream file(json);
|
||
|
||
// 检查文件是否成功打开
|
||
if (!file.is_open()) {
|
||
printf("can not open file:%s \n", json);
|
||
return;
|
||
}
|
||
|
||
// 读取文件内容到字符串
|
||
std::ostringstream ss;
|
||
ss << file.rdbuf();
|
||
std::string json_string = ss.str();
|
||
|
||
//printf("%s \n", json_string.c_str());
|
||
|
||
// 关闭文件
|
||
file.close();
|
||
|
||
cJSON* root = cJSON_Parse(json_string.c_str());
|
||
|
||
if (root == NULL) {
|
||
printf("Error before: [%s]\n", cJSON_GetErrorPtr());
|
||
return;
|
||
}
|
||
|
||
// 遍历JSON数组中的每个对象
|
||
int count = cJSON_GetArraySize(root);
|
||
for (int i = 0; i < count; i++) {
|
||
cJSON* item = cJSON_GetArrayItem(root, i);
|
||
|
||
// 提取"table"字段
|
||
const char* table = cJSON_GetObjectItemCaseSensitive(item, "table")->valuestring;
|
||
CTable* ctable = new CTable(table);
|
||
DataTableList.push_back(ctable);
|
||
//printf("Table: %s\n", ctable->TableName.c_str());
|
||
|
||
// 解析"cfg"字段
|
||
cJSON* cfg = cJSON_GetObjectItemCaseSensitive(item, "cfg");
|
||
// 解析"TELEMETRYTYPE"数组
|
||
cJSON* telemetry_types = cJSON_GetObjectItemCaseSensitive(cfg, "TELEMETRYTYPE");
|
||
int telemetry_count = cJSON_GetArraySize(telemetry_types);
|
||
for (int i = 0; i < telemetry_count; i++) {
|
||
cJSON* telemetry = cJSON_GetArrayItem(telemetry_types, i);
|
||
const char* seq = cJSON_GetObjectItemCaseSensitive(telemetry, "seq")->valuestring;
|
||
const char* key_name = cJSON_GetObjectItemCaseSensitive(telemetry, "KeyName")->valuestring;
|
||
const char* json_name = cJSON_GetObjectItemCaseSensitive(telemetry, "JsonName")->valuestring;
|
||
CSeq* cseq = new CSeq(seq, key_name, json_name);
|
||
ctable->DateSeqList.push_back(cseq);
|
||
//printf(" Telemetry: Seq=%s, KeyName=%s\n", seq, key_name);
|
||
|
||
// 解析"Item"数组(类似地处理其他字段)
|
||
cJSON* items = cJSON_GetObjectItemCaseSensitive(cfg, "Item");
|
||
int item_count = cJSON_GetArraySize(items);
|
||
for (int i = 0; i < item_count; i++) {
|
||
cJSON* item = cJSON_GetArrayItem(items, i);
|
||
const char* key_name = cJSON_GetObjectItemCaseSensitive(item, "KeyName")->valuestring;
|
||
const char* data_name = cJSON_GetObjectItemCaseSensitive(item, "DataName")->valuestring; //const char* data_name = "V HRMS A[%2,25%]"
|
||
const char* type = cJSON_GetObjectItemCaseSensitive(item, "Type")->valuestring;
|
||
std::string str_key_name(key_name); // 将const char*转换为std::string
|
||
std::string str_data_name(data_name); // 将const char*转换为std::string
|
||
size_t pos;
|
||
while ((pos = str_data_name.find('*')) != std::string::npos) {
|
||
str_data_name.replace(pos, 1, seq);
|
||
}
|
||
int start = 0, end = 0;
|
||
if (ExtractNumbersBetweenPercent(str_data_name, start, end))
|
||
{
|
||
//printf(" Item: start=%d, end=%d\n", start,end);
|
||
for (int i = start; i <= end; i++) {
|
||
std::string str_key_name_temp = str_key_name;
|
||
std::string str_data_name_temp = str_data_name;
|
||
std::ostringstream oss;
|
||
oss << "%" << start << "," << end << "%";
|
||
std::string result = oss.str();
|
||
|
||
std::ostringstream count;
|
||
count << i;
|
||
std::string count_str = count.str();
|
||
|
||
size_t pos = str_data_name.find(result);
|
||
if (pos != std::string::npos) {
|
||
str_data_name_temp.replace(pos, result.length(), count_str); // 替换6个字符长度的子串
|
||
//str_key_name_temp.replace(pos, result.length(), count_str);
|
||
}
|
||
pos = str_key_name.find(result);
|
||
if (pos != std::string::npos) {
|
||
//str_data_name_temp.replace(pos, result.length(), count_str); // 替换6个字符长度的子串
|
||
str_key_name_temp.replace(pos, result.length(), count_str);
|
||
}
|
||
|
||
CItem* citem = new CItem(str_key_name_temp.c_str(), str_data_name_temp.c_str(), type);
|
||
cseq->DateItemList.push_back(citem);
|
||
//printf(" Item: KeyName=%s, DataName=%s, Type=%s\n", str_key_name_temp.c_str(), str_data_name_temp.c_str(), type);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
CItem* citem = new CItem(key_name, str_data_name.c_str(), type);
|
||
cseq->DateItemList.push_back(citem);
|
||
//printf(" Item: KeyName=%s, DataName=%s, Type=%s\n", key_name, str_data_name.c_str(), type);
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
// 释放cJSON对象占用的内存
|
||
cJSON_Delete(root);
|
||
}
|
||
|
||
cJSON* CDeal::cJSON_GetObjectItemCaseSensitive(cJSON* object, const char* string) {
|
||
cJSON* c = object->child;
|
||
while (c) {
|
||
if (strcmp(c->string, string) == 0) {
|
||
return c;
|
||
}
|
||
c = c->next;
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
std::string CDeal::convertToDateOnly(const std::string& dateTime) {
|
||
size_t spacePos = dateTime.find(' '); // 寻找空格的位置,以分隔日期和时间
|
||
if (spacePos != std::string::npos) {
|
||
return dateTime.substr(0, spacePos); // 返回从字符串开始到空格之前的子串
|
||
}
|
||
return dateTime; // 如果没有找到空格,返回原字符串(虽然这种情况在这个例子中不太可能发生)
|
||
}
|
||
|
||
int CDeal::getCurrentGroup(const std::time_t& currentTime, int min) {
|
||
// 将time_t转换为tm结构体
|
||
std::tm* localTime = std::localtime(¤tTime);
|
||
|
||
// 计算从午夜开始到当前时间的总分钟数
|
||
int totalMinutes = localTime->tm_hour * 60 + localTime->tm_min;
|
||
|
||
// 每组的分钟数
|
||
const int groupSize = min;
|
||
|
||
// 计算组号
|
||
// 使用总分钟数除以组大小,然后向下取整得到完整的组数
|
||
// 再加上余数不为零时的一组(如果有余数,说明在下一组的开始或中间)
|
||
int groupNumber = totalMinutes / groupSize;
|
||
if (totalMinutes % groupSize != 0) {
|
||
groupNumber++; // 如果有余数,则属于下一组
|
||
}
|
||
groupNumber++;//数据从0开始 下标从1开始 所以下标值+1
|
||
return groupNumber;
|
||
}
|
||
|
||
std::time_t CDeal::stringToTimeT(const std::string& dateTime) {
|
||
std::tm tm{};
|
||
|
||
// strptime is not standard C++ but is available on many systems (POSIX)
|
||
strptime(dateTime.c_str(), "%Y-%m-%d %H:%M:%S", &tm);
|
||
|
||
// Convert tm to time_t
|
||
std::time_t currentTime = std::mktime(&tm);
|
||
if (currentTime == -1) {
|
||
std::cerr << "Error converting string to time_t." << std::endl;
|
||
// Handle the error as needed
|
||
}
|
||
|
||
return currentTime;
|
||
}
|
||
|
||
void CDeal::clear()
|
||
{
|
||
// 清除AvgData,同时释放list<double>中的内存(如果有的话,但通常list<double>不需要手动释放)
|
||
AvgData.clear();
|
||
// 清除MaxData
|
||
MaxData.clear();
|
||
// 清除MinData
|
||
MinData.clear();
|
||
// 清除CP95Data
|
||
CP95Data.clear();
|
||
// 清除ValData
|
||
ValData.clear();
|
||
// 清除TimeData
|
||
TimeData.clear();
|
||
// 清除DateData(这里的value是std::string,它不需要手动释放内存)
|
||
DateData.clear();
|
||
// 清除aggCydeMinList
|
||
aggCydeMinList.clear();
|
||
|
||
// 遍历DataTableList并释放每个CTable对象的内存
|
||
for (std::list<CTable*>::iterator it = DataTableList.begin(); it != DataTableList.end(); ++it) {
|
||
delete* it; // 释放内存
|
||
}
|
||
DataTableList.clear(); // 清除列表中的指针
|
||
}
|
||
|
||
bool CPQDIF::ObservationGetChannelInfoEx(long pRecordObserv, long idxChannel, PqdifChannelInfoEx* out)
|
||
{
|
||
if (out == nullptr)
|
||
return false;
|
||
|
||
bool status = false;
|
||
CPQDIF_R_Observation* pobs = nullptr;
|
||
|
||
try
|
||
{
|
||
pobs = ValidateObservation(pRecordObserv);
|
||
if (pobs)
|
||
{
|
||
if (idxChannel >= 0 && idxChannel < pobs->GetCountChannels())
|
||
{
|
||
std::string nameLocal;
|
||
UINT4 idPhaseLocal = 0;
|
||
GUID idQuantityTypeLocal{};
|
||
UINT4 idQuantityMeasuredLocal = 0;
|
||
|
||
out->countSeries = pobs->GetCountSeries(idxChannel);
|
||
|
||
status = pobs->GetChannelInfo(
|
||
idxChannel,
|
||
nameLocal,
|
||
idPhaseLocal,
|
||
idQuantityTypeLocal,
|
||
idQuantityMeasuredLocal
|
||
);
|
||
|
||
if (status)
|
||
{
|
||
out->name = nameLocal;
|
||
out->phaseId = static_cast<long>(idPhaseLocal);
|
||
out->quantityTypeId = idQuantityTypeLocal;
|
||
out->quantityMeasuredId = static_cast<long>(idQuantityMeasuredLocal);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (...)
|
||
{
|
||
status = false;
|
||
}
|
||
|
||
return status;
|
||
}
|
||
|
||
bool CPQDIF::ObservationGetSeriesInfoEx(long pRecordObserv, long idxChannel, long idxSeries, PqdifSeriesInfoEx* out)
|
||
{
|
||
if (out == nullptr)
|
||
return false;
|
||
|
||
bool status = false;
|
||
CPQDIF_R_Observation* pobs = nullptr;
|
||
|
||
try
|
||
{
|
||
pobs = ValidateObservation(pRecordObserv);
|
||
if (pobs)
|
||
{
|
||
UINT4 idQuantityUnitsLocal = 0;
|
||
GUID idQuantityCharacteristicLocal{};
|
||
GUID idValueTypeLocal{};
|
||
|
||
status = pobs->GetSeriesInfo(
|
||
idxChannel,
|
||
idxSeries,
|
||
idQuantityUnitsLocal,
|
||
idQuantityCharacteristicLocal,
|
||
idValueTypeLocal
|
||
);
|
||
|
||
if (status)
|
||
{
|
||
out->quantityUnitsId = static_cast<long>(idQuantityUnitsLocal);
|
||
out->quantityCharacteristicId = idQuantityCharacteristicLocal;
|
||
out->valueTypeId = idValueTypeLocal;
|
||
|
||
long baseType = -1;
|
||
if (pobs->GetSeriesBaseType(idxChannel, idxSeries, baseType))
|
||
{
|
||
out->seriesBaseType = baseType;
|
||
}
|
||
|
||
double scale = 1.0;
|
||
double offset = 0.0;
|
||
if (pobs->GetSeriesScale(idxChannel, idxSeries, scale, offset))
|
||
{
|
||
out->scale = scale;
|
||
out->offset = offset;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (...)
|
||
{
|
||
status = false;
|
||
}
|
||
|
||
return status;
|
||
} |