Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions src/CUcontent_MBsSWs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,47 @@ bool CUcontent_MBsSWs::startMBSWreading()
}
else
goto err;

// store start time
startTime = std::chrono::high_resolution_clock::now();

// create csv object and write header
csv = new csvfile("measurements.csv");

// global time
*csv << "Time";

// time since measurement
*csv << "Delta Time";

// write header
for (size_t i=0; i < _MBSWmetaList.size(); i++)
{
const MBSWmetadata_dt& metadata = _MBSWmetaList.at(i);

std::string title;
std::string unit;

// find title and units
if (metadata.blockType == BlockType::MB)
{
const mb_dt& mb = _supportedMBs.at(metadata.nativeIndex);
title = mb.title.toStdString();
unit = mb.unit.toStdString();
}
else if (metadata.blockType == BlockType::SW)
{
const sw_dt& sw = _supportedSWs.at(metadata.nativeIndex);
title = sw.title.toStdString();
unit = sw.unit.toStdString();
}

// write to file
*csv << title + " (" + unit + ")";

}
*csv << endrow;

// Reset old data:
_lastValues.clear();
_minmaxData.clear();
Expand Down Expand Up @@ -410,6 +451,8 @@ bool CUcontent_MBsSWs::stopMBSWreading()
}
}
disconnect( _SSMPdev, SIGNAL( newMBSWrawValues(const std::vector<unsigned int>&, int) ), this, SLOT( processMBSWRawValues(const std::vector<unsigned int>&, int) ) );
// close csv files (also flushes csv)
delete csv;
// Set text+icon of start/stop-button:
labelStartStopButtonReadyForStart();
// Enable delete button if MBs/SWs are selected on the table:
Expand Down Expand Up @@ -711,6 +754,28 @@ void CUcontent_MBsSWs::processMBSWRawValues(const std::vector<unsigned int>& raw
_valuesTableView->updateMBSWvalues(valueStrList, minValueStrList, maxValueStrList, unitStrList);
// Output refresh duration:
updateTimeInfo(refreshduration_ms);

// write to csv

// get timestamp
const auto currTime = std::chrono::high_resolution_clock::now();
const std::chrono::duration<double> deltaTime = currTime - startTime;

// conver to unix epoch time in ms
const double unixEpochMs = std::chrono::duration_cast<std::chrono::milliseconds>
(currTime.time_since_epoch()).count() / 1000.0;
const double deltaEpochMs = std::chrono::duration_cast<std::chrono::milliseconds>
(deltaTime).count() / 1000.0;

// save to csv
*csv << std::fixed << unixEpochMs;
*csv << deltaEpochMs;
for (size_t i=0; i < valueStrList.size(); i++) {
std::string value = valueStrList.at(i).toStdString();
*csv << value;
}
*csv << endrow;
csv->flush();
}


Expand Down
9 changes: 9 additions & 0 deletions src/CUcontent_MBsSWs.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@
// To do binary file operations storing the current setup
#include <fstream>

#include <chrono>

#include "csvfile.h"

class MBSWvalue_dt
{
public:
Expand Down Expand Up @@ -106,6 +110,11 @@ class CUcontent_MBsSWs : public QWidget, private Ui::MBSWcontent_Form
std::vector<unsigned int> _tableRowPosIndexes; /* index of the row at which the MB/SW is displayed in the values-table-widget */
bool _MBSWreading;

// pointer to csv file object
csvfile *csv = nullptr;
// measurement start time (default ot current time)
std::chrono::high_resolution_clock::time_point startTime;

void setupTimeModeUiElements();
bool validateMBSWselection(const std::vector<MBSWmetadata_dt>& MBSWmetaList);
void setMBSWselectionUnvalidated(const std::vector<MBSWmetadata_dt>& MBSWmetaList);
Expand Down
128 changes: 128 additions & 0 deletions src/csvfile.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/**
* csvfile.h - Utility for writing CSV files
*
* Based on this github gist: https://gist.github.com/rudolfovich/f250900f1a833e715260a66c87369d15
*/

#ifndef CSVFILE_H
#define CSVFILE_H

#include <string>
#include <iostream>
#include <fstream>
#include <sstream>

class csvfile;

inline static csvfile& endrow(csvfile& file);
inline static csvfile& flush(csvfile& file);

class csvfile
{
std::ofstream fs_;
bool is_first_;
const std::string separator_;
const std::string escape_seq_;
const std::string special_chars_;
public:
csvfile(const std::string filename, const std::string separator = ";")
: fs_()
, is_first_(true)
, separator_(separator)
, escape_seq_("\"")
, special_chars_("\"")
{
fs_.exceptions(std::ios::failbit | std::ios::badbit);
fs_.open(filename);
}

~csvfile()
{
flush();
fs_.close();
}

void flush()
{
fs_.flush();
}

void endrow()
{
fs_ << std::endl;
is_first_ = true;
}

csvfile& operator << ( csvfile& (* val)(csvfile&))
{
return val(*this);
}

csvfile& operator << (const char * val)
{
return write(escape(val));
}

csvfile& operator << (const std::string & val)
{
return write(escape(val));
}

csvfile& operator<<(std::ios_base& (*manip)(std::ios_base&))
{
fs_ << manip;
return *this;
}

template<typename T>
csvfile& operator << (const T& val)
{
return write(val);
}

private:
template<typename T>
csvfile& write (const T& val)
{
if (!is_first_)
{
fs_ << separator_;
}
else
{
is_first_ = false;
}
fs_ << val;
return *this;
}

std::string escape(const std::string & val)
{
std::ostringstream result;
result << '"';
std::string::size_type to, from = 0u, len = val.length();
while (from < len &&
std::string::npos != (to = val.find_first_of(special_chars_, from)))
{
result << val.substr(from, to - from) << escape_seq_ << val[to];
from = to + 1;
}
result << val.substr(from) << '"';
return result.str();
}
};


inline static csvfile& endrow(csvfile& file)
{
file.endrow();
return file;
}

inline static csvfile& flush(csvfile& file)
{
file.flush();
return file;
}

#endif