Fix ZEO loader to handle MyZeo 0.3.1 date formatting.

Also make the UI more informative and fix up the regression test output.
This commit is contained in:
sawinglogz 2020-01-29 16:21:42 -05:00
parent 448bfa048c
commit 8ef068af7e
6 changed files with 59 additions and 27 deletions

View File

@ -83,15 +83,17 @@ int ZEOLoader::Open(const QString & dirpath)
int ZEOLoader::OpenFile(const QString & filename) int ZEOLoader::OpenFile(const QString & filename)
{ {
if (!openCSV(filename)) { if (!openCSV(filename)) {
return 0; return -1;
} }
int count = 0;
Session* sess; Session* sess;
while ((sess = readNextSession()) != nullptr) { while ((sess = readNextSession()) != nullptr) {
sess->SetChanged(true); sess->SetChanged(true);
mach->AddSession(sess); mach->AddSession(sess);
count++;
} }
mach->Save(); mach->Save();
return true; return count;
} }
bool ZEOLoader::openCSV(const QString & filename) bool ZEOLoader::openCSV(const QString & filename)
@ -101,11 +103,11 @@ bool ZEOLoader::openCSV(const QString & filename)
if (filename.toLower().endsWith(".csv")) { if (filename.toLower().endsWith(".csv")) {
if (!file.open(QFile::ReadOnly)) { if (!file.open(QFile::ReadOnly)) {
qDebug() << "Couldn't open zeo file" << filename; qDebug() << "Couldn't open zeo file" << filename;
return 0; return false;
} }
} else {// if (filename.toLower().endsWith(".dat")) { } else {// if (filename.toLower().endsWith(".dat")) {
return 0; return false;
// not supported. // not supported.
} }
@ -211,15 +213,15 @@ Session* ZEOLoader::readNextSession()
if (!ok) { dodgy = true; } if (!ok) { dodgy = true; }
start_of_night = QDateTime::fromString(linecomp[idxStartOfNight], "MM/dd/yyyy HH:mm"); start_of_night = readDateTime(linecomp[idxStartOfNight]);
if (!start_of_night.isValid()) { dodgy = true; } if (!start_of_night.isValid()) { dodgy = true; }
end_of_night = QDateTime::fromString(linecomp[idxEndOfNight], "MM/dd/yyyy HH:mm"); end_of_night = readDateTime(linecomp[idxEndOfNight]);
if (!end_of_night.isValid()) { dodgy = true; } if (!end_of_night.isValid()) { dodgy = true; }
rise_time = QDateTime::fromString(linecomp[idxRiseTime], "MM/dd/yyyy HH:mm"); rise_time = readDateTime(linecomp[idxRiseTime]);
if (!rise_time.isValid()) { dodgy = true; } if (!rise_time.isValid()) { dodgy = true; }
@ -244,31 +246,31 @@ Session* ZEOLoader::readNextSession()
// if (!ok) { dodgy = true; } // if (!ok) { dodgy = true; }
if (!linecomp[idxFirstAlaramRing].isEmpty()) { if (!linecomp[idxFirstAlaramRing].isEmpty()) {
FirstAlarmRing = QDateTime::fromString(linecomp[idxFirstAlaramRing], "MM/dd/yyyy HH:mm"); FirstAlarmRing = readDateTime(linecomp[idxFirstAlaramRing]);
if (!FirstAlarmRing.isValid()) { dodgy = true; } if (!FirstAlarmRing.isValid()) { dodgy = true; }
} }
if (!linecomp[idxLastAlaramRing].isEmpty()) { if (!linecomp[idxLastAlaramRing].isEmpty()) {
LastAlarmRing = QDateTime::fromString(linecomp[idxLastAlaramRing], "MM/dd/yyyy HH:mm"); LastAlarmRing = readDateTime(linecomp[idxLastAlaramRing]);
if (!LastAlarmRing.isValid()) { dodgy = true; } if (!LastAlarmRing.isValid()) { dodgy = true; }
} }
if (!linecomp[idxFirstSnoozeTime].isEmpty()) { if (!linecomp[idxFirstSnoozeTime].isEmpty()) {
FirstSnoozeTime = QDateTime::fromString(linecomp[idxFirstSnoozeTime], "MM/dd/yyyy HH:mm"); FirstSnoozeTime = readDateTime(linecomp[idxFirstSnoozeTime]);
if (!FirstSnoozeTime.isValid()) { dodgy = true; } if (!FirstSnoozeTime.isValid()) { dodgy = true; }
} }
if (!linecomp[idxLastSnoozeTime].isEmpty()) { if (!linecomp[idxLastSnoozeTime].isEmpty()) {
LastSnoozeTime = QDateTime::fromString(linecomp[idxLastSnoozeTime], "MM/dd/yyyy HH:mm"); LastSnoozeTime = readDateTime(linecomp[idxLastSnoozeTime]);
if (!LastSnoozeTime.isValid()) { dodgy = true; } if (!LastSnoozeTime.isValid()) { dodgy = true; }
} }
if (!linecomp[idxSetAlarmTime].isEmpty()) { if (!linecomp[idxSetAlarmTime].isEmpty()) {
SetAlarmTime = QDateTime::fromString(linecomp[idxSetAlarmTime], "MM/dd/yyyy HH:mm"); SetAlarmTime = readDateTime(linecomp[idxSetAlarmTime]);
if (!SetAlarmTime.isValid()) { dodgy = true; } if (!SetAlarmTime.isValid()) { dodgy = true; }
} }
@ -331,16 +333,22 @@ Session* ZEOLoader::readNextSession()
} }
sess->really_set_last(tt); sess->really_set_last(tt);
int size = DSG.size(); //int size = DSG.size();
//qDebug() << linecomp[0] << start_of_night << end_of_night << rise_time << size << "30 second chunks";
qDebug() << linecomp[0] << start_of_night << end_of_night << rise_time << size <<
"30 second chunks";
} }
return sess; return sess;
} }
QDateTime ZEOLoader::readDateTime(const QString & text)
{
QDateTime dt = QDateTime::fromString(text, "MM/dd/yyyy HH:mm");
if (!dt.isValid()) {
dt = QDateTime::fromString(text, "yyyy-MM-dd HH:mm:ss");
}
return dt;
}
static bool zeo_initialized = false; static bool zeo_initialized = false;
void ZEOLoader::Register() void ZEOLoader::Register()

View File

@ -43,6 +43,8 @@ class ZEOLoader : public MachineLoader
Session* readNextSession(); Session* readNextSession();
protected: protected:
QDateTime readDateTime(const QString & text);
private: private:
QFile file; QFile file;
QTextStream text; QTextStream text;

View File

@ -328,7 +328,7 @@ void init()
schema::channel.add(GRP_SLEEP, ch = new Channel(ZEO_TimeInREM = 0x2005, DATA, MT_SLEEPSTAGE, SESSION, "TimeInREM", QObject::tr("Time In REM Sleep"), QObject::tr("Time spent in REM Sleep"), QObject::tr("Time in REM Sleep"), STR_UNIT_Minutes, INTEGER, Qt::black)); schema::channel.add(GRP_SLEEP, ch = new Channel(ZEO_TimeInREM = 0x2005, DATA, MT_SLEEPSTAGE, SESSION, "TimeInREM", QObject::tr("Time In REM Sleep"), QObject::tr("Time spent in REM Sleep"), QObject::tr("Time in REM Sleep"), STR_UNIT_Minutes, INTEGER, Qt::black));
schema::channel.add(GRP_SLEEP, ch = new Channel(ZEO_TimeInLight= 0x2006, DATA, MT_SLEEPSTAGE, SESSION, "TimeInLight",QObject::tr("Time In Light Sleep"), QObject::tr("Time spent in light sleep"), QObject::tr("Time in Light Sleep"), STR_UNIT_Minutes, INTEGER, Qt::black)); schema::channel.add(GRP_SLEEP, ch = new Channel(ZEO_TimeInLight= 0x2006, DATA, MT_SLEEPSTAGE, SESSION, "TimeInLight",QObject::tr("Time In Light Sleep"), QObject::tr("Time spent in light sleep"), QObject::tr("Time in Light Sleep"), STR_UNIT_Minutes, INTEGER, Qt::black));
schema::channel.add(GRP_SLEEP, ch = new Channel(ZEO_TimeInDeep = 0x2007, DATA, MT_SLEEPSTAGE, SESSION, "TimeInDeep", QObject::tr("Time In Deep Sleep"), QObject::tr("Time spent in deep sleep"), QObject::tr("Time in Deep Sleep"), STR_UNIT_Minutes, INTEGER, Qt::black)); schema::channel.add(GRP_SLEEP, ch = new Channel(ZEO_TimeInDeep = 0x2007, DATA, MT_SLEEPSTAGE, SESSION, "TimeInDeep", QObject::tr("Time In Deep Sleep"), QObject::tr("Time spent in deep sleep"), QObject::tr("Time in Deep Sleep"), STR_UNIT_Minutes, INTEGER, Qt::black));
schema::channel.add(GRP_SLEEP, ch = new Channel(ZEO_TimeInDeep = 0x2008, DATA, MT_SLEEPSTAGE, SESSION, "TimeToZ", QObject::tr("Time to Sleep"), QObject::tr("Time taken to get to sleep"), QObject::tr("Time to Sleep"), STR_UNIT_Minutes, INTEGER, Qt::black)); schema::channel.add(GRP_SLEEP, ch = new Channel(ZEO_TimeToZ = 0x2008, DATA, MT_SLEEPSTAGE, SESSION, "TimeToZ", QObject::tr("Time to Sleep"), QObject::tr("Time taken to get to sleep"), QObject::tr("Time to Sleep"), STR_UNIT_Minutes, INTEGER, Qt::black));
schema::channel.add(GRP_SLEEP, ch = new Channel(ZEO_ZQ = 0x2009, DATA, MT_SLEEPSTAGE, SESSION, "ZeoZQ", QObject::tr("Zeo ZQ"), QObject::tr("Zeo sleep quality measurement"), QObject::tr("ZEO ZQ"), QString(), INTEGER, Qt::black)); schema::channel.add(GRP_SLEEP, ch = new Channel(ZEO_ZQ = 0x2009, DATA, MT_SLEEPSTAGE, SESSION, "ZeoZQ", QObject::tr("Zeo ZQ"), QObject::tr("Zeo sleep quality measurement"), QObject::tr("ZEO ZQ"), QString(), INTEGER, Qt::black));
NoChannel = 0; NoChannel = 0;

View File

@ -2309,12 +2309,17 @@ void MainWindow::on_actionImport_ZEO_Data_triggered()
if (w.exec() == QFileDialog::Accepted) { if (w.exec() == QFileDialog::Accepted) {
QString filename = w.selectedFiles()[0]; QString filename = w.selectedFiles()[0];
if (!zeo.OpenFile(filename)) { qDebug() << "Loading ZEO data from" << filename;
Notify(tr("There was a problem opening ZEO File: ") + filename); int c = zeo.OpenFile(filename);
return; if (c > 0) {
Notify(tr("Imported %1 ZEO session(s) from\n\n%2").arg(c).arg(filename), tr("Import Success"));
qDebug() << "Imported" << c << "ZEO sessions";
} else if (c == 0) {
Notify(tr("Already up to date with ZEO data at\n\n%1").arg(filename), tr("Up to date"));
} else {
Notify(tr("Couldn't find any valid ZEO CSV data at\n\n%1").arg(filename),tr("Import Problem"));
} }
Notify(tr("Zeo CSV Import complete"));
daily->LoadDate(daily->getDate()); daily->LoadDate(daily->getDate());
} }

View File

@ -90,6 +90,14 @@ static QString settingChannel(ChannelID i)
CHANNELNAME(PRS1_MaskAlert); CHANNELNAME(PRS1_MaskAlert);
CHANNELNAME(PRS1_ShowAHI); CHANNELNAME(PRS1_ShowAHI);
CHANNELNAME(CPAP_BrokenSummary); CHANNELNAME(CPAP_BrokenSummary);
CHANNELNAME(ZEO_Awakenings);
CHANNELNAME(ZEO_MorningFeel);
CHANNELNAME(ZEO_TimeInWake);
CHANNELNAME(ZEO_TimeInREM);
CHANNELNAME(ZEO_TimeInLight);
CHANNELNAME(ZEO_TimeInDeep);
CHANNELNAME(ZEO_TimeToZ);
CHANNELNAME(ZEO_ZQ);
s = hex(i); s = hex(i);
qDebug() << "setting channel" << qPrintable(s); qDebug() << "setting channel" << qPrintable(s);
} while(false); } while(false);
@ -137,6 +145,7 @@ static QString eventChannel(ChannelID i)
CHANNELNAME(CPAP_IPAPSet); CHANNELNAME(CPAP_IPAPSet);
CHANNELNAME(CPAP_EPAPSet); CHANNELNAME(CPAP_EPAPSet);
CHANNELNAME(POS_Movement); CHANNELNAME(POS_Movement);
CHANNELNAME(ZEO_SleepStage);
s = hex(i); s = hex(i);
qDebug() << "event channel" << qPrintable(s); qDebug() << "event channel" << qPrintable(s);
} while(false); } while(false);

View File

@ -12,7 +12,7 @@
#define TESTDATA_PATH "./testdata/" #define TESTDATA_PATH "./testdata/"
static ZEOLoader* s_loader = nullptr; static ZEOLoader* s_loader = nullptr;
static QString zeoOutputPath(const QString & inpath, const QString & suffix); static QString zeoOutputPath(const QString & inpath, int sid, const QString & suffix);
void ZeoTests::initTestCase(void) void ZeoTests::initTestCase(void)
{ {
@ -37,12 +37,19 @@ static void parseAndEmitSessionYaml(const QString & path)
qDebug() << path; qDebug() << path;
if (s_loader->openCSV(path)) { if (s_loader->openCSV(path)) {
int count = 0;
Session* session; Session* session;
while ((session = s_loader->readNextSession()) != nullptr) { while ((session = s_loader->readNextSession()) != nullptr) {
QString outpath = zeoOutputPath(path, "-session.yml"); QString outpath = zeoOutputPath(path, session->session(), "-session.yml");
SessionToYaml(outpath, session, true); SessionToYaml(outpath, session, true);
delete session; delete session;
count++;
} }
if (count == 0) {
qWarning() << "no sessions found";
}
} else {
qWarning() << "unable to open file";
} }
} }
@ -67,18 +74,19 @@ void ZeoTests::testSessionsToYaml()
// ==================================================================================================== // ====================================================================================================
QString zeoOutputPath(const QString & inpath, const QString & suffix) QString zeoOutputPath(const QString & inpath, int sid, const QString & suffix)
{ {
// Output to zeo/output/DIR/FILENAME(-session.yml, etc.) // Output to zeo/output/DIR/FILENAME(-session.yml, etc.)
QFileInfo path(inpath); QFileInfo path(inpath);
QString basename = path.fileName(); QString basename = path.baseName();
QString foldername = path.dir().dirName(); QString foldername = path.dir().dirName();
QDir outdir(TESTDATA_PATH "zeo/output/" + foldername); QDir outdir(TESTDATA_PATH "zeo/output/" + foldername);
outdir.mkpath("."); outdir.mkpath(".");
QString filename = QString("%1%2") QString filename = QString("%1-%2%3")
.arg(basename) .arg(basename)
.arg(sid, 8, 10, QChar('0'))
.arg(suffix); .arg(suffix);
return outdir.path() + QDir::separator() + filename; return outdir.path() + QDir::separator() + filename;
} }