Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 

1043 рядки
29 KiB

  1. /*******************************************************************************
  2. * *
  3. * Société de Transports de Montréal. *
  4. * 2012 - 2013 *
  5. * *
  6. * Projet Zones Tests *
  7. * *
  8. * *
  9. * *
  10. *******************************************************************************/
  11. /*
  12. Description:
  13. Cette classe est responsable de la sauvegarde et de l'ouverture des fichiers
  14. log de passage des trains.
  15. */
  16. /* ************************************************************************** */
  17. /* Revision:
  18. ### YYYMMDD JFM
  19. Verision d'origine.
  20. ### YYYYMMDD Description du besoin ou du bug
  21. Description du changement.
  22. */
  23. /* ************************************************************************** */
  24. #include "TrainLogFileMgr.h"
  25. #include <QFile>
  26. #include <QTextStream>
  27. #include "LogMgr.h"
  28. CTrainLogFileMgr CTrainLogFileMgr::mSingleton;
  29. CTrainLogFileMgr::CTrainLogFileMgr()
  30. {
  31. }
  32. //unsigned int CTrainLogFileMgr::SaveTrainLog(QString LogFilePathName, CZT1Log *ZT1Log, QList<CZTDetectionData *> *ZT1DetectionsLog,QString StationName)
  33. unsigned int CTrainLogFileMgr::SaveTrainLog(QString LogFilePathName, CZT1Log *ZT1Log, QVector<CZTDetectionData *> *ZT1DetectionsLog,QString StationName)
  34. {
  35. QFile* BinaryLogFile = new QFile(LogFilePathName);
  36. if(BinaryLogFile)
  37. {
  38. if(BinaryLogFile->open(QIODevice::WriteOnly | QIODevice::Unbuffered) == false)
  39. {
  40. qDebug("Could not create log file : %s",LogFilePathName.toLatin1().data());
  41. delete BinaryLogFile;
  42. return RET_ERROR;
  43. }
  44. }
  45. else
  46. return RET_ERROR;
  47. QDataStream * OutputStream = new QDataStream(BinaryLogFile);
  48. OutputStream->setVersion(QDataStream::Qt_4_8);
  49. quint32 MagicNbr = 0xDEADBEEF;
  50. quint32 NbLogEntry = 0,NbDetections = 0;
  51. quint32 LogType = ZT1_LOG_TYPE;
  52. NbLogEntry = ZT1Log->mZT1LogData.size();
  53. NbDetections = ZT1DetectionsLog->size();
  54. quint32 TrainType = 0;
  55. quint32 NbElements = 0;
  56. quint64 ThreadDataStartTime = 0, ThreadDataEndTime = 0;
  57. qreal MeanSpeed = 0;
  58. QDateTime DateTime;
  59. //Compute some stats
  60. int SpeedSampleCount = 0;
  61. bool TrainTypeFound = false;
  62. unsigned int NbBogie = 0;
  63. bool ThreadStartTimeFound = false, ThreadEndTimeFound = false;
  64. for(unsigned int i = 0; i < NbLogEntry; i++)
  65. {
  66. if(ZT1Log->mZT1LogData.at(i)->mZT1ThreadData != 0)
  67. {
  68. //get the train type
  69. if(!TrainTypeFound)
  70. {
  71. if(ZT1Log->mZT1LogData.at(i)->mZT1ThreadData->mTrainType != TRAIN_TYPE_UNKNOWN)
  72. {
  73. TrainType = ZT1Log->mZT1LogData.at(i)->mZT1ThreadData->mTrainType;
  74. TrainTypeFound = true;
  75. }
  76. }
  77. //Get the rank count for the train
  78. if(ZT1Log->mZT1LogData.at(i)->mZT1ThreadData->mRank > NbBogie)
  79. NbBogie = ZT1Log->mZT1LogData.at(i)->mZT1ThreadData->mBogie;
  80. //Find the time limits
  81. if(ThreadStartTimeFound == false)
  82. {
  83. ThreadStartTimeFound = true;
  84. ThreadDataStartTime = ZT1Log->mZT1LogData.at(i)->mTimestamp;
  85. }
  86. //Compute the mean speed
  87. if(ZT1Log->mZT1LogData.at(i)->mZT1ThreadData->mTrainSpeed != 0)
  88. {
  89. MeanSpeed += ZT1Log->mZT1LogData.at(i)->mZT1ThreadData->mTrainSpeed;
  90. SpeedSampleCount++;
  91. }
  92. }
  93. else
  94. {
  95. //Find the time limits
  96. if(ThreadStartTimeFound == true && ThreadEndTimeFound == false)
  97. {
  98. ThreadEndTimeFound = true;
  99. ThreadDataEndTime = ZT1Log->mZT1LogData.at(i-1)->mTimestamp;
  100. }
  101. }
  102. }
  103. MeanSpeed /= SpeedSampleCount;
  104. NbElements = NbBogie/6;
  105. DateTime = ZT1Log->mZT1LogData.first()->mDateTime;
  106. *OutputStream << MagicNbr << LogType << NbLogEntry << NbDetections;
  107. *OutputStream << StationName;
  108. *OutputStream << ZT1Log->mZT1Flags;
  109. *OutputStream << TrainType << NbElements << ThreadDataStartTime << ThreadDataEndTime << MeanSpeed << DateTime;
  110. //write detections
  111. for(unsigned int i =0; i < NbDetections; i++)
  112. {
  113. *OutputStream << *ZT1DetectionsLog->at(i);
  114. }
  115. //write train passage log
  116. for(unsigned int i = 0; i < NbLogEntry; i++)
  117. {
  118. *OutputStream << *ZT1Log->mZT1LogData.at(i);
  119. }
  120. #ifdef USE_ANALOG_ACQUISITION
  121. //write analog data if present.
  122. if(ZT1Log->mZT1Flags.mAnalogTracePresent == 1)
  123. {
  124. for(unsigned int i = 0; i < NbLogEntry; i++)
  125. {
  126. *OutputStream << ZT1Log->mZT1LogData.at(i)->mAnalogData;
  127. }
  128. }
  129. #endif
  130. BinaryLogFile->close();
  131. delete BinaryLogFile;
  132. delete OutputStream;
  133. return RET_OK;
  134. }
  135. unsigned int CTrainLogFileMgr::SaveTrainLog(QString LogFilePathName, QVector<CZT2LogData *> *ZT2Log, QVector<CZTDetectionData *> *ZT2DetectionsLog, QString StationName)
  136. {
  137. QFile* BinaryLogFile = new QFile(LogFilePathName);
  138. if(BinaryLogFile)
  139. {
  140. if(BinaryLogFile->open(QIODevice::WriteOnly | QIODevice::Unbuffered) == false)
  141. {
  142. qDebug("Could not create log file : %s",LogFilePathName.toLatin1().data());
  143. delete BinaryLogFile;
  144. return RET_ERROR;
  145. }
  146. }
  147. else
  148. return RET_ERROR;
  149. QDataStream * OutputStream = new QDataStream(BinaryLogFile);
  150. OutputStream->setVersion(QDataStream::Qt_4_8);
  151. quint32 MagicNbr = 0xDEADBEEF;
  152. quint32 NbLogEntry,NbDetections;
  153. quint32 LogType = ZT2_LOG_TYPE;
  154. NbLogEntry = ZT2Log->size();
  155. NbDetections = ZT2DetectionsLog->size();
  156. quint32 NbElements = 0;
  157. QDateTime DateTime = ZT2Log->at(0)->mDateTime;
  158. //Get some stats
  159. for(int j = 0; j < ZT2Log->size(); j++)
  160. {
  161. if(ZT2Log->at(j)->mZT2ThreadData != 0)
  162. {
  163. //Get the rank count for the train
  164. if(ZT2Log->at(j)->mZT2ThreadData->mRank > NbElements)
  165. NbElements = ZT2Log->at(j)->mZT2ThreadData->mBogie;
  166. }
  167. }
  168. NbElements /= 6; //6 bogies per element
  169. *OutputStream << MagicNbr << LogType << NbLogEntry << NbDetections;
  170. *OutputStream << StationName;
  171. *OutputStream << NbElements << DateTime;
  172. //write detections
  173. for(unsigned int i =0; i < NbDetections; i++)
  174. {
  175. *OutputStream << *ZT2DetectionsLog->at(i);
  176. }
  177. //write train passage log
  178. for(unsigned int i = 0; i < NbLogEntry; i++)
  179. {
  180. *OutputStream << *ZT2Log->at(i);
  181. }
  182. BinaryLogFile->close();
  183. delete BinaryLogFile;
  184. delete OutputStream;
  185. return RET_OK;
  186. }
  187. //It is the responsibility of the caller to make shure TargetElement is empty
  188. CLogElement* CTrainLogFileMgr::OpenTrainLog(QString LogFilePathName,unsigned int &Retvalue,CLogElement* TargetElement,bool LoadData)
  189. {
  190. // if(!ZT1Log->isEmpty() || !ZT1DetectionsLog->isEmpty())
  191. // return RET_ERROR;
  192. int LogFileVersion;
  193. bool FileProtected = false;
  194. if(QFileInfo(LogFilePathName).suffix() != "bin")
  195. {
  196. Retvalue = RET_ERROR;
  197. return 0;
  198. }
  199. QFile* BinaryLogFile = new QFile(LogFilePathName);
  200. if(BinaryLogFile)
  201. {
  202. if(BinaryLogFile->open(QIODevice::ReadOnly | QIODevice::Unbuffered) == false)
  203. {
  204. Retvalue = RET_ERROR;
  205. delete BinaryLogFile;
  206. return 0;
  207. }
  208. }
  209. else
  210. {
  211. Retvalue = RET_ERROR;
  212. return 0;
  213. }
  214. QDataStream * InputStream = new QDataStream(BinaryLogFile);
  215. InputStream->setVersion(QDataStream::Qt_4_8);
  216. quint32 MagicNbr,NbLogEntry,NbDetections,LogType;
  217. *InputStream >> MagicNbr;
  218. if(MagicNbr == 0xDEADBEEF)
  219. {
  220. LogFileVersion = 1;
  221. FileProtected = false;
  222. }
  223. else if(MagicNbr == 0xDEADBEEF+1)
  224. {
  225. LogFileVersion = 2;
  226. FileProtected = false;
  227. }
  228. else if(MagicNbr == 0xDEADBEEF+2)
  229. {
  230. LogFileVersion = 1;
  231. FileProtected = true;
  232. }
  233. else if(MagicNbr == 0xDEADBEEF+3)
  234. {
  235. LogFileVersion = 2;
  236. FileProtected = true;
  237. }
  238. else if(MagicNbr == 0xDEADBEEF+15)
  239. {
  240. LogFileVersion = 3;
  241. qint32 OutilZTFlags[10];
  242. for(int i = 0; i < 10; i++)
  243. {
  244. *InputStream >> OutilZTFlags[i];
  245. }
  246. if(OutilZTFlags[OUTILZT_FILE_PROTECTED_FLAG] == 1)
  247. {
  248. FileProtected = true;
  249. }
  250. else
  251. {
  252. FileProtected = false;
  253. }
  254. }
  255. else
  256. {
  257. qDebug(qPrintable(QString().sprintf("Fichier de passage invalide (Magic number) %s",qPrintable(LogFilePathName))));
  258. BinaryLogFile->close();
  259. delete BinaryLogFile;
  260. delete InputStream;
  261. Retvalue = RET_ERROR;
  262. return 0;
  263. }
  264. *InputStream >> LogType;
  265. if(LogType == ZT1_LOG_TYPE)
  266. {
  267. CZT1LogElement *PassageLog;
  268. if(TargetElement == 0)
  269. {
  270. PassageLog = new CZT1LogElement();
  271. }
  272. else
  273. {
  274. PassageLog = (CZT1LogElement*)TargetElement; //It is the responsibility of the caller to make shure TargetElement is empty
  275. }
  276. PassageLog->mLogFileName = LogFilePathName;
  277. PassageLog->mFileProtected = FileProtected;
  278. *InputStream >> NbLogEntry;
  279. *InputStream >> NbDetections;
  280. *InputStream >> PassageLog->mStationName;
  281. if(LogFileVersion == 1)
  282. {
  283. *InputStream >> PassageLog->mFlags.mExtPGOffset
  284. >> PassageLog->mFlags.mIntPGOffset
  285. >> PassageLog->mFlags.mPGCalibrationON
  286. >> PassageLog->mFlags.mPGTresholdValue
  287. >> PassageLog->mFlags.mAnalogTracePresent;
  288. PassageLog->mFlags.mTrainCompo1 = 0;
  289. PassageLog->mFlags.mTrainCompo2 = 0;
  290. PassageLog->mFlags.mTrainCompo3 = 0;
  291. PassageLog->mFlags.mModbusTrainType = MODBUS_CC_TRAIN_TYPE_INVALID_NOT_UPDATED;
  292. PassageLog->mFlags.mZT1ITI = ZT_PRIMARY_ITI;
  293. }
  294. else if(LogFileVersion == 2)
  295. {
  296. *InputStream >> PassageLog->mFlags.mExtPGOffset
  297. >> PassageLog->mFlags.mIntPGOffset
  298. >> PassageLog->mFlags.mPGCalibrationON
  299. >> PassageLog->mFlags.mPGTresholdValue
  300. >> PassageLog->mFlags.mAnalogTracePresent
  301. >> PassageLog->mFlags.mIsProblematicPassage;
  302. PassageLog->mFlags.mTrainCompo1 = 0;
  303. PassageLog->mFlags.mTrainCompo2 = 0;
  304. PassageLog->mFlags.mTrainCompo3 = 0;
  305. PassageLog->mFlags.mModbusTrainType = MODBUS_CC_TRAIN_TYPE_INVALID_NOT_UPDATED;
  306. PassageLog->mFlags.mZT1ITI = ZT_PRIMARY_ITI;
  307. }
  308. else if(LogFileVersion == 3)
  309. {
  310. *InputStream >> PassageLog->mFlags;
  311. }
  312. *InputStream >> PassageLog->mTrainType;
  313. *InputStream >> PassageLog->mNbElements;
  314. *InputStream >> PassageLog->mThreadDataStartTime;
  315. *InputStream >> PassageLog->mThreadDataEndTime;
  316. *InputStream >> PassageLog->mMeanSpeed;
  317. *InputStream >> PassageLog->mPassageDateTime;
  318. for(unsigned int i = 0; i < NbDetections; i++)
  319. {
  320. CZTDetectionData *NewDetection = new CZTDetectionData();
  321. *InputStream >> *NewDetection;
  322. PassageLog->mZTDetections.append(NewDetection);
  323. }
  324. if(LoadData == true)
  325. {
  326. for(unsigned int i = 0; i < NbLogEntry; i++)
  327. {
  328. CZT1LogData *NewLogChunk = new CZT1LogData();
  329. *InputStream >> *NewLogChunk;
  330. PassageLog->mZTLogData.append(NewLogChunk);
  331. }
  332. #ifdef USE_ANALOG_ACQUISITION
  333. if(PassageLog->mFlags.mAnalogTracePresent == 1)
  334. {
  335. for(int i = 0; i < PassageLog->mZTLogData.size(); i++)
  336. {
  337. *InputStream >> PassageLog->mZTLogData.at(i)->mAnalogData;
  338. }
  339. }
  340. #endif
  341. }
  342. BinaryLogFile->close();
  343. delete BinaryLogFile;
  344. delete InputStream;
  345. Retvalue = RET_OK;
  346. return (CZT1LogElement*) PassageLog;
  347. }
  348. else if(LogType == ZT2_LOG_TYPE)
  349. {
  350. quint32 NbElements;
  351. QDateTime DateTime;
  352. CZT2LogElement *PassageLog;
  353. if(TargetElement == 0)
  354. {
  355. PassageLog = new CZT2LogElement();
  356. }
  357. else
  358. {
  359. PassageLog = (CZT2LogElement*) TargetElement; //It is the responsibility of the caller to make shure TargetElement is empty
  360. }
  361. *InputStream >> NbLogEntry;
  362. *InputStream >> NbDetections;
  363. *InputStream >> PassageLog->mStationName;
  364. if(LogFileVersion == 2)
  365. {
  366. *InputStream >> PassageLog->mFlags.mIsProblematicPassage;
  367. PassageLog->mFlags.mModbusTrainType = MODBUS_CC_TRAIN_TYPE_INVALID_NOT_UPDATED;
  368. PassageLog->mFlags.mTrainCompo1 = 0;
  369. PassageLog->mFlags.mTrainCompo2 = 0;
  370. PassageLog->mFlags.mTrainCompo3 = 0;
  371. }
  372. else if(LogFileVersion == 3)
  373. {
  374. *InputStream >> PassageLog->mFlags;
  375. }
  376. else
  377. {
  378. PassageLog->mFlags.mIsProblematicPassage = 2;
  379. PassageLog->mFlags.mModbusTrainType = MODBUS_CC_TRAIN_TYPE_INVALID_NOT_UPDATED;
  380. PassageLog->mFlags.mTrainCompo1 = 0;
  381. PassageLog->mFlags.mTrainCompo2 = 0;
  382. PassageLog->mFlags.mTrainCompo3 = 0;
  383. }
  384. *InputStream >> NbElements;
  385. *InputStream >> DateTime;
  386. PassageLog->mNbElements = NbElements;
  387. PassageLog->mLogFileName = LogFilePathName;
  388. PassageLog->mPassageDateTime = DateTime;
  389. PassageLog->mFileProtected = FileProtected;
  390. for(unsigned int i = 0; i < NbDetections; i++)
  391. {
  392. CZTDetectionData *NewDetection = new CZTDetectionData();
  393. *InputStream >> *NewDetection;
  394. PassageLog->mZTDetections.append(NewDetection);
  395. }
  396. if(LoadData == true)
  397. {
  398. for(unsigned int i = 0; i < NbLogEntry; i++)
  399. {
  400. CZT2LogData *NewLogChunk = new CZT2LogData();
  401. *InputStream >> *NewLogChunk;
  402. PassageLog->mZTLogData.append(NewLogChunk);
  403. }
  404. }
  405. BinaryLogFile->close();
  406. delete BinaryLogFile;
  407. delete InputStream;
  408. Retvalue = RET_OK;
  409. return PassageLog;
  410. }
  411. else
  412. {
  413. qDebug("Invalid log type in file %s",LogFilePathName.toLatin1().data());
  414. Retvalue = RET_ERROR;
  415. return 0;
  416. }
  417. }
  418. unsigned int CTrainLogFileMgr::SetTrainLogProtected(bool IsProtected, QString LogFilePathName)
  419. {
  420. QFile* BinaryLogFile = new QFile(LogFilePathName);
  421. if(BinaryLogFile)
  422. {
  423. if(BinaryLogFile->open(QIODevice::ReadWrite | QIODevice::Unbuffered) == false)
  424. {
  425. qDebug("Could not Open log file to set protection : %s",LogFilePathName.toLatin1().data());
  426. delete BinaryLogFile;
  427. return RET_ERROR;
  428. }
  429. }
  430. else
  431. return RET_ERROR;
  432. QDataStream * Stream = new QDataStream(BinaryLogFile);
  433. Stream->setVersion(QDataStream::Qt_4_8);
  434. quint32 MagicNbr;
  435. *Stream >> MagicNbr;
  436. if(IsProtected == true)
  437. {
  438. if(MagicNbr == 0xDEADBEEF + 2 || MagicNbr == 0xDEADBEEF + 3)
  439. {
  440. //file is already protected
  441. }
  442. else if(MagicNbr == 0xDEADBEEF || MagicNbr == 0xDEADBEEF + 1)
  443. {
  444. MagicNbr += 2;
  445. BinaryLogFile->seek(0);
  446. *Stream << MagicNbr;
  447. }
  448. else if(MagicNbr == 0xDEADBEEF + 15)
  449. {
  450. //Use the reserved registers inside the file...
  451. qint32 Flags[10];
  452. for(int i = 0; i < 10; i++)
  453. {
  454. *Stream >> Flags[i];
  455. }
  456. Flags[OUTILZT_FILE_PROTECTED_FLAG] = 1;
  457. BinaryLogFile->seek(0);
  458. *Stream >> MagicNbr; //Dummy read;
  459. for(int i = 0; i < 10; i++)
  460. {
  461. *Stream << Flags[i];
  462. }
  463. }
  464. else
  465. {
  466. //Log File Error
  467. BinaryLogFile->close();
  468. qDebug("Invalid log file magic number to set protection : %s",LogFilePathName.toLatin1().data());
  469. delete BinaryLogFile;
  470. }
  471. }
  472. else
  473. {
  474. if(MagicNbr == 0xDEADBEEF + 2 || MagicNbr == 0xDEADBEEF + 3)
  475. {
  476. //file is already protected
  477. MagicNbr -= 2;
  478. BinaryLogFile->seek(0);
  479. *Stream << MagicNbr;
  480. }
  481. else if(MagicNbr == 0xDEADBEEF || MagicNbr == 0xDEADBEEF + 1)
  482. {
  483. //file is already unprotected
  484. }
  485. else if(MagicNbr == 0xDEADBEEF + 15)
  486. {
  487. //Use the reserved registers inside the file...
  488. qint32 Flags[10];
  489. for(int i = 0; i < 10; i++)
  490. {
  491. *Stream >> Flags[i];
  492. }
  493. Flags[OUTILZT_FILE_PROTECTED_FLAG] = 0;
  494. BinaryLogFile->seek(0);
  495. *Stream >> MagicNbr; //Dummy read;
  496. for(int i = 0; i < 10; i++)
  497. {
  498. *Stream << Flags[i];
  499. }
  500. }
  501. else
  502. {
  503. //Log File Error
  504. BinaryLogFile->close();
  505. qDebug("Invalid log file magic number to set protection : %s",LogFilePathName.toLatin1().data());
  506. delete BinaryLogFile;
  507. }
  508. }
  509. BinaryLogFile->close();
  510. qDebug("Invalid log file magic number to set protection : %s",LogFilePathName.toLatin1().data());
  511. delete BinaryLogFile;
  512. return RET_OK;
  513. }
  514. //unsigned int CTrainLogFileMgr::SaveCSVFile(QString CSVFilePathName, CZT1Log *ZT1Log, QList<CZTDetectionData *> *ZT1DetectionsLog, QString StationName)
  515. unsigned int CTrainLogFileMgr::SaveCSVFile(QString CSVFilePathName, CZT1Log *ZT1Log, QVector<CZTDetectionData *> *ZT1DetectionsLog, QString StationName)
  516. {
  517. return SaveCSVFile(CSVFilePathName, &ZT1Log->mZT1LogData, &ZT1Log->mZT1Flags, ZT1DetectionsLog,StationName);
  518. }
  519. //unsigned int CTrainLogFileMgr::SaveCSVFile(QString CSVFilePathName, QList<CZT1LogData*> *ZT1Log, CZT1FlagsData *ZT1Flags, QList<CZTDetectionData *> *ZT1DetectionsLog, QString StationName)
  520. unsigned int CTrainLogFileMgr::SaveCSVFile(QString CSVFilePathName, QVector<CZT1LogData*> *ZT1Log, CZT1FlagsData *ZT1Flags, QVector<CZTDetectionData *> *ZT1DetectionsLog, QString StationName)
  521. {
  522. QFile CSVFile(CSVFilePathName);
  523. if(!CSVFile.open(QIODevice::QIODevice::WriteOnly|QIODevice::Text|QIODevice::Truncate))
  524. return RET_ERROR;
  525. QTextStream CSVStream(&CSVFile);
  526. CSVStream << "Log de passage du train dans la ZT1\n";
  527. CSVStream << QString::fromUtf8("Station : ") << StationName << "\n";
  528. CSVStream << QString::fromUtf8("Valeur seuil Pneu de guidage : ") << ZT1Flags->mPGTresholdValue << "\n";
  529. CSVStream << QString::fromUtf8("Valeur zérotage PG Extérieur : ") << ZT1Flags->mExtPGOffset << "\n";
  530. CSVStream << QString::fromUtf8("Valeur zérotage PG Intérieur : ") << ZT1Flags->mIntPGOffset << "\n";
  531. if(ZT1Flags->mPGCalibrationON == 1)
  532. {
  533. CSVStream << "Calibration PG en cours lors du passage: OUI\n";
  534. }
  535. else
  536. CSVStream << "Calibration PG en cours lors du passage: NON\n";
  537. CSVStream << QString::fromUtf8("Nombre de déclenchements : ") << ZT1DetectionsLog->size() << "\n";
  538. if(ZT1DetectionsLog->size() > 0)
  539. {
  540. for(int i = 0; i < ZT1DetectionsLog->size(); i++)
  541. {
  542. CSVStream << QString::fromUtf8("Déclenchement ") << i+1 << ": " << ZT1DetectionsLog->at(i)->mTimeStamp << " - " << QString::fromUtf8(CZTData::GetErrorString(ZT1DetectionsLog->at(i)->mDetectionID)) << " au rang " << ZT1DetectionsLog->at(i)->mRank << "\n";
  543. }
  544. }
  545. CSVStream << "\n";
  546. CSVStream << "Date,Heure,Timestamp,CI,CDV Approche,CDV ZT1,S1,S2,FN,PPI,PPE,PG,Vitesse,Bogie,Rang,Laser Ext,Laser Int,Train";
  547. if(ZT1Flags->mAnalogTracePresent == 1)
  548. {
  549. CSVStream << ",4-20mA SDF";
  550. }
  551. CSVStream << "\n";
  552. for(int i = 0; i < ZT1Log->size(); i++)
  553. {
  554. CSVStream << ZT1Log->at(i)->mDateTime.toString("yyyy-MM-dd, hh:mm:ss:zzz") << ",";
  555. CSVStream << ZT1Log->at(i)->mTimestamp << ",";
  556. CSVStream << ZT1Log->at(i)->mCIZT1 << ",";
  557. CSVStream << ZT1Log->at(i)->mCDVApproach_ZT1 << ",";
  558. CSVStream << ZT1Log->at(i)->mCDVARM_ZT1 << ",";
  559. if(ZT1Log->at(i)->mZT1ThreadData != 0)
  560. {
  561. CSVStream << ZT1Log->at(i)->mZT1ThreadData->mS1 << ",";
  562. CSVStream << ZT1Log->at(i)->mZT1ThreadData->mS2 << ",";
  563. CSVStream << ZT1Log->at(i)->mZT1ThreadData->mFN << ",";
  564. CSVStream << ZT1Log->at(i)->mZT1ThreadData->mPInt << ",";
  565. CSVStream << ZT1Log->at(i)->mZT1ThreadData->mPExt << ",";
  566. CSVStream << ZT1Log->at(i)->mZT1ThreadData->mPG << ",";
  567. CSVStream << ZT1Log->at(i)->mZT1ThreadData->mTrainSpeed << ",";
  568. CSVStream << ZT1Log->at(i)->mZT1ThreadData->mBogie << ",";
  569. CSVStream << ZT1Log->at(i)->mZT1ThreadData->mRank << ",";
  570. CSVStream << ZT1Log->at(i)->mZT1ThreadData->mPGExtValue << ",";
  571. CSVStream << ZT1Log->at(i)->mZT1ThreadData->mPGIntValue << ",";
  572. CSVStream << CZTData::GetTrainTypeString(ZT1Log->at(i)->mZT1ThreadData->mTrainType);
  573. }
  574. else
  575. {
  576. CSVStream << "0,0,0,0,0,0,0,0,0,0,0,0";
  577. //CSVStream <<"\n";
  578. }
  579. if(ZT1Flags->mAnalogTracePresent == 1)
  580. {
  581. CSVStream << "," << ZT1Log->at(i)->mAnalogData ;
  582. }
  583. CSVStream << "\n";
  584. }
  585. CSVFile.flush();
  586. CSVFile.close();
  587. return RET_OK;
  588. }
  589. unsigned int CTrainLogFileMgr::SaveCSVFile(QString CSVFilePathName, QVector<CZT2LogData *> *ZT2Log, QVector<CZTDetectionData *> *ZT2DetectionsLog, QString StationName)
  590. //unsigned int CTrainLogFileMgr::SaveCSVFile(QString CSVFilePathName, QVector<CZT2LogData *> *ZT2Log, QVector<CZTDetectionData *> *ZT2DetectionsLog, QString StationName)
  591. {
  592. QFile CSVFile(CSVFilePathName);
  593. if(!CSVFile.open(QIODevice::QIODevice::WriteOnly|QIODevice::Text|QIODevice::Truncate))
  594. return RET_ERROR;
  595. QTextStream CSVStream(&CSVFile);
  596. CSVStream << "Log de passage du train dans la ZT2\n";
  597. CSVStream << QString::fromUtf8("Station : ") << StationName << "\n";
  598. CSVStream << QString::fromUtf8("Nombre de déclenchements : ") << ZT2DetectionsLog->size() << "\n";
  599. if(ZT2DetectionsLog->size() > 0)
  600. {
  601. for(int i = 0; i < ZT2DetectionsLog->size(); i++)
  602. {
  603. CSVStream << QString::fromUtf8("Déclenchement ") << i+1 << ": " << ZT2DetectionsLog->at(i)->mTimeStamp << " - " << QString::fromUtf8(CZTData::GetErrorString(ZT2DetectionsLog->at(i)->mDetectionID)) << " au rang " << ZT2DetectionsLog->at(i)->mRank << "\n";
  604. }
  605. CSVStream << "\n";
  606. }
  607. CSVStream << "Date,Heure,Timestamp,CI,CDV ZT2,S1,PPI,PPE,Bogie,Rang\n";
  608. for(int i = 0; i < ZT2Log->size(); i++)
  609. {
  610. CSVStream << ZT2Log->at(i)->mDateTime.toString("yyyy-MM-dd, hh:mm:ss:zzz") << ",";
  611. CSVStream << ZT2Log->at(i)->mTimestamp << ",";
  612. CSVStream << ZT2Log->at(i)->mCIZT2 << ",";
  613. CSVStream << ZT2Log->at(i)->mCDVARM_ZT2 << ",";
  614. if(ZT2Log->at(i)->mZT2ThreadData != 0)
  615. {
  616. CSVStream << ZT2Log->at(i)->mZT2ThreadData->mS1 << ",";
  617. CSVStream << ZT2Log->at(i)->mZT2ThreadData->mPPInt << ",";
  618. CSVStream << ZT2Log->at(i)->mZT2ThreadData->mPPExt << ",";
  619. CSVStream << ZT2Log->at(i)->mZT2ThreadData->mBogie << ",";
  620. CSVStream << ZT2Log->at(i)->mZT2ThreadData->mRank << ",";
  621. }
  622. else
  623. {
  624. CSVStream << "0,0,0,0,0";
  625. CSVStream <<"\n";
  626. }
  627. }
  628. CSVFile.flush();
  629. CSVFile.close();
  630. return RET_OK;
  631. }
  632. //Cette fonction a été écrite pour des fins de tests et n'est PAS du tout robuste.
  633. //utiliser avec précaution.
  634. unsigned int CTrainLogFileMgr::SaveBINFromCSV(QString CSVFilePathName)
  635. {
  636. QFile CSVFile(CSVFilePathName);
  637. if(!CSVFile.open(QIODevice::ReadOnly|QIODevice::Text))
  638. return RET_ERROR;
  639. QTextStream CSVStream(&CSVFile);
  640. bool IsZT1 = true;
  641. QString Line;
  642. QStringList LineElements;
  643. QString StationName;
  644. Line.clear();
  645. LineElements.clear();
  646. Line = CSVStream.readLine(); //Log de passage du train dans la ZT1
  647. if(Line.contains("ZT1") == true)
  648. {
  649. IsZT1 = true;
  650. }
  651. else if(Line.contains("ZT2") == true)
  652. {
  653. IsZT1 = false;
  654. }
  655. else
  656. {
  657. //invalid file
  658. CSVFile.close();
  659. return RET_ERROR;
  660. }
  661. Line = CSVStream.readLine(); //Station : Snowdon
  662. LineElements = Line.split(":");
  663. if(LineElements.isEmpty())
  664. {
  665. CSVFile.close();
  666. return RET_ERROR;
  667. }
  668. StationName = LineElements.at(1);
  669. Line.clear();
  670. if(IsZT1 == true)
  671. {
  672. CZT1Log *ZT1LOG = new CZT1Log();
  673. Line = CSVStream.readLine(); //Valeur seuil Pneu de guidage : 15625
  674. LineElements = Line.split(":");
  675. if(LineElements.isEmpty())
  676. {
  677. CSVFile.close();
  678. return RET_ERROR;
  679. }
  680. ZT1LOG->mZT1Flags.mPGTresholdValue = LineElements.at(1).toInt();
  681. Line.clear();
  682. Line = CSVStream.readLine(); //Valeur zérotage PG Extérieur : 128457
  683. LineElements = Line.split(":");
  684. if(LineElements.isEmpty())
  685. {
  686. CSVFile.close();
  687. return RET_ERROR;
  688. }
  689. ZT1LOG->mZT1Flags.mExtPGOffset = LineElements.at(1).toInt();
  690. Line.clear();
  691. Line = CSVStream.readLine(); //Valeur zérotage PG Intérieur : 1300637
  692. LineElements = Line.split(":");
  693. if(LineElements.isEmpty())
  694. {
  695. CSVFile.close();
  696. return RET_ERROR;
  697. }
  698. ZT1LOG->mZT1Flags.mIntPGOffset = LineElements.at(1).toInt();
  699. Line.clear();
  700. Line = CSVStream.readLine(); //Calibration PG en cours lors du passage: NON
  701. if(Line.contains("OUI") == true)
  702. {
  703. ZT1LOG->mZT1Flags.mPGCalibrationON = true;
  704. }
  705. else if(Line.contains("NON") == true)
  706. {
  707. ZT1LOG->mZT1Flags.mPGCalibrationON = false;
  708. }
  709. else
  710. {
  711. CSVFile.close();
  712. return RET_ERROR;
  713. }
  714. Line.clear();
  715. int NbDetections;
  716. Line = CSVStream.readLine(); //Nombre de déclenchements : 12
  717. LineElements = Line.split(":");
  718. if(LineElements.isEmpty())
  719. {
  720. CSVFile.close();
  721. return RET_ERROR;
  722. }
  723. NbDetections = LineElements.at(1).toInt();
  724. Line.clear();
  725. //Ignore detections...
  726. for(int i = 0; i < NbDetections; i++)
  727. {
  728. Line = CSVStream.readLine();
  729. Line.clear();
  730. }
  731. //Skip the empty line after the detections.
  732. Line = CSVStream.readLine();
  733. Line.clear();
  734. //Skip the table header
  735. Line = CSVStream.readLine();
  736. Line.clear();
  737. quint32 LastS1 = 0, LastS2 = 0, LastFN = 0;
  738. quint32 S1Count = 0;
  739. quint32 S2Count = 0;
  740. quint32 FNCount = 0;
  741. while(CSVStream.atEnd() == false)
  742. {
  743. Line.clear();
  744. LineElements.clear();
  745. Line = CSVStream.readLine(); //Date Heure Timestamp CI CDV Approche CDV ZT1 S1 S2 FN PPI PPE PG Vitesse Bogie Rang Sonde Ext Sonde Int Train
  746. LineElements = Line.split(",");
  747. if(LineElements.count() != 18)
  748. {
  749. CSVFile.close();
  750. return RET_ERROR;
  751. }
  752. QDate date = QDate::fromString(LineElements.at(0),"yyyy-MM-dd");
  753. if(date.isValid() == false)
  754. {
  755. CSVFile.close();
  756. return RET_ERROR;
  757. }
  758. QTime time = QTime::fromString(LineElements.at(1).trimmed(),"hh:mm:ss:zzz");
  759. if(time.isValid() == false)
  760. {
  761. CSVFile.close();
  762. return RET_ERROR;
  763. }
  764. qint64 timestamp = LineElements.at(2).toLongLong();
  765. quint32 CIZT1 = LineElements.at(3).toUInt();
  766. quint32 CDVApproach_ZT1 = LineElements.at(4).toUInt();
  767. quint32 CDVARM_ZT1 = LineElements.at(5).toUInt();
  768. CZT1LogData *LogData;
  769. CZT1ThreadData *ThreadData;
  770. if(LineElements.at(17) == "0") //Check if ThreadData is valid
  771. {
  772. //Thread data not valid...
  773. LogData = new CZT1LogData();
  774. }
  775. else
  776. {
  777. ThreadData = new CZT1ThreadData();
  778. LogData = new CZT1LogData(ThreadData);
  779. quint32 S1 = LineElements.at(6).toUInt();
  780. quint32 S2 = LineElements.at(7).toUInt();
  781. quint32 FN = LineElements.at(8).toUInt();
  782. quint32 PInt = LineElements.at(9).toUInt();
  783. quint32 PExt = LineElements.at(10).toUInt();
  784. quint32 PG = LineElements.at(11).toUInt();
  785. qreal TrainSpeed = LineElements.at(12).toFloat();
  786. quint32 Bogie = LineElements.at(13).toUInt();
  787. quint32 Rank = LineElements.at(14).toUInt();
  788. qint32 PGIntValue = LineElements.at(15).toInt();
  789. qint32 PGExtValue = LineElements.at(16).toInt();
  790. quint32 TrainType;
  791. if(LineElements.at(17) == "Inconnu")
  792. {
  793. TrainType = TRAIN_TYPE_UNKNOWN;
  794. }
  795. else if(LineElements.at(17) == "MR63/73")
  796. {
  797. TrainType = TRAIN_TYPE_MR63_MR73;
  798. }
  799. else if(LineElements.at(17) == "MPM10")
  800. {
  801. TrainType = TRAIN_TYPE_MPM10;
  802. }
  803. else
  804. {
  805. CSVFile.close();
  806. return RET_ERROR;
  807. }
  808. if(S1 == 1 && LastS1 == 0)
  809. S1Count++;
  810. if(S2 == 1 && LastS2 == 0)
  811. S2Count++;
  812. if(FN == 1 && LastFN == 0)
  813. FNCount++;
  814. LastS1 = S1;
  815. LastS2 = S2;
  816. LastFN = FN;
  817. ThreadData->mTimeStamp = timestamp; //nanosecs
  818. ThreadData->mDateTime.setDate(date);
  819. ThreadData->mDateTime.setTime(time);
  820. ThreadData->mS1 = S1;
  821. ThreadData->mS2 = S2;
  822. ThreadData->mFN = FN;
  823. ThreadData->mPInt = PInt;
  824. ThreadData->mPExt = PExt;
  825. ThreadData->mPG = PG;
  826. ThreadData->mTrainSpeed = TrainSpeed;
  827. ThreadData->mBogie = Bogie;
  828. ThreadData->mRank = Rank;
  829. ThreadData->mPGIntValue = PGIntValue;
  830. ThreadData->mPGExtValue = PGExtValue;
  831. ThreadData->mS1Count = S1Count;
  832. ThreadData->mS2Count = S2Count;
  833. ThreadData->mFNCount = FNCount;
  834. ThreadData->mTrainType = TrainType;
  835. }
  836. LogData->mTimestamp = timestamp;
  837. LogData->mCIZT1 = CIZT1;
  838. LogData->mCDVApproach_ZT1 = CDVApproach_ZT1;
  839. LogData->mCDVARM_ZT1 = CDVARM_ZT1;
  840. LogData->mDateTime.setDate(date);
  841. LogData->mDateTime.setTime(time);
  842. ZT1LOG->mZT1LogData.append(LogData);
  843. }
  844. // QList<CZTDetectionData*> Dummy; //JFM
  845. QVector<CZTDetectionData*> Dummy;
  846. Dummy.clear();
  847. SaveTrainLog(CSVFilePathName.replace("csv","bin"),ZT1LOG,&Dummy,StationName);
  848. for(int i = 0; i < ZT1LOG->mZT1LogData.size(); i++)
  849. {
  850. delete ZT1LOG->mZT1LogData.at(i);
  851. }
  852. ZT1LOG->mZT1LogData.clear();
  853. delete ZT1LOG;
  854. }
  855. else //ZT1
  856. {
  857. }
  858. return RET_OK;
  859. }