mirror of
https://gitlab.com/pholy/OSCAR-code.git
synced 2025-04-22 05:30:44 +00:00
Merge branch 'master' into Legacy
This commit is contained in:
commit
a2232d4b61
File diff suppressed because it is too large
Load Diff
@ -28,7 +28,7 @@
|
|||||||
const int prs1_data_version = 15;
|
const int prs1_data_version = 15;
|
||||||
//
|
//
|
||||||
//********************************************************************************************
|
//********************************************************************************************
|
||||||
|
#if 0 // Apparently unused
|
||||||
/*! \class PRS1
|
/*! \class PRS1
|
||||||
\brief PRS1 customized machine object (via CPAP)
|
\brief PRS1 customized machine object (via CPAP)
|
||||||
*/
|
*/
|
||||||
@ -41,6 +41,7 @@ class PRS1: public CPAP
|
|||||||
|
|
||||||
|
|
||||||
const int max_load_buffer_size = 1024 * 1024;
|
const int max_load_buffer_size = 1024 * 1024;
|
||||||
|
#endif
|
||||||
const QString prs1_class_name = STR_MACH_PRS1;
|
const QString prs1_class_name = STR_MACH_PRS1;
|
||||||
|
|
||||||
/*! \struct PRS1Waveform
|
/*! \struct PRS1Waveform
|
||||||
@ -77,13 +78,13 @@ public:
|
|||||||
m_index = -1;
|
m_index = -1;
|
||||||
}
|
}
|
||||||
PRS1DataChunk(class QFile & f);
|
PRS1DataChunk(class QFile & f);
|
||||||
~PRS1DataChunk() {
|
~PRS1DataChunk();
|
||||||
}
|
|
||||||
inline int size() const { return m_data.size(); }
|
inline int size() const { return m_data.size(); }
|
||||||
|
|
||||||
QByteArray m_header;
|
QByteArray m_header;
|
||||||
QByteArray m_data;
|
QByteArray m_data;
|
||||||
QByteArray m_headerblock;
|
QByteArray m_headerblock;
|
||||||
|
QList<class PRS1ParsedEvent*> m_parsedData;
|
||||||
|
|
||||||
QString m_path;
|
QString m_path;
|
||||||
qint64 m_filepos; // file offset
|
qint64 m_filepos; // file offset
|
||||||
@ -109,6 +110,9 @@ public:
|
|||||||
// V3 normal/non-waveform fields
|
// V3 normal/non-waveform fields
|
||||||
QMap<unsigned char, short> hblock;
|
QMap<unsigned char, short> hblock;
|
||||||
|
|
||||||
|
QMap<unsigned char, QByteArray> mainblock;
|
||||||
|
QMap<unsigned char, QByteArray> hbdata;
|
||||||
|
|
||||||
// Trailing common fields
|
// Trailing common fields
|
||||||
quint8 storedChecksum; // header checksum stored in file, last byte of m_header
|
quint8 storedChecksum; // header checksum stored in file, last byte of m_header
|
||||||
quint8 calcChecksum; // header checksum as calculated when parsing
|
quint8 calcChecksum; // header checksum as calculated when parsing
|
||||||
@ -124,7 +128,58 @@ public:
|
|||||||
//! \brief Read the chunk's data from a PRS1 file and calculate its CRC, must be called after ReadHeader
|
//! \brief Read the chunk's data from a PRS1 file and calculate its CRC, must be called after ReadHeader
|
||||||
bool ReadData(class QFile & f);
|
bool ReadData(class QFile & f);
|
||||||
|
|
||||||
|
//! \brief Parse a single data chunk from a .000 file containing compliance data for a brick
|
||||||
|
bool ParseCompliance(void);
|
||||||
|
|
||||||
|
//! \brief Figures out which Summary Parser to call, based on machine family/version and calls it.
|
||||||
|
bool ParseSummary();
|
||||||
|
|
||||||
|
//! \brief Parse a single data chunk from a .001 file containing summary data for a family 0 CPAP/APAP family version 2 or 3 machine
|
||||||
|
bool ParseSummaryF0V23(void);
|
||||||
|
|
||||||
|
//! \brief Parse a single data chunk from a .001 file containing summary data for a family 0 CPAP/APAP family version 4 machine
|
||||||
|
bool ParseSummaryF0V4(void);
|
||||||
|
|
||||||
|
//! \brief Parse a single data chunk from a .001 file containing summary data for a family 0 CPAP/APAP family version 6 machine
|
||||||
|
bool ParseSummaryF0V6(void);
|
||||||
|
|
||||||
|
//! \brief Parse a single data chunk from a .001 file containing summary data for a family 3 ventilator (family version 6?) machine
|
||||||
|
bool ParseSummaryF3(void);
|
||||||
|
|
||||||
|
//! \brief Parse a single data chunk from a .001 file containing summary data for a family 5 ASV family version 0-2 machine
|
||||||
|
bool ParseSummaryF5V012(void);
|
||||||
|
|
||||||
|
//! \brief Parse a single data chunk from a .001 file containing summary data for a family 5 ASV family version 3 machine
|
||||||
|
bool ParseSummaryF5V3(void);
|
||||||
|
|
||||||
|
//! \brief Parse a flex setting byte from a .000 or .001 containing compliance/summary data
|
||||||
|
void ParseFlexSetting(quint8 flex, CPAPMode cpapmode);
|
||||||
|
|
||||||
|
//! \brief Parse an humidifier setting byte from a .000 or .001 containing compliance/summary data
|
||||||
|
void ParseHumidifierSetting(int humid, bool supportsHeatedTubing=true);
|
||||||
|
|
||||||
|
//! \brief Figures out which Event Parser to call, based on machine family/version and calls it.
|
||||||
|
bool ParseEvents(CPAPMode mode);
|
||||||
|
|
||||||
|
//! \brief Parse a single data chunk from a .002 file containing event data for a family 0 CPAP/APAP machine
|
||||||
|
bool ParseEventsF0(CPAPMode mode);
|
||||||
|
|
||||||
|
//! \brief Parse a single data chunk from a .002 file containing event data for a family 3 ventilator family version 3 machine
|
||||||
|
bool ParseEventsF3V3(void);
|
||||||
|
|
||||||
|
//! \brief Parse a single data chunk from a .002 file containing event data for a family 3 ventilator family version 6 machine
|
||||||
|
bool ParseEventsF3V6(void);
|
||||||
|
|
||||||
|
//! \brief Parse a single data chunk from a .002 file containing event data for a family 5 ASV family version 0-2 machine
|
||||||
|
bool ParseEventsF5V012(void);
|
||||||
|
|
||||||
|
//! \brief Parse a single data chunk from a .002 file containing event data for a family 5 ASV family version 3 machine
|
||||||
|
bool ParseEventsF5V3(void);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
//! \brief Add a parsed event to the chunk
|
||||||
|
void AddEvent(class PRS1ParsedEvent* event);
|
||||||
|
|
||||||
//! \brief Read and parse the non-waveform header data from a V2 PRS1 file
|
//! \brief Read and parse the non-waveform header data from a V2 PRS1 file
|
||||||
bool ReadNormalHeaderV2(class QFile & f);
|
bool ReadNormalHeaderV2(class QFile & f);
|
||||||
|
|
||||||
@ -138,6 +193,13 @@ protected:
|
|||||||
bool ExtractStoredCrc(int size);
|
bool ExtractStoredCrc(int size);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if UNITTEST_MODE
|
||||||
|
QString _PRS1ParsedEventName(PRS1ParsedEvent* e);
|
||||||
|
QMap<QString,QString> _PRS1ParsedEventContents(PRS1ParsedEvent* e);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
class PRS1Loader;
|
class PRS1Loader;
|
||||||
|
|
||||||
/*! \class PRS1Import
|
/*! \class PRS1Import
|
||||||
@ -167,9 +229,6 @@ public:
|
|||||||
QList<PRS1DataChunk *> waveforms;
|
QList<PRS1DataChunk *> waveforms;
|
||||||
QList<PRS1DataChunk *> oximetry;
|
QList<PRS1DataChunk *> oximetry;
|
||||||
|
|
||||||
QMap<unsigned char, QByteArray> mainblock;
|
|
||||||
QMap<unsigned char, QByteArray> hbdata;
|
|
||||||
|
|
||||||
|
|
||||||
QString wavefile;
|
QString wavefile;
|
||||||
QString oxifile;
|
QString oxifile;
|
||||||
@ -177,8 +236,8 @@ public:
|
|||||||
//! \brief As it says on the tin.. Parses .001 files for bricks.
|
//! \brief As it says on the tin.. Parses .001 files for bricks.
|
||||||
bool ParseCompliance();
|
bool ParseCompliance();
|
||||||
|
|
||||||
//! \brief Figures out which Summary Parser to call, based on machine family/version and calls it.
|
//! \brief Imports the .002 summary file.
|
||||||
bool ParseSummary();
|
bool ImportSummary();
|
||||||
|
|
||||||
//! \brief Figures out which Event Parser to call, based on machine family/version and calls it.
|
//! \brief Figures out which Event Parser to call, based on machine family/version and calls it.
|
||||||
bool ParseEvents();
|
bool ParseEvents();
|
||||||
@ -193,24 +252,6 @@ public:
|
|||||||
bool ParseOximetery();
|
bool ParseOximetery();
|
||||||
|
|
||||||
|
|
||||||
//! \brief Summary parser for 50 series Family 0 CPAP/APAP models
|
|
||||||
bool ParseSummaryF0();
|
|
||||||
//! \brief Summary parser for 60 series Family 0 CPAP/APAP models
|
|
||||||
bool ParseSummaryF0V4();
|
|
||||||
//! \brief Summary parser for 1060 series AVAPS models
|
|
||||||
bool ParseSummaryF3();
|
|
||||||
//! \brief Summary parser for 50 series Family 5-0 BiPAP/AutoSV models
|
|
||||||
bool ParseSummaryF5V0();
|
|
||||||
//! \brief Summary parser for 60 series Family 5-1 BiPAP/AutoSV models
|
|
||||||
bool ParseSummaryF5V1();
|
|
||||||
//! \brief Summary parser for 60 series Family 5-2 BiPAP/AutoSV models
|
|
||||||
bool ParseSummaryF5V2();
|
|
||||||
//! \brief Summary parser for 60 series Family 5-3 BiPAP/AutoSV models
|
|
||||||
bool ParseSummaryF5V3();
|
|
||||||
|
|
||||||
//! \brief Summary parser for DreamStation series CPAP/APAP models
|
|
||||||
bool ParseSummaryF0V6();
|
|
||||||
|
|
||||||
//! \brief Parse a single data chunk from a .002 file containing event data for a standard system one machine
|
//! \brief Parse a single data chunk from a .002 file containing event data for a standard system one machine
|
||||||
bool ParseF0Events();
|
bool ParseF0Events();
|
||||||
//! \brief Parse a single data chunk from a .002 file containing event data for a AVAPS 1060P machine
|
//! \brief Parse a single data chunk from a .002 file containing event data for a AVAPS 1060P machine
|
||||||
@ -250,6 +291,9 @@ class PRS1Loader : public CPAPLoader
|
|||||||
//! \brief Examine path and return it back if it contains what looks to be a valid PRS1 SD card structure
|
//! \brief Examine path and return it back if it contains what looks to be a valid PRS1 SD card structure
|
||||||
QString checkDir(const QString & path);
|
QString checkDir(const QString & path);
|
||||||
|
|
||||||
|
//! \brief Peek into PROP.TXT or properties.txt at given path, and return it as a normalized key/value hash
|
||||||
|
bool PeekProperties(const QString & filename, QHash<QString,QString> & props);
|
||||||
|
|
||||||
//! \brief Peek into PROP.TXT or properties.txt at given path, and use it to fill MachineInfo structure
|
//! \brief Peek into PROP.TXT or properties.txt at given path, and use it to fill MachineInfo structure
|
||||||
bool PeekProperties(MachineInfo & info, const QString & path, Machine * mach = nullptr);
|
bool PeekProperties(MachineInfo & info, const QString & path, Machine * mach = nullptr);
|
||||||
|
|
||||||
@ -337,4 +381,21 @@ class PRS1Loader : public CPAPLoader
|
|||||||
qint32 summary_duration;
|
qint32 summary_duration;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//********************************************************************************************
|
||||||
|
|
||||||
|
class PRS1ModelInfo
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
QHash<int, QHash<int, QStringList>> m_testedModels;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PRS1ModelInfo();
|
||||||
|
bool IsSupported(const QHash<QString,QString> & properties) const;
|
||||||
|
bool IsSupported(int family, int familyVersion) const;
|
||||||
|
bool IsTested(const QHash<QString,QString> & properties) const;
|
||||||
|
bool IsTested(const QString & modelNumber, int family, int familyVersion) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // PRS1LOADER_H
|
#endif // PRS1LOADER_H
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/* SleepLib Machine Class Implementation
|
/* SleepLib Machine Class Implementation
|
||||||
*
|
*
|
||||||
|
* Copyright (c) 2019 The OSCAR Team
|
||||||
* Copyright (c) 2011-2018 Mark Watkins <mark@jedimark.net>
|
* Copyright (c) 2011-2018 Mark Watkins <mark@jedimark.net>
|
||||||
*
|
*
|
||||||
* This file is subject to the terms and conditions of the GNU General Public
|
* This file is subject to the terms and conditions of the GNU General Public
|
||||||
@ -45,6 +46,7 @@ Machine::Machine(Profile *_profile, MachineID id) : profile(_profile)
|
|||||||
day.clear();
|
day.clear();
|
||||||
highest_sessionid = 0;
|
highest_sessionid = 0;
|
||||||
m_unsupported = false;
|
m_unsupported = false;
|
||||||
|
m_untested = false;
|
||||||
|
|
||||||
if (!id) {
|
if (!id) {
|
||||||
srand(time(nullptr));
|
srand(time(nullptr));
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/* SleepLib Machine Class Header
|
/* SleepLib Machine Class Header
|
||||||
*
|
*
|
||||||
|
* Copyright (c) 2019 The OSCAR Team
|
||||||
* Copyright (C) 2011-2018 Mark Watkins <mark@jedimark.net>
|
* Copyright (C) 2011-2018 Mark Watkins <mark@jedimark.net>
|
||||||
*
|
*
|
||||||
* This file is subject to the terms and conditions of the GNU General Public
|
* This file is subject to the terms and conditions of the GNU General Public
|
||||||
@ -184,9 +185,12 @@ class Machine
|
|||||||
QSemaphore *savelistSem;
|
QSemaphore *savelistSem;
|
||||||
|
|
||||||
bool m_unsupported;
|
bool m_unsupported;
|
||||||
|
bool m_untested;
|
||||||
|
|
||||||
bool unsupported() { return m_unsupported; }
|
bool unsupported() { return m_unsupported; }
|
||||||
void setUnsupported(bool b) { m_unsupported = b; }
|
void setUnsupported(bool b) { m_unsupported = b; }
|
||||||
|
bool untested() { return m_untested; }
|
||||||
|
void setUntested(bool b) { m_untested = b; }
|
||||||
|
|
||||||
void lockSaveMutex() { listMutex.lock(); }
|
void lockSaveMutex() { listMutex.lock(); }
|
||||||
void unlockSaveMutex() { listMutex.unlock(); }
|
void unlockSaveMutex() { listMutex.unlock(); }
|
||||||
|
@ -33,6 +33,47 @@ void PRS1Tests::cleanupTestCase(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ====================================================================================================
|
||||||
|
|
||||||
|
extern PRS1ModelInfo s_PRS1ModelInfo;
|
||||||
|
void PRS1Tests::testMachineSupport()
|
||||||
|
{
|
||||||
|
QHash<QString,QString> tested = {
|
||||||
|
{ "ModelNumber", "550P" },
|
||||||
|
{ "Family", "0" },
|
||||||
|
{ "FamilyVersion", "3" },
|
||||||
|
};
|
||||||
|
QHash<QString,QString> supported = {
|
||||||
|
{ "ModelNumber", "700X999" },
|
||||||
|
{ "Family", "0" },
|
||||||
|
{ "FamilyVersion", "6" },
|
||||||
|
};
|
||||||
|
QHash<QString,QString> unsupported = {
|
||||||
|
{ "ModelNumber", "550P" },
|
||||||
|
{ "Family", "0" },
|
||||||
|
{ "FamilyVersion", "9" },
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_ASSERT(s_PRS1ModelInfo.IsSupported(5, 3));
|
||||||
|
Q_ASSERT(!s_PRS1ModelInfo.IsSupported(5, 9));
|
||||||
|
Q_ASSERT(!s_PRS1ModelInfo.IsSupported(9, 9));
|
||||||
|
Q_ASSERT(s_PRS1ModelInfo.IsTested("550P", 0, 2));
|
||||||
|
Q_ASSERT(s_PRS1ModelInfo.IsTested("550P", 0, 3));
|
||||||
|
Q_ASSERT(s_PRS1ModelInfo.IsTested("760P", 0, 4));
|
||||||
|
Q_ASSERT(s_PRS1ModelInfo.IsTested("700X110", 0, 6));
|
||||||
|
Q_ASSERT(!s_PRS1ModelInfo.IsTested("700X999", 0, 6));
|
||||||
|
|
||||||
|
Q_ASSERT(s_PRS1ModelInfo.IsTested(tested));
|
||||||
|
Q_ASSERT(!s_PRS1ModelInfo.IsTested(supported));
|
||||||
|
Q_ASSERT(s_PRS1ModelInfo.IsSupported(tested));
|
||||||
|
Q_ASSERT(s_PRS1ModelInfo.IsSupported(supported));
|
||||||
|
Q_ASSERT(!s_PRS1ModelInfo.IsSupported(unsupported));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ====================================================================================================
|
||||||
|
|
||||||
|
|
||||||
void parseAndEmitSessionYaml(const QString & path)
|
void parseAndEmitSessionYaml(const QString & path)
|
||||||
{
|
{
|
||||||
qDebug() << path;
|
qDebug() << path;
|
||||||
@ -84,13 +125,16 @@ static QString ts(qint64 msecs)
|
|||||||
return QDateTime::fromMSecsSinceEpoch(msecs).toString(Qt::ISODate);
|
return QDateTime::fromMSecsSinceEpoch(msecs).toString(Qt::ISODate);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString byteList(QByteArray data)
|
static QString byteList(QByteArray data, int limit=-1)
|
||||||
{
|
{
|
||||||
|
int count = data.size();
|
||||||
|
if (limit == -1 || limit > count) limit = count;
|
||||||
QStringList l;
|
QStringList l;
|
||||||
for (int i = 0; i < data.size(); i++) {
|
for (int i = 0; i < limit; i++) {
|
||||||
l.push_back(QString( "%1" ).arg((int) data[i] & 0xFF, 2, 16, QChar('0') ).toUpper());
|
l.push_back(QString( "%1" ).arg((int) data[i] & 0xFF, 2, 16, QChar('0') ).toUpper());
|
||||||
}
|
}
|
||||||
QString s = l.join("");
|
if (limit < count) l.push_back("...");
|
||||||
|
QString s = l.join(" ");
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +183,36 @@ void ChunkToYaml(QFile & file, PRS1DataChunk* chunk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// data
|
// data
|
||||||
out << " data: " << byteList(chunk->m_data) << endl;
|
bool dump_data = true;
|
||||||
|
if (chunk->m_parsedData.size() > 0) {
|
||||||
|
dump_data = false;
|
||||||
|
out << " events:" << endl;
|
||||||
|
for (auto & e : chunk->m_parsedData) {
|
||||||
|
QString name = _PRS1ParsedEventName(e);
|
||||||
|
if (name == "raw" || name == "unknown") {
|
||||||
|
dump_data = true;
|
||||||
|
}
|
||||||
|
QMap<QString,QString> contents = _PRS1ParsedEventContents(e);
|
||||||
|
if (name == "setting" && contents.size() == 1) {
|
||||||
|
out << " - set_" << contents.firstKey() << ": " << contents.first() << endl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
out << " - " << name << ":" << endl;
|
||||||
|
|
||||||
|
// Always emit start first if present
|
||||||
|
if (contents.contains("start")) {
|
||||||
|
out << " " << "start" << ": " << contents["start"] << endl;
|
||||||
|
}
|
||||||
|
for (auto & key : contents.keys()) {
|
||||||
|
if (key == "start") continue;
|
||||||
|
out << " " << key << ": " << contents[key] << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dump_data) {
|
||||||
|
out << " data: " << byteList(chunk->m_data, 100) << endl;
|
||||||
|
}
|
||||||
|
|
||||||
// data CRC
|
// data CRC
|
||||||
out << " crc: " << hex << chunk->storedCrc << endl;
|
out << " crc: " << hex << chunk->storedCrc << endl;
|
||||||
@ -211,8 +284,17 @@ void parseAndEmitChunkYaml(const QString & path)
|
|||||||
// Parse the chunks in the file.
|
// Parse the chunks in the file.
|
||||||
QList<PRS1DataChunk *> chunks = s_loader->ParseFile(inpath);
|
QList<PRS1DataChunk *> chunks = s_loader->ParseFile(inpath);
|
||||||
for (int i=0; i < chunks.size(); i++) {
|
for (int i=0; i < chunks.size(); i++) {
|
||||||
// Emit the YAML.
|
|
||||||
PRS1DataChunk * chunk = chunks.at(i);
|
PRS1DataChunk * chunk = chunks.at(i);
|
||||||
|
|
||||||
|
// Parse the inner data.
|
||||||
|
switch (chunk->ext) {
|
||||||
|
case 0: chunk->ParseCompliance(); break;
|
||||||
|
case 1: chunk->ParseSummary(); break;
|
||||||
|
case 2: chunk->ParseEvents(MODE_UNKNOWN); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emit the YAML.
|
||||||
ChunkToYaml(file, chunk);
|
ChunkToYaml(file, chunk);
|
||||||
delete chunk;
|
delete chunk;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ class PRS1Tests : public QObject
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void initTestCase();
|
void initTestCase();
|
||||||
|
void testMachineSupport();
|
||||||
void testChunksToYaml();
|
void testChunksToYaml();
|
||||||
void testSessionsToYaml();
|
void testSessionsToYaml();
|
||||||
// void test2();
|
// void test2();
|
||||||
|
@ -133,22 +133,26 @@ static QString eventChannel(ChannelID i)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString intList(EventStoreType* data, int count)
|
static QString intList(EventStoreType* data, int count, int limit=-1)
|
||||||
{
|
{
|
||||||
|
if (limit == -1 || limit > count) limit = count;
|
||||||
QStringList l;
|
QStringList l;
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < limit; i++) {
|
||||||
l.push_back(QString::number(data[i]));
|
l.push_back(QString::number(data[i]));
|
||||||
}
|
}
|
||||||
|
if (limit < count) l.push_back("...");
|
||||||
QString s = "[ " + l.join(",") + " ]";
|
QString s = "[ " + l.join(",") + " ]";
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString intList(quint32* data, int count)
|
static QString intList(quint32* data, int count, int limit=-1)
|
||||||
{
|
{
|
||||||
|
if (limit == -1 || limit > count) limit = count;
|
||||||
QStringList l;
|
QStringList l;
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < limit; i++) {
|
||||||
l.push_back(QString::number(data[i] / 1000));
|
l.push_back(QString::number(data[i] / 1000));
|
||||||
}
|
}
|
||||||
|
if (limit < count) l.push_back("...");
|
||||||
QString s = "[ " + l.join(",") + " ]";
|
QString s = "[ " + l.join(",") + " ]";
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -174,7 +178,14 @@ void SessionToYaml(QString filepath, Session* session)
|
|||||||
QList<ChannelID> keys = session->settings.keys();
|
QList<ChannelID> keys = session->settings.keys();
|
||||||
std::sort(keys.begin(), keys.end());
|
std::sort(keys.begin(), keys.end());
|
||||||
for (QList<ChannelID>::iterator key = keys.begin(); key != keys.end(); key++) {
|
for (QList<ChannelID>::iterator key = keys.begin(); key != keys.end(); key++) {
|
||||||
out << " " << settingChannel(*key) << ": " << session->settings[*key].toString() << endl;
|
QVariant & value = session->settings[*key];
|
||||||
|
QString s;
|
||||||
|
if ((QMetaType::Type) value.type() == QMetaType::Float) {
|
||||||
|
s = QString::number(value.toFloat()); // Print the shortest accurate representation rather than QVariant's full precision.
|
||||||
|
} else {
|
||||||
|
s = value.toString();
|
||||||
|
}
|
||||||
|
out << " " << settingChannel(*key) << ": " << s << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
out << " events:" << endl;
|
out << " events:" << endl;
|
||||||
@ -209,15 +220,15 @@ void SessionToYaml(QString filepath, Session* session)
|
|||||||
out << " data:" << endl;
|
out << " data:" << endl;
|
||||||
out << " min: " << e.Min() << endl;
|
out << " min: " << e.Min() << endl;
|
||||||
out << " max: " << e.Max() << endl;
|
out << " max: " << e.Max() << endl;
|
||||||
out << " raw: " << intList((EventStoreType*) e.m_data.data(), e.count()) << endl;
|
out << " raw: " << intList((EventStoreType*) e.m_data.data(), e.count(), 100) << endl;
|
||||||
if (e.type() != EVL_Waveform) {
|
if (e.type() != EVL_Waveform) {
|
||||||
out << " delta: " << intList((quint32*) e.m_time.data(), e.count()) << endl;
|
out << " delta: " << intList((quint32*) e.m_time.data(), e.count(), 100) << endl;
|
||||||
}
|
}
|
||||||
if (e.hasSecondField()) {
|
if (e.hasSecondField()) {
|
||||||
out << " data2:" << endl;
|
out << " data2:" << endl;
|
||||||
out << " min: " << e.min2() << endl;
|
out << " min: " << e.min2() << endl;
|
||||||
out << " max: " << e.max2() << endl;
|
out << " max: " << e.max2() << endl;
|
||||||
out << " raw: " << intList((EventStoreType*) e.m_data2.data(), e.count()) << endl;
|
out << " raw: " << intList((EventStoreType*) e.m_data2.data(), e.count(), 100) << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user