Files
front_linux/LFtid1056/pqdif/PQDIF.cpp

1585 lines
40 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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(&currentTime);
// 计算从午夜开始到当前时间的总分钟数
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;
}