/* SleepLib ZEO Loader Implementation * * Copyright (c) 2020 The OSCAR Team * Copyright (c) 2011-2018 Mark Watkins * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of the source code * for more details. */ //******************************************************************************************** // IMPORTANT!!! //******************************************************************************************** // Please INCREMENT the zeo_data_version in zel_loader.h when making changes to this loader // that change loader behaviour or modify channels. //******************************************************************************************** #include #include #include "zeo_loader.h" #include "SleepLib/machine.h" ZEOLoader::ZEOLoader() { m_type = MT_SLEEPSTAGE; } ZEOLoader::~ZEOLoader() { } int ZEOLoader::Open(const QString & dirpath) { QString newpath; QString dirtag = "zeo"; // Could Scan the ZEO folder for a list of CSVs QString path(dirpath); path = path.replace("\\", "/"); if (path.toLower().endsWith("/" + dirtag)) { return 0; //newpath=path; } else { newpath = path + "/" + dirtag.toUpper(); } //QString filename; // ZEO folder structure detection stuff here. return 0; // number of machines affected } /*15233: "Sleep Date" 15234: "ZQ" 15236: "Total Z" 15237: "Time to Z" 15237: "Time in Wake" 15238: "Time in REM" 15238: "Time in Light" 15241: "Time in Deep" 15242: "Awakenings" 15245: "Start of Night" 15246: "End of Night" 15246: "Rise Time" 15247: "Alarm Reason" 15247: "Snooze Time" 15254: "Wake Tone" 15259: "Wake Window" 15259: "Alarm Type" 15260: "First Alarm Ring" 15261: "Last Alarm Ring" 15261: "First Snooze Time" 15265: "Last Snooze Time" 15266: "Set Alarm Time" 15266: "Morning Feel" 15267: "Sleep Graph" 15267: "Detailed Sleep Graph" 15268: "Firmware Version" */ int ZEOLoader::OpenFile(const QString & filename) { if (!openCSV(filename)) { return -1; } int count = 0; Session* sess; while ((sess = readNextSession()) != nullptr) { sess->SetChanged(true); mach->AddSession(sess); count++; } mach->Save(); return count; } bool ZEOLoader::openCSV(const QString & filename) { file.setFileName(filename); if (filename.toLower().endsWith(".csv")) { if (!file.open(QFile::ReadOnly)) { qDebug() << "Couldn't open zeo file" << filename; return false; } } else {// if (filename.toLower().endsWith(".dat")) { return false; // not supported. } text.setDevice(&file); QString headerdata = text.readLine(); QStringList header = headerdata.split(","); MachineInfo info = newInfo(); mach = p_profile->CreateMachine(info); idxZQ = header.indexOf("ZQ"); //int idxTotalZ = header.indexOf("Total Z"); idxAwakenings = header.indexOf("Awakenings"); idxSG = header.indexOf("Sleep Graph"); idxDSG = header.indexOf("Detailed Sleep Graph"); idxTimeInWake = header.indexOf("Time in Wake"); idxTimeToZ = header.indexOf("Time to Z"); idxTimeInREM = header.indexOf("Time in REM"); idxTimeInLight = header.indexOf("Time in Light"); idxTimeInDeep = header.indexOf("Time in Deep"); idxStartOfNight = header.indexOf("Start of Night"); idxEndOfNight = header.indexOf("End of Night"); idxRiseTime = header.indexOf("Rise Time"); // int idxAlarmReason = header.indexOf("Alarm Reason"); // int idxSnoozeTime = header.indexOf("Snooze Time"); // int idxWakeTone = header.indexOf("Wake Tone"); // int idxWakeWindow = header.indexOf("Wake Window"); // int idxAlarmType = header.indexOf("Alarm Type"); idxFirstAlaramRing = header.indexOf("First Alarm Ring"); idxLastAlaramRing = header.indexOf("Last Alarm Ring"); idxFirstSnoozeTime = header.indexOf("First Snooze Time"); idxLastSnoozeTime = header.indexOf("Last Snooze Time"); idxSetAlarmTime = header.indexOf("Set Alarm Time"); idxMorningFeel = header.indexOf("Morning Feel"); idxFirmwareVersion = header.indexOf("Firmware Version"); idxMyZEOVersion = header.indexOf("My ZEO Version"); return true; } Session* ZEOLoader::readNextSession() { Session* sess = nullptr; QString line; QStringList linecomp; QDateTime start_of_night, end_of_night, rise_time; SessionID sid; //const qint64 WindowSize=30000; qint64 st, tt; int stage; int ZQ, TimeToZ, TimeInWake, TimeInREM, TimeInLight, TimeInDeep, Awakenings; //int AlarmReason, SnoozeTime, WakeTone, WakeWindow, AlarmType, TotalZ; int MorningFeel; QString FirmwareVersion, MyZeoVersion; QDateTime FirstAlarmRing, LastAlarmRing, FirstSnoozeTime, LastSnoozeTime, SetAlarmTime; QStringList SG, DSG; bool ok; bool dodgy; do { line = text.readLine(); dodgy = false; if (line.isEmpty()) { continue; } linecomp = line.split(","); ZQ = linecomp[idxZQ].toInt(&ok); if (!ok) { dodgy = true; } // TotalZ = linecomp[idxTotalZ].toInt(&ok); // if (!ok) { dodgy = true; } TimeToZ = linecomp[idxTimeToZ].toInt(&ok); if (!ok) { dodgy = true; } TimeInWake = linecomp[idxTimeInWake].toInt(&ok); if (!ok) { dodgy = true; } TimeInREM = linecomp[idxTimeInREM].toInt(&ok); if (!ok) { dodgy = true; } TimeInLight = linecomp[idxTimeInLight].toInt(&ok); if (!ok) { dodgy = true; } TimeInDeep = linecomp[idxTimeInDeep].toInt(&ok); if (!ok) { dodgy = true; } Awakenings = linecomp[idxAwakenings].toInt(&ok); if (!ok) { dodgy = true; } start_of_night = readDateTime(linecomp[idxStartOfNight]); if (!start_of_night.isValid()) { dodgy = true; } end_of_night = readDateTime(linecomp[idxEndOfNight]); if (!end_of_night.isValid()) { dodgy = true; } rise_time = readDateTime(linecomp[idxRiseTime]); if (!rise_time.isValid()) { dodgy = true; } // AlarmReason = linecomp[idxAlarmReason].toInt(&ok); // if (!ok) { dodgy = true; } // SnoozeTime = linecomp[idxSnoozeTime].toInt(&ok); // if (!ok) { dodgy = true; } // WakeTone = linecomp[idxWakeTone].toInt(&ok); // if (!ok) { dodgy = true; } // WakeWindow = linecomp[idxWakeWindow].toInt(&ok); // if (!ok) { dodgy = true; } // AlarmType = linecomp[idxAlarmType].toInt(&ok); // if (!ok) { dodgy = true; } if (!linecomp[idxFirstAlaramRing].isEmpty()) { FirstAlarmRing = readDateTime(linecomp[idxFirstAlaramRing]); if (!FirstAlarmRing.isValid()) { dodgy = true; } } if (!linecomp[idxLastAlaramRing].isEmpty()) { LastAlarmRing = readDateTime(linecomp[idxLastAlaramRing]); if (!LastAlarmRing.isValid()) { dodgy = true; } } if (!linecomp[idxFirstSnoozeTime].isEmpty()) { FirstSnoozeTime = readDateTime(linecomp[idxFirstSnoozeTime]); if (!FirstSnoozeTime.isValid()) { dodgy = true; } } if (!linecomp[idxLastSnoozeTime].isEmpty()) { LastSnoozeTime = readDateTime(linecomp[idxLastSnoozeTime]); if (!LastSnoozeTime.isValid()) { dodgy = true; } } if (!linecomp[idxSetAlarmTime].isEmpty()) { SetAlarmTime = readDateTime(linecomp[idxSetAlarmTime]); if (!SetAlarmTime.isValid()) { dodgy = true; } } MorningFeel = linecomp[idxMorningFeel].toInt(&ok); if (!ok) { MorningFeel = 0; } FirmwareVersion = linecomp[idxFirmwareVersion]; if (idxMyZEOVersion >= 0) { MyZeoVersion = linecomp[idxMyZEOVersion]; } if (dodgy) { continue; } SG = linecomp[idxSG].split(" "); DSG = linecomp[idxDSG].split(" "); sid = start_of_night.toTime_t(); if (DSG.size() == 0) { continue; } if (mach->SessionExists(sid)) { continue; } sess = new Session(mach, sid); break; } while (!line.isNull()); if (sess) { const int WindowSize = 30000; sess->settings[ZEO_Awakenings] = Awakenings; sess->settings[ZEO_MorningFeel] = MorningFeel; sess->settings[ZEO_TimeToZ] = TimeToZ; sess->settings[ZEO_ZQ] = ZQ; sess->settings[ZEO_TimeInWake] = TimeInWake; sess->settings[ZEO_TimeInREM] = TimeInREM; sess->settings[ZEO_TimeInLight] = TimeInLight; sess->settings[ZEO_TimeInDeep] = TimeInDeep; st = qint64(start_of_night.toTime_t()) * 1000L; sess->really_set_first(st); tt = st; EventList *sleepstage = sess->AddEventList(ZEO_SleepStage, EVL_Event, 1, 0, 0, 4); for (int i = 0; i < DSG.size(); i++) { stage = DSG[i].toInt(&ok); if (ok) { sleepstage->AddEvent(tt, stage); } tt += WindowSize; } sess->really_set_last(tt); //int size = DSG.size(); //qDebug() << linecomp[0] << start_of_night << end_of_night << rise_time << size << "30 second chunks"; } 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; void ZEOLoader::Register() { if (zeo_initialized) { return; } qDebug("Registering ZEOLoader"); RegisterLoader(new ZEOLoader()); //InitModelMap(); zeo_initialized = true; }