[Pkg-running-devel] [openambit] 30/131: Added initial support for movescount.com syncronisation.
Christian Perrier
bubulle at moszumanska.debian.org
Thu Jul 17 20:19:08 UTC 2014
This is an automated email from the git hooks/post-receive script.
bubulle pushed a commit to branch master
in repository openambit.
commit e23f1f705ed8f8f8accefd366c4c0ac39c1d8203
Author: Emil Ljungdahl <emil at kratern.se>
Date: Thu Jan 9 23:12:40 2014 +0100
Added initial support for movescount.com syncronisation.
---
src/openambit/devicemanager.cpp | 77 +-
src/openambit/devicemanager.h | 15 +-
src/openambit/logentry.cpp | 14 +
src/openambit/logentry.h | 1 +
src/openambit/logstore.cpp | 72 +-
src/openambit/logstore.h | 8 +-
src/openambit/mainwindow.cpp | 111 ++-
src/openambit/mainwindow.h | 15 +-
src/openambit/mainwindow.ui | 79 +-
src/openambit/movescount.cpp | 924 +++++----------------
src/openambit/movescount.h | 71 +-
src/openambit/movescountjson.cpp | 502 +++++++++++
src/openambit/{movescount.h => movescountjson.h} | 44 +-
.../{movescount.cpp => movescountxml.cpp} | 22 +-
src/openambit/{movescount.h => movescountxml.h} | 12 +-
src/openambit/openambit.pro | 8 +-
src/openambit/settingsdialog.cpp | 2 +
src/openambit/settingsdialog.h | 3 +
18 files changed, 1151 insertions(+), 829 deletions(-)
diff --git a/src/openambit/devicemanager.cpp b/src/openambit/devicemanager.cpp
index 60c8e73..a9428a7 100644
--- a/src/openambit/devicemanager.cpp
+++ b/src/openambit/devicemanager.cpp
@@ -24,11 +24,10 @@
#include <QTimer>
#include <libambit.h>
-void DeviceManager::start()
+DeviceManager::DeviceManager(QObject *parent) :
+ QObject(parent)
{
- connect(&chargeTimer, SIGNAL(timeout()), this, SLOT(chargeTimerHit()));
- chargeTimer.setInterval(10000);
- chargeTimer.start();
+ movesCount = MovesCount::instance();
}
DeviceManager::~DeviceManager()
@@ -36,6 +35,13 @@ DeviceManager::~DeviceManager()
chargeTimer.stop();
}
+void DeviceManager::start()
+{
+ connect(&chargeTimer, SIGNAL(timeout()), this, SLOT(chargeTimerHit()));
+ chargeTimer.setInterval(10000);
+ chargeTimer.start();
+}
+
void DeviceManager::detect()
{
int res = -1;
@@ -59,19 +65,60 @@ void DeviceManager::detect()
}
}
-void DeviceManager::startSync(bool readAllLogs = false)
+void DeviceManager::startSync(bool readAllLogs = false, bool syncTime = true, bool syncOrbit = true, bool syncMovescount = false)
{
int res = -1;
+ time_t current_time;
+ struct tm *local_time;
+ uint8_t *orbitData;
+ int orbitDataLen;
mutex.lock();
+ this->syncMovescount = syncMovescount;
+ currentSyncPart = 0;
+ syncParts = 2;
+ if (syncTime) syncParts++;
+ if (syncOrbit) syncParts+=2;
+
if (this->deviceObject != NULL) {
- emit this->syncProgressInform(QString(tr("Reading personal settings")), true, 0);
+ emit this->syncProgressInform(QString(tr("Reading personal settings")), false, true, 0);
res = libambit_personal_settings_get(this->deviceObject, ¤tPersonalSettings);
+ currentSyncPart++;
+
+ libambit_sync_display_show(this->deviceObject);
+
+ if (syncTime && res != -1) {
+ emit this->syncProgressInform(QString(tr("Setting date/time")), false, true, 100*currentSyncPart/syncParts);
+ current_time = time(NULL);
+ local_time = localtime(¤t_time);
+ res = libambit_date_time_set(this->deviceObject, local_time);
+ currentSyncPart++;
+ }
if (res != -1) {
- emit this->syncProgressInform(QString(tr("Reading log files")), true, 0);
+ emit this->syncProgressInform(QString(tr("Reading log files")), false, true, 100*currentSyncPart/syncParts);
res = libambit_log_read(this->deviceObject, readAllLogs ? NULL : &log_skip_cb, &log_push_cb, &log_progress_cb, this);
+ currentSyncPart++;
+ }
+
+ if (syncOrbit && res != -1) {
+ emit this->syncProgressInform(QString(tr("Fetching orbital data")), false, true, 100*currentSyncPart/syncParts);
+ if ((orbitDataLen = movesCount->getOrbitalData(&orbitData)) != -1) {
+ currentSyncPart++;
+ emit this->syncProgressInform(QString(tr("Writing orbital data")), false, false, 100*currentSyncPart/syncParts);
+ res = libambit_gps_orbit_write(this->deviceObject, orbitData, orbitDataLen);
+ free(orbitData);
+ }
+ else {
+ currentSyncPart++;
+ emit this->syncProgressInform(QString(tr("Failed to get orbital data")), true, false, 100*currentSyncPart/syncParts);
+ res = -1;
+ }
+
+ currentSyncPart++;
}
+
+ libambit_sync_display_clear(this->deviceObject);
}
mutex.unlock();
@@ -118,16 +165,22 @@ int DeviceManager::log_skip_cb(void *ref, ambit_log_header_t *log_header)
void DeviceManager::log_push_cb(void *ref, ambit_log_entry_t *log_entry)
{
DeviceManager *manager = static_cast<DeviceManager*> (ref);
- LogEntry *entry = manager->logStore.store(QString(manager->currentDeviceInfo.serial), &manager->currentPersonalSettings, log_entry);
+ LogEntry *entry = manager->logStore.store(&manager->currentDeviceInfo, &manager->currentPersonalSettings, log_entry);
if (entry != NULL) {
- manager->movesCount.sendLog(entry);
- }
+ //! TODO: make this optional, only used for debugging
+ manager->movesCountXML.writeLog(entry);
- delete entry;
+ if (manager->syncMovescount) {
+ manager->movesCount->writeLog(entry);
+ }
+
+ delete entry;
+ }
}
void DeviceManager::log_progress_cb(void *ref, uint16_t log_count, uint16_t log_current, uint8_t progress_percent)
{
DeviceManager *manager = static_cast<DeviceManager*> (ref);
- emit manager->syncProgressInform(QString(tr("Downloading message %1 of %2")).arg(log_current).arg(log_count), false, progress_percent);
+ progress_percent = 100*manager->currentSyncPart/manager->syncParts + progress_percent*1/manager->syncParts;
+ emit manager->syncProgressInform(QString(tr("Downloading message %1 of %2")).arg(log_current).arg(log_count), false, false, progress_percent);
}
diff --git a/src/openambit/devicemanager.h b/src/openambit/devicemanager.h
index aa7e1f6..7f8a683 100644
--- a/src/openambit/devicemanager.h
+++ b/src/openambit/devicemanager.h
@@ -31,23 +31,25 @@
#include "settings.h"
#include "logstore.h"
#include "movescount.h"
+#include "movescountxml.h"
#include <libambit.h>
class DeviceManager : public QObject
{
Q_OBJECT
public:
- void start();
+ explicit DeviceManager(QObject *parent = 0);
~DeviceManager();
+ void start();
signals:
void deviceDetected(ambit_device_info_t deviceInfo, bool supported);
void deviceRemoved(void);
void deviceCharge(quint8 percent);
void syncFinished(bool success);
- void syncProgressInform(QString message, bool newRow, quint8 percentDone);
+ void syncProgressInform(QString message, bool error, bool newRow, quint8 percentDone);
public slots:
void detect(void);
- void startSync(bool readAllLogs);
+ void startSync(bool readAllLogs, bool syncTime, bool syncOrbit, bool syncMovescount);
private slots:
void chargeTimerHit();
@@ -61,9 +63,14 @@ private:
ambit_device_info_t currentDeviceInfo;
ambit_personal_settings_t currentPersonalSettings;
+ int syncParts;
+ int currentSyncPart;
+ bool syncMovescount;
+
QMutex mutex;
QTimer chargeTimer;
- MovesCount movesCount;
+ MovesCount *movesCount;
+ MovesCountXML movesCountXML;
Settings settings;
LogStore logStore;
};
diff --git a/src/openambit/logentry.cpp b/src/openambit/logentry.cpp
index b09dfcd..b4c8654 100644
--- a/src/openambit/logentry.cpp
+++ b/src/openambit/logentry.cpp
@@ -29,6 +29,14 @@ LogEntry::LogEntry(const LogEntry &other)
{
u_int32_t i;
+ if (other.deviceInfo != NULL) {
+ deviceInfo = (ambit_device_info_t*)malloc(sizeof(ambit_device_info_t));
+ memcpy(deviceInfo, other.deviceInfo, sizeof(ambit_device_info_t));
+ }
+ else {
+ deviceInfo = NULL;
+ }
+
if (other.personalSettings != NULL) {
personalSettings = (ambit_personal_settings_t*)malloc(sizeof(ambit_personal_settings_t));
memcpy(personalSettings, other.personalSettings, sizeof(ambit_personal_settings_t));
@@ -73,6 +81,7 @@ LogEntry& LogEntry::operator=(const LogEntry &rhs)
std::swap(device, tmp.device);
std::swap(time, tmp.time);
+ std::swap(deviceInfo, tmp.deviceInfo);
std::swap(personalSettings, tmp.personalSettings);
std::swap(logEntry, tmp.logEntry);
@@ -83,6 +92,11 @@ LogEntry::~LogEntry()
{
u_int32_t i;
+ if (deviceInfo != NULL) {
+ free(deviceInfo);
+ deviceInfo = NULL;
+ }
+
if (personalSettings != NULL) {
free(personalSettings);
personalSettings = NULL;
diff --git a/src/openambit/logentry.h b/src/openambit/logentry.h
index 62465bc..23dc3e9 100644
--- a/src/openambit/logentry.h
+++ b/src/openambit/logentry.h
@@ -36,6 +36,7 @@ public:
QString device;
QDateTime time;
+ ambit_device_info_t *deviceInfo = NULL;
ambit_personal_settings_t *personalSettings = NULL;
ambit_log_entry_t *logEntry = NULL;
signals:
diff --git a/src/openambit/logstore.cpp b/src/openambit/logstore.cpp
index e8f60bf..248b777 100644
--- a/src/openambit/logstore.cpp
+++ b/src/openambit/logstore.cpp
@@ -94,14 +94,14 @@ LogStore::LogStore(QObject *parent) :
storagePath = QString(getenv("HOME")) + "/.openambit";
}
-LogEntry *LogStore::store(QString device, ambit_personal_settings_t *personalSettings, ambit_log_entry_t *logEntry)
+LogEntry *LogStore::store(ambit_device_info_t *deviceInfo, ambit_personal_settings_t *personalSettings, ambit_log_entry_t *logEntry)
{
LogEntry *retEntry = new LogEntry();
QDateTime dateTime(QDate(logEntry->header.date_time.year, logEntry->header.date_time.month, logEntry->header.date_time.day),
QTime(logEntry->header.date_time.hour, logEntry->header.date_time.minute, logEntry->header.date_time.msec/1000));
- XMLWriter writer(device, dateTime, personalSettings, logEntry);
- QFile logfile(logEntryPath(device, dateTime));
+ XMLWriter writer(deviceInfo, dateTime, personalSettings, logEntry);
+ QFile logfile(logEntryPath(QString(deviceInfo->serial), dateTime));
logfile.open(QIODevice::WriteOnly);
writer.write(&logfile);
logfile.close();
@@ -227,6 +227,9 @@ void LogStore::XMLReader::readRoot()
else if (xml.name() == "Time") {
readTime();
}
+ else if (xml.name() == "DeviceInfo") {
+ readDeviceInfo();
+ }
else if (xml.name() == "PersonalSettings") {
readPersonalSettings();
}
@@ -254,6 +257,49 @@ void LogStore::XMLReader::readTime()
logEntry->time = QDateTime::fromString(datestring, Qt::ISODate);
}
+void LogStore::XMLReader::readDeviceInfo()
+{
+ QRegExp versionRX("([0-9]+)\\.([0-9]+)\\.([0-9]+)");
+
+ Q_ASSERT(xml.isStartElement() && xml.name() == "DeviceInfo");
+
+ if (logEntry->deviceInfo == NULL) {
+ logEntry->deviceInfo = (ambit_device_info_t*)malloc(sizeof(ambit_device_info_t));
+ memset(logEntry->deviceInfo, 0, sizeof(ambit_device_info_t));
+ }
+
+ while (xml.readNextStartElement()) {
+ if (xml.name() == "Serial") {
+ strcpy(logEntry->deviceInfo->serial, xml.readElementText().toAscii().data());
+ }
+ else if (xml.name() == "Model") {
+ strcpy(logEntry->deviceInfo->model, xml.readElementText().toAscii().data());
+ }
+ else if (xml.name() == "Name") {
+ strcpy(logEntry->deviceInfo->name, xml.readElementText().toAscii().data());
+ }
+ else if (xml.name() == "FWVersion") {
+ if (versionRX.indexIn(xml.readElementText()) >= 0) {
+ logEntry->deviceInfo->fw_version[0] = versionRX.cap(1).toInt();
+ logEntry->deviceInfo->fw_version[1] = versionRX.cap(2).toInt();
+ logEntry->deviceInfo->fw_version[2] = versionRX.cap(3).toInt() & 0xff;
+ logEntry->deviceInfo->fw_version[3] = (versionRX.cap(3).toInt() >> 8) & 0xff;
+ }
+ }
+ else if (xml.name() == "HWVersion") {
+ if (versionRX.indexIn(xml.readElementText()) >= 0) {
+ logEntry->deviceInfo->hw_version[0] = versionRX.cap(1).toInt();
+ logEntry->deviceInfo->hw_version[1] = versionRX.cap(2).toInt();
+ logEntry->deviceInfo->hw_version[2] = versionRX.cap(3).toInt() & 0xff;
+ logEntry->deviceInfo->hw_version[3] = (versionRX.cap(3).toInt() >> 8) & 0xff;
+ }
+ }
+ else {
+ xml.skipCurrentElement();
+ }
+ }
+}
+
void LogStore::XMLReader::readPersonalSettings()
{
Q_ASSERT(xml.isStartElement() && xml.name() == "PersonalSettings");
@@ -1112,8 +1158,8 @@ void LogStore::XMLReader::readPeriodicSample(QList<ambit_log_sample_periodic_val
}
-LogStore::XMLWriter::XMLWriter(QString serial, QDateTime time, ambit_personal_settings_t *personalSettings, ambit_log_entry_t *logEntry) :
- serial(serial), time(time), personalSettings(personalSettings), logEntry(logEntry)
+LogStore::XMLWriter::XMLWriter(ambit_device_info_t *deviceInfo, QDateTime time, ambit_personal_settings_t *personalSettings, ambit_log_entry_t *logEntry) :
+ deviceInfo(deviceInfo), time(time), personalSettings(personalSettings), logEntry(logEntry)
{
xml.setAutoFormatting(true);
}
@@ -1129,8 +1175,9 @@ bool LogStore::XMLWriter::write(QIODevice *device)
xml.writeStartElement("openambitlog");
xml.writeAttribute("version", "1.0");
- xml.writeTextElement("SerialNumber", serial);
+ xml.writeTextElement("SerialNumber", QString("%1").arg(deviceInfo->serial));
xml.writeTextElement("Time", time.toString(Qt::ISODate));
+ ret = writeDeviceInfo();
ret = writePersonalSettings();
if (ret) {
ret = writeLogEntry();
@@ -1141,6 +1188,19 @@ bool LogStore::XMLWriter::write(QIODevice *device)
return ret;
}
+bool LogStore::XMLWriter::writeDeviceInfo()
+{
+ xml.writeStartElement("DeviceInfo");
+ xml.writeTextElement("Serial", QString("%1").arg(deviceInfo->serial));
+ xml.writeTextElement("Model", QString("%1").arg(deviceInfo->model));
+ xml.writeTextElement("Name", QString("%1").arg(deviceInfo->name));
+ xml.writeTextElement("FWVersion", QString("%1.%2.%3").arg((int)deviceInfo->fw_version[0]).arg((int)deviceInfo->fw_version[1]).arg((int)deviceInfo->fw_version[2] | ((int)deviceInfo->fw_version[3] << 8)));
+ xml.writeTextElement("HWVersion", QString("%1.%2.%3").arg((int)deviceInfo->hw_version[0]).arg((int)deviceInfo->hw_version[1]).arg((int)deviceInfo->hw_version[2] | ((int)deviceInfo->hw_version[3] << 8)));
+ xml.writeEndElement();
+
+ return true;
+}
+
bool LogStore::XMLWriter::writePersonalSettings()
{
xml.writeStartElement("PersonalSettings");
diff --git a/src/openambit/logstore.h b/src/openambit/logstore.h
index adaf484..32e5443 100644
--- a/src/openambit/logstore.h
+++ b/src/openambit/logstore.h
@@ -45,7 +45,7 @@ public:
};
explicit LogStore(QObject *parent = 0);
- LogEntry *store(QString device, ambit_personal_settings_t *personalSettings, ambit_log_entry_t *logEntry);
+ LogEntry *store(ambit_device_info_t *deviceInfo, ambit_personal_settings_t *personalSettings, ambit_log_entry_t *logEntry);
bool logExists(QString device, ambit_log_header_t *logHeader);
LogEntry *read(QString device, QDateTime time);
LogEntry *read(LogDirEntry dirEntry);
@@ -71,6 +71,7 @@ private:
void readRoot();
void readSerial();
void readTime();
+ void readDeviceInfo();
void readPersonalSettings();
void readLog();
void readLogHeader();
@@ -83,16 +84,17 @@ private:
class XMLWriter
{
public:
- XMLWriter(QString serial, QDateTime time, ambit_personal_settings_t *personalSettings, ambit_log_entry_t *logEntry);
+ XMLWriter(ambit_device_info_t *deviceInfo, QDateTime time, ambit_personal_settings_t *personalSettings, ambit_log_entry_t *logEntry);
bool write(QIODevice *device);
private:
+ bool writeDeviceInfo();
bool writePersonalSettings();
bool writeLogEntry();
bool writeLogSample(ambit_log_sample_t *sample);
bool writePeriodicSample(ambit_log_sample_t *sample);
- QString serial;
+ ambit_device_info_t *deviceInfo;
QDateTime time;
QXmlStreamWriter xml;
ambit_personal_settings_t *personalSettings;
diff --git a/src/openambit/mainwindow.cpp b/src/openambit/mainwindow.cpp
index 07f3337..eec67a1 100644
--- a/src/openambit/mainwindow.cpp
+++ b/src/openambit/mainwindow.cpp
@@ -24,6 +24,9 @@
#include <QListWidgetItem>
+#define APPKEY "HpF9f1qV5qrDJ1hY1QK1diThyPsX10Mh4JvCw9xVQSglJNLdcwr3540zFyLzIC3e"
+#define MOVESCOUNT_DEFAULT_URL "https://uiservices.movescount.com/"
+
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
@@ -32,9 +35,16 @@ MainWindow::MainWindow(QWidget *parent) :
// Setup UI parts
QIcon warningIcon = QIcon::fromTheme("dialog-warning");
+ QIcon infoIcon = QIcon::fromTheme("dialog-information");
ui->labelNotSupportedIcon->setPixmap(warningIcon.pixmap(8,8));
ui->labelNotSupportedIcon->setHidden(true);
ui->labelNotSupported->setHidden(true);
+ ui->labelMovescountAuthIcon->setPixmap(warningIcon.pixmap(8,8));
+ ui->labelMovescountAuthIcon->setHidden(true);
+ ui->labelMovescountAuth->setHidden(true);
+ ui->labelNewFirmwareIcon->setPixmap(infoIcon.pixmap(8,8));
+ ui->labelNewFirmwareIcon->setHidden(true);
+ ui->labelNewFirmware->setHidden(true);
ui->labelCharge->setHidden(true);
ui->chargeIndicator->setHidden(true);
ui->checkBoxResyncAll->setHidden(true);
@@ -51,10 +61,10 @@ MainWindow::MainWindow(QWidget *parent) :
connect(deviceManager, SIGNAL(deviceRemoved()), this, SLOT(deviceRemoved()), Qt::QueuedConnection);
connect(deviceManager, SIGNAL(deviceCharge(quint8)), this, SLOT(deviceCharge(quint8)), Qt::QueuedConnection);
connect(deviceManager, SIGNAL(syncFinished(bool)), this, SLOT(syncFinished(bool)), Qt::QueuedConnection);
- connect(deviceManager, SIGNAL(syncProgressInform(QString,bool,quint8)), this, SLOT(syncProgressInform(QString,bool,quint8)), Qt::QueuedConnection);
+ connect(deviceManager, SIGNAL(syncProgressInform(QString,bool,bool,quint8)), this, SLOT(syncProgressInform(QString,bool,bool,quint8)), Qt::QueuedConnection);
connect(ui->buttonDeviceReload, SIGNAL(clicked()), deviceManager, SLOT(detect()));
connect(ui->buttonSyncNow, SIGNAL(clicked()), this, SLOT(syncNowClicked()));
- connect(this, SIGNAL(syncNow(bool)), deviceManager, SLOT(startSync(bool)));
+ connect(this, SIGNAL(syncNow(bool,bool,bool,bool)), deviceManager, SLOT(startSync(bool,bool,bool,bool)));
deviceWorkerThread.start();
deviceManager->start();
deviceManager->detect();
@@ -65,6 +75,9 @@ MainWindow::MainWindow(QWidget *parent) :
connect(ui->logsList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenuForLogItem(QPoint)));
updateLogList();
+
+ // Setup Movescount
+ movesCountSetup();
}
MainWindow::~MainWindow()
@@ -78,11 +91,20 @@ void MainWindow::showSettings()
{
settingsDialog = new SettingsDialog(this);
settingsDialog->setModal(true);
+ connect(settingsDialog, SIGNAL(settingsSaved()), this, SLOT(settingsSaved()));
settingsDialog->show();
}
+void MainWindow::settingsSaved()
+{
+ // Update Movescount
+ movesCountSetup();
+}
+
void MainWindow::syncNowClicked()
{
+ bool syncTime, syncOrbit, syncMovescount;
+
ui->checkBoxResyncAll->setEnabled(false);
ui->buttonSyncNow->setEnabled(false);
currentLogMessageRow = NULL;
@@ -93,7 +115,15 @@ void MainWindow::syncNowClicked()
}
ui->syncProgressBar->setHidden(false);
ui->syncProgressBar->setValue(0);
- emit MainWindow::syncNow(ui->checkBoxResyncAll->isChecked());
+
+ settings.beginGroup("syncSettings");
+ syncTime = settings.value("syncTime", true).toBool();
+ syncOrbit = settings.value("syncOrbit", true).toBool();
+ settings.endGroup();
+ settings.beginGroup("movescountSettings");
+ syncMovescount = settings.value("movescountEnable", true).toBool();
+ settings.endGroup();
+ emit MainWindow::syncNow(ui->checkBoxResyncAll->isChecked(), syncTime, syncOrbit, syncMovescount);
}
void MainWindow::deviceDetected(ambit_device_info_t deviceInfo, bool supported)
@@ -103,6 +133,10 @@ void MainWindow::deviceDetected(ambit_device_info_t deviceInfo, bool supported)
if (!supported) {
ui->labelNotSupportedIcon->setHidden(false);
ui->labelNotSupported->setHidden(false);
+ ui->labelMovescountAuthIcon->setHidden(true);
+ ui->labelMovescountAuth->setHidden(true);
+ ui->labelNewFirmwareIcon->setHidden(true);
+ ui->labelNewFirmware->setHidden(true);
ui->labelCharge->setHidden(true);
ui->chargeIndicator->setHidden(true);
ui->checkBoxResyncAll->setHidden(true);
@@ -112,10 +146,27 @@ void MainWindow::deviceDetected(ambit_device_info_t deviceInfo, bool supported)
else {
ui->labelNotSupportedIcon->setHidden(true);
ui->labelNotSupported->setHidden(true);
+ ui->labelMovescountAuthIcon->setHidden(true);
+ ui->labelMovescountAuth->setHidden(true);
+ ui->labelNewFirmwareIcon->setHidden(true);
+ ui->labelNewFirmware->setHidden(true);
ui->labelCharge->setHidden(false);
ui->chargeIndicator->setHidden(false);
ui->checkBoxResyncAll->setHidden(false);
ui->buttonSyncNow->setHidden(false);
+
+ movesCountSetup();
+ if (movesCount != NULL) {
+ movesCount->setDevice(&deviceInfo);
+ settings.beginGroup("movescountSettings");
+ if (settings.value("checkNewVersions", true).toBool()) {
+ movesCount->checkLatestFirmwareVersion();
+ }
+ if (settings.value("movescountEnable", true).toBool()) {
+ movesCount->getDeviceSettings();
+ }
+ settings.endGroup();
+ }
}
}
@@ -125,6 +176,10 @@ void MainWindow::deviceRemoved(void)
ui->labelSerial->setText("");
ui->labelNotSupportedIcon->setHidden(true);
ui->labelNotSupported->setHidden(true);
+ ui->labelMovescountAuthIcon->setHidden(true);
+ ui->labelMovescountAuth->setHidden(true);
+ ui->labelNewFirmwareIcon->setHidden(true);
+ ui->labelNewFirmware->setHidden(true);
ui->labelCharge->setHidden(true);
ui->chargeIndicator->setHidden(true);
ui->checkBoxResyncAll->setHidden(true);
@@ -162,7 +217,7 @@ void MainWindow::syncFinished(bool success)
updateLogList();
}
-void MainWindow::syncProgressInform(QString message, bool newRow, quint8 percentDone)
+void MainWindow::syncProgressInform(QString message, bool error, bool newRow, quint8 percentDone)
{
if (newRow) {
if (currentLogMessageRow != NULL) {
@@ -176,11 +231,27 @@ void MainWindow::syncProgressInform(QString message, bool newRow, quint8 percent
else {
if (currentLogMessageRow != NULL) {
currentLogMessageRow->setMessage(message);
+ if (error) {
+ currentLogMessageRow->setStatus(LogMessageRow::StatusFailed);
+ }
}
}
ui->syncProgressBar->setValue(percentDone);
}
+void MainWindow::newerFirmwareExists(QByteArray fw_version)
+{
+ ui->labelNewFirmware->setText(QString(tr("Newer firmware exists (%1.%2.%3)")).arg((int)fw_version[0]).arg((int)fw_version[1]).arg((int)(fw_version[2] | ((int)fw_version[3] << 8))));
+ ui->labelNewFirmware->setHidden(false);
+ ui->labelNewFirmwareIcon->setHidden(false);
+}
+
+void MainWindow::movesCountAuth(bool authorized)
+{
+ ui->labelMovescountAuth->setHidden(authorized);
+ ui->labelMovescountAuthIcon->setHidden(authorized);
+}
+
void MainWindow::logItemSelected(QListWidgetItem *current,QListWidgetItem *previous)
{
LogEntry *logEntry = NULL;
@@ -209,7 +280,8 @@ void MainWindow::logItemWriteMovescount()
logEntry = logStore.read(ui->logsList->selectedItems().at(0)->data(Qt::UserRole).toString());
if (logEntry != NULL) {
- movesCount.sendLog(logEntry);
+ movesCount->writeLog(logEntry);
+ movesCountXML.writeLog(logEntry);
delete logEntry;
}
}
@@ -264,3 +336,32 @@ void MainWindow::LogMessageRow::setStatus(Status status)
}
iconLabel->setPixmap(icon.pixmap(8,8));
}
+
+void MainWindow::movesCountSetup()
+{
+ bool syncOrbit = false;
+ bool movescountEnable = false;
+
+ settings.beginGroup("syncSettings");
+ syncOrbit = settings.value("syncOrbit").toBool();
+ settings.endGroup();
+
+ settings.beginGroup("movescountSettings");
+ movescountEnable = settings.value("movescountEnable").toBool();
+ if (syncOrbit || movescountEnable) {
+ if (movesCount == NULL) {
+ movesCount = MovesCount::instance();
+ movesCount->setAppkey(APPKEY);
+ movesCount->setBaseAddress(settings.value("movescountBaseAddress", MOVESCOUNT_DEFAULT_URL).toString());
+ if (settings.value("movescountUserkey", "").toString().length() == 0) {
+ settings.setValue("movescountUserkey", movesCount->generateUserkey());
+ }
+ movesCount->setUserkey(settings.value("movescountUserkey").toString());
+
+ connect(movesCount, SIGNAL(newerFirmwareExists(QByteArray)), this, SLOT(newerFirmwareExists(QByteArray)), Qt::QueuedConnection);
+ connect(movesCount, SIGNAL(movesCountAuth(bool)), this, SLOT(movesCountAuth(bool)), Qt::QueuedConnection);
+ }
+ movesCount->setUsername(settings.value("email").toString());
+ }
+ settings.endGroup();
+}
diff --git a/src/openambit/mainwindow.h b/src/openambit/mainwindow.h
index f4632bd..301fdbf 100644
--- a/src/openambit/mainwindow.h
+++ b/src/openambit/mainwindow.h
@@ -24,6 +24,7 @@
#include "devicemanager.h"
#include "settingsdialog.h"
+#include "movescount.h"
#include <QMainWindow>
#include <QThread>
#include <QVBoxLayout>
@@ -43,10 +44,11 @@ public:
~MainWindow();
signals:
- void syncNow(bool readAll);
+ void syncNow(bool readAll, bool syncTime, bool syncOrbit, bool syncMovescount);
private slots:
void showSettings();
+ void settingsSaved();
void syncNowClicked();
@@ -54,7 +56,10 @@ private slots:
void deviceRemoved();
void deviceCharge(quint8 percent);
void syncFinished(bool success);
- void syncProgressInform(QString message, bool newRow, quint8 percentDone);
+ void syncProgressInform(QString message, bool error, bool newRow, quint8 percentDone);
+
+ void newerFirmwareExists(QByteArray fw_version);
+ void movesCountAuth(bool authorized);
void logItemSelected(QListWidgetItem *current,QListWidgetItem *previous);
void showContextMenuForLogItem(const QPoint &pos);
@@ -66,11 +71,15 @@ private:
void updateLogMessageRow(QString message);
void finalizeLogMessageRow();
+ void movesCountSetup();
+
Ui::MainWindow *ui;
+ Settings settings;
SettingsDialog *settingsDialog;
DeviceManager *deviceManager;
LogStore logStore;
- MovesCount movesCount;
+ MovesCountXML movesCountXML;
+ MovesCount *movesCount = NULL;
QThread deviceWorkerThread;
class LogMessageRow : public QHBoxLayout
diff --git a/src/openambit/mainwindow.ui b/src/openambit/mainwindow.ui
index c3988c8..8b76f79 100644
--- a/src/openambit/mainwindow.ui
+++ b/src/openambit/mainwindow.ui
@@ -132,12 +132,18 @@
</widget>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <layout class="QHBoxLayout" name="horizontalLayoutNotSupported">
<item>
<widget class="QLabel" name="labelNotSupported">
<property name="enabled">
<bool>true</bool>
</property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="text">
<string>Device not supported yet!</string>
</property>
@@ -145,9 +151,78 @@
</item>
<item>
<widget class="QLabel" name="labelNotSupportedIcon">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="text">
<string/>
</property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayoutMovescountAuth">
+ <item>
+ <widget class="QLabel" name="labelMovescountAuth">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Auth on movescount.com!</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelMovescountAuthIcon">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayoutNewFirmware">
+ <item>
+ <widget class="QLabel" name="labelNewFirmware">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelNewFirmwareIcon">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
</widget>
</item>
</layout>
@@ -255,7 +330,7 @@
<x>0</x>
<y>0</y>
<width>872</width>
- <height>20</height>
+ <height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuOpenambit">
diff --git a/src/openambit/movescount.cpp b/src/openambit/movescount.cpp
index 37cc842..5a1b311 100644
--- a/src/openambit/movescount.cpp
+++ b/src/openambit/movescount.cpp
@@ -20,787 +20,261 @@
*
*/
#include "movescount.h"
-#include <QFile>
-
-#define _USE_MATH_DEFINES
-#include <math.h>
-
-typedef struct typename_lookup_entry_s {
- u_int8_t id;
- QString XMLName;
-} typename_lookup_entry_t;
-
-static typename_lookup_entry_t sampleDistanceSourceNames[] = {
- { 0x02, "Gps" },
- { 0x03, "Wrist" },
- { 0, "" }
-};
-
-static typename_lookup_entry_t sampleAltitudeSourceNames[] = {
- { 0x04, "Pressure" },
- { 0, "" }
-};
-
-static typename_lookup_entry_t sampleLapEventTypeNames[] = {
- { 0x01, "Manual" },
- { 0x14, "High Interval" },
- { 0x15, "Low Interval" },
- { 0x16, "Interval" },
- { 0x1e, "Pause" },
- { 0x1f, "Start" },
- { 0, "" }
-};
-
-static typename_lookup_entry_t sampleActivityNames[] = {
- { 0x01, "Not Specified Sport" },
- { 0x02, "Multisport" },
- { 0x03, "Run" },
- { 0x04, "Cycling" },
- { 0x05, "Mountain Biking" },
- { 0x06, "UNDEFINED7" },
- { 0x07, "Skating" },
- { 0x08, "Aerobics" },
- { 0x09, "Yoga Pilates" },
- { 0x0a, "Trekking" },
- { 0x0b, "Walking" },
- { 0x0c, "Sailing" },
- { 0x0d, "Kayaking" },
- { 0x0e, "Rowing" },
- { 0x0f, "Climbing" },
- { 0x10, "Indoor Cycling" },
- { 0x11, "Circuit Training" },
- { 0x12, "Triathlon" },
- { 0x13, "Alpine Skiing" },
- { 0x14, "Snowboarding" },
- { 0x15, "Crosscountry Skiing" },
- { 0x16, "Weight Training" },
- { 0x17, "Basketball" },
- { 0x18, "Soccer" },
- { 0x19, "Ice Hockey" },
- { 0x1a, "Volleyball" },
- { 0x1b, "Football" },
- { 0x1c, "Softball" },
- { 0x1d, "Cheerleading" },
- { 0x1e, "Baseball" },
- { 0x1f, "UNDEFINED32" },
- { 0x20, "Tennis" },
- { 0x21, "Badminton" },
- { 0x22, "Table Tenni" },
- { 0x23, "Racquet Ball" },
- { 0x24, "Squash" },
- { 0x25, "Combat Sport" },
- { 0x26, "Boxing" },
- { 0x27, "Floorball" },
- { 0x28, "UNDEFINED41" },
- { 0x29, "UNDEFINED42" },
- { 0x2a, "UNDEFINED43" },
- { 0x2b, "UNDEFINED44" },
- { 0x2c, "UNDEFINED45" },
- { 0x2d, "UNDEFINED46" },
- { 0x2e, "UNDEFINED47" },
- { 0x2f, "UNDEFINED48" },
- { 0x30, "UNDEFINED49" },
- { 0x31, "UNDEFINED50" },
- { 0x32, "Scuba Diving" },
- { 0x33, "Free Diving" },
- { 0x34, "UNDEFINED53" },
- { 0x35, "UNDEFINED54" },
- { 0x36, "UNDEFINED55" },
- { 0x37, "UNDEFINED56" },
- { 0x38, "UNDEFINED57" },
- { 0x39, "UNDEFINED58" },
- { 0x3a, "UNDEFINED59" },
- { 0x3b, "UNDEFINED60" },
- { 0x3c, "Adventure Racing" },
- { 0x3d, "Bowling" },
- { 0x3e, "Cricket" },
- { 0x3f, "Crosstrainer" },
- { 0x40, "Dancing" },
- { 0x41, "Golf" },
- { 0x42, "Gymnastics" },
- { 0x43, "Handball" },
- { 0x44, "Horseback Riding" },
- { 0x45, "Ice Skating" },
- { 0x46, "Indoor Rowing" },
- { 0x47, "Canoeing" },
- { 0x48, "Motorsports" },
- { 0x49, "Mountaineering" },
- { 0x4a, "Orienteering" },
- { 0x4b, "Rugby" },
- { 0x4c, "UNDEFINED77" },
- { 0x4d, "Ski Touring" },
- { 0x4e, "Stretching" },
- { 0x4f, "Telemark Skiing" },
- { 0x50, "Track And Field" },
- { 0x51, "Trail Running" },
- { 0x52, "Openwater Swimming" },
- { 0x53, "UNDEFINED84" },
- { 0x54, "UNDEFINED85" },
- { 0x55, "UNDEFINED86" },
- { 0x56, "UNDEFINED87" },
- { 0x57, "UNDEFINED88" },
- { 0x58, "UNDEFINED89" },
- { 0x59, "UNDEFINED90" },
- { 0x5a, "UNDEFINED91" },
- { 0x5b, "UNDEFINED92" },
- { 0x5c, "UNDEFINED93" },
- { 0x5d, "UNDEFINED94" },
- { 0x5e, "UNDEFINED95" },
- { 0x5f, "UNDEFINED96" },
- { 0x60, "UNDEFINED97" },
- { 0x61, "UNDEFINED98" },
- { 0x62, "UNDEFINED99" },
- { 0x63, "Other" },
- { 0x64, "Butterfly" },
- { 0x65, "Backstroke" },
- { 0x66, "Breaststroke" },
- { 0x67, "Freestyle" },
- { 0x68, "Drill" },
- { 0, "" }
-};
-
-MovesCount::MovesCount(QObject *parent) :
- QObject(parent)
+#include <QtNetwork/QNetworkRequest>
+#include <QEventLoop>
+#include <QMutex>
+
+#include <qdebug.h>
+
+#define AUTH_CHECK_TIMEOUT 5000 /* ms */
+#define GPS_ORBIT_DATA_MIN_SIZE 30000 /* byte */
+
+static MovesCount *m_Instance;
+
+MovesCount* MovesCount::instance()
{
- storagePath = QString(getenv("HOME")) + "/.openambit/movescount";
+ static QMutex mutex;
+ if (!m_Instance) {
+ mutex.lock();
+
+ if (!m_Instance)
+ m_Instance = new MovesCount;
+
+ mutex.unlock();
+ }
+
+ return m_Instance;
}
-void MovesCount::sendLog(LogEntry *logEntry)
+void MovesCount::setBaseAddress(QString baseAddress)
{
- XMLWriter writer(logEntry);
- QFile logfile(logEntryPath(logEntry));
- logfile.open(QIODevice::WriteOnly | QIODevice::Truncate);
-
- writer.write(&logfile);
+ this->baseAddress = baseAddress;
+ if (this->baseAddress[this->baseAddress.length()-1] == '/') {
+ this->baseAddress = this->baseAddress.remove(this->baseAddress.length()-1, 1);
+ }
+}
- logfile.close();
+void MovesCount::setAppkey(QString appkey)
+{
+ this->appkey = appkey;
}
-QString MovesCount::logEntryPath(LogEntry *logEntry)
+void MovesCount::setUsername(QString username)
{
- return storagePath + "/log-" + logEntry->device + "-" + logEntry->time.toString("yyyy-MM-ddThh_mm_ss") + "-0.log";
+ this->username = username;
}
-MovesCount::XMLWriter::XMLWriter(LogEntry *logEntry) :
- logEntry(logEntry)
+void MovesCount::setUserkey(QString userkey)
{
- xml.setAutoFormatting(true);
- xml.setAutoFormattingIndent(-1);
+ this->userkey = userkey;
}
-bool MovesCount::XMLWriter::write(QIODevice *device)
+QString MovesCount::generateUserkey()
{
- bool ret = true;
+ char randString[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+ QString retString = "";
- xml.setDevice(device);
+ for (int i=0; i<14; i++) {
+ retString += QString(randString[qrand() % sizeof(randString)]);
+ }
- xml.writeStartDocument();
- ret = writeLogEntry();
- xml.writeEndDocument();
+ return retString;
+}
- return ret;
+void MovesCount::setDevice(ambit_device_info_t *device_info)
+{
+ memcpy(&this->device_info, device_info, sizeof(ambit_device_info_t));
}
-bool MovesCount::XMLWriter::writeLogEntry()
+bool MovesCount::isAuthorized()
{
- u_int32_t i;
-
- xml.writeStartElement("header");
- xml.writeTextElement("Duration", QString::number((double)logEntry->logEntry->header.duration/1000.0, 'g', 16));
- xml.writeTextElement("Ascent", QString("%1").arg(logEntry->logEntry->header.ascent));
- xml.writeTextElement("Descent", QString("%1").arg(logEntry->logEntry->header.descent));
- xml.writeTextElement("AscentTime", QString::number((double)logEntry->logEntry->header.ascent_time/1000.0, 'g', 16));
- xml.writeTextElement("DescentTime", QString::number((double)logEntry->logEntry->header.descent_time/1000.0, 'g', 16));
- xml.writeTextElement("RecoveryTime", QString::number((double)logEntry->logEntry->header.recovery_time/1000.0, 'g', 16));
- xml.writeStartElement("Speed");
- xml.writeTextElement("Avg", QString::number((double)logEntry->logEntry->header.speed_avg/3600.0, 'g', 16));
- xml.writeTextElement("Max", QString::number((double)logEntry->logEntry->header.speed_max/3600.0, 'g', 16));
- xml.writeTextElement("MaxTime", QString::number((double)logEntry->logEntry->header.speed_max_time/1000.0, 'g', 16));
- xml.writeEndElement();
- // We have no idea about cadence yet, but we better include an empty tag!
- xml.writeStartElement("Cadence");
- xml.writeTextElement("MaxTime", QString::number(0));
- xml.writeEndElement();
- xml.writeStartElement("Altitude");
- xml.writeTextElement("Max", QString("%1").arg(logEntry->logEntry->header.altitude_max));
- xml.writeTextElement("Min", QString("%1").arg(logEntry->logEntry->header.altitude_min));
- xml.writeTextElement("MaxTime", QString::number((double)logEntry->logEntry->header.altitude_max_time/1000.0, 'g', 16));
- xml.writeTextElement("MinTime", QString::number((double)logEntry->logEntry->header.altitude_min_time/1000.0, 'g', 16));
- xml.writeEndElement();
- // Only include HR if heartrate seems to be present
- if (logEntry->logEntry->header.heartrate_avg != 0) {
- xml.writeStartElement("HR");
- xml.writeTextElement("Avg", QString::number((double)logEntry->logEntry->header.heartrate_avg/logEntry->personalSettings->rest_hr, 'g', 16));
- xml.writeTextElement("Max", QString::number((double)logEntry->logEntry->header.heartrate_max/logEntry->personalSettings->rest_hr, 'g', 16));
- xml.writeTextElement("Min", QString::number((double)logEntry->logEntry->header.heartrate_min/logEntry->personalSettings->rest_hr, 'g', 16));
- xml.writeTextElement("MaxTime", QString::number((double)logEntry->logEntry->header.heartrate_max_time/1000.0, 'g', 16));
- xml.writeTextElement("MinTime", QString::number((double)logEntry->logEntry->header.heartrate_min_time/1000.0, 'g', 16));
- xml.writeEndElement();
- xml.writeTextElement("PeakTrainingEffect", QString::number((double)logEntry->logEntry->header.peak_training_effect/10.0, 'g', 16));
- }
- xml.writeTextElement("ActivityType", QString("%1").arg(logEntry->logEntry->header.activity_type));
- xml.writeTextElement("Activity", QString(logEntry->logEntry->header.activity_name));
- xml.writeStartElement("Temperature");
- xml.writeTextElement("Max", QString::number((double)logEntry->logEntry->header.temperature_max/10.0 + 273.15, 'g', 16));
- xml.writeTextElement("Min", QString::number((double)logEntry->logEntry->header.temperature_min/10.0 + 273.15, 'g', 16));
- xml.writeTextElement("MaxTime", QString::number((double)logEntry->logEntry->header.temperature_max_time/1000.0, 'g', 16));
- xml.writeTextElement("MinTime", QString::number((double)logEntry->logEntry->header.temperature_min_time/1000.0, 'g', 16));
- xml.writeEndElement();
- xml.writeTextElement("Distance", QString("%1").arg(logEntry->logEntry->header.distance));
- xml.writeTextElement("LogItemCount", QString("%1").arg(logEntry->logEntry->header.samples_count));
- // Only include energy if heartrate seems to be present
- if (logEntry->logEntry->header.heartrate_avg != 0) {
- xml.writeTextElement("Energy", QString::number((double)logEntry->logEntry->header.energy_consumption*4186.8, 'g', 16)); // kcal to Joule
- }
- xml.writeTextElement("TimeToFirstFix", QString::number((double)logEntry->logEntry->header.first_fix_time/1000.0, 'g', 16));
- xml.writeTextElement("BatteryChargeAtStart", QString::number((double)logEntry->logEntry->header.battery_start/100.0, 'g', 16));
- xml.writeTextElement("BatteryCharge", QString::number((double)logEntry->logEntry->header.battery_end/100.0, 'g', 16));
- xml.writeTextElement("DistanceBeforeCalibrationChange", QString("%1").arg(logEntry->logEntry->header.distance_before_calib));
- QDateTime dateTime(QDate(logEntry->logEntry->header.date_time.year,
- logEntry->logEntry->header.date_time.month,
- logEntry->logEntry->header.date_time.day),
- QTime(logEntry->logEntry->header.date_time.hour,
- logEntry->logEntry->header.date_time.minute, 0).addMSecs(logEntry->logEntry->header.date_time.msec));
- xml.writeTextElement("DateTime", dateTime.toString(Qt::ISODate));
- xml.writeEndElement();
- QList<quint16> ibis;
- xml.writeStartElement("Samples");
- QList<int> order = rearrangeSamples();
- foreach(int index, order) {
- writeLogSample(&logEntry->logEntry->samples[index], &ibis);
- }
+ return authorized;
+}
- xml.writeEndElement();
- if (ibis.count() > 0) {
- xml.writeStartElement("IBI");
- for (i=0; i<(u_int32_t)ibis.count(); i++) {
- if (i > 0) {
- xml.writeCharacters(" ");
- }
- xml.writeCharacters(QString("%1").arg(ibis.at(i)));
+int MovesCount::getOrbitalData(u_int8_t **data)
+{
+ int ret = -1;
+ QNetworkReply *reply;
+
+ reply = syncGET("/devices/gpsorbit/binary", "", false);
+
+ if(reply->error() == QNetworkReply::NoError) {
+ QByteArray _data = reply->readAll();
+
+ if (_data.length() >= GPS_ORBIT_DATA_MIN_SIZE) {
+ *data = (u_int8_t*)malloc(_data.length());
+
+ memcpy(*data, _data.data(), _data.length());
+
+ ret = _data.length();
}
- xml.writeEndElement();
}
- return true;
+ delete reply;
+
+ return ret;
+}
+
+int MovesCount::getPersonalSettings(ambit_personal_settings_t *settings)
+{
+ Q_UNUSED(settings);
+ return 0;
}
-bool MovesCount::XMLWriter::writeLogSample(ambit_log_sample_t *sample, QList<quint16> *ibis)
+int MovesCount::getDeviceSettings()
{
- typename_lookup_entry_t *name_lookup;
- int i;
-
- switch(sample->type) {
- case ambit_log_sample_type_periodic:
- xml.writeStartElement("Sample");
- writePeriodicSample(sample);
- xml.writeEndElement();
- break;
- case ambit_log_sample_type_logpause:
- {
- //! TODO: Unknown representation!
- break;
+ QNetworkReply *reply;
+
+ reply = syncGET("/userdevices/" + QString("%1").arg(device_info.serial), "", true);
+
+ if (checkReplyAuthorization(reply)) {
+ QByteArray _data = reply->readAll();
+
+ return 0;
}
- case ambit_log_sample_type_logrestart:
- {
- //! TODO: Unknown representation!
- break;
+
+ return -1;
+}
+
+void MovesCount::checkLatestFirmwareVersion()
+{
+ if (firmwareCheckReply == NULL) {
+ firmwareCheckReply = asyncGET("/devices/" + QString("%1/%2.%3.%4")
+ .arg(device_info.model)
+ .arg(device_info.hw_version[0])
+ .arg(device_info.hw_version[1])
+ .arg(device_info.hw_version[3] << 8 | device_info.hw_version[2]), "", false);
+ connect(firmwareCheckReply, SIGNAL(finished()), this, SLOT(firmwareReplyFinished()));
}
- case ambit_log_sample_type_ibi:
- for (i=0; i<sample->u.ibi.ibi_count; i++) {
- ibis->append(sample->u.ibi.ibi[i]);
- }
- break;
- case ambit_log_sample_type_ttff:
- /* Unknown! */
- break;
- case ambit_log_sample_type_distance_source:
- {
- xml.writeStartElement("Sample");
- xml.writeTextElement("Time", QString::number((double)sample->time/1000.0, 'g', 16));
- xml.writeStartElement("Events");
- xml.writeStartElement("Distance");
- xml.writeStartElement("Source");
- for (name_lookup = &sampleDistanceSourceNames[0]; name_lookup->XMLName != ""; name_lookup++) {
- if (name_lookup->id == sample->u.distance_source) {
- xml.writeCharacters(QString(name_lookup->XMLName));
- break;
- }
- }
- xml.writeEndElement();
- QDateTime dateTime(QDate(sample->utc_time.year, sample->utc_time.month, sample->utc_time.day), QTime(sample->utc_time.hour, sample->utc_time.minute, 0).addMSecs(sample->utc_time.msec));
- dateTime.setTimeSpec(Qt::UTC);
- if (sample->u.distance_source == 0x02) {
- // Only include UTC time for GPS source
- xml.writeTextElement("UTC", dateTimeString(dateTime));
+}
+
+void MovesCount::writePersonalSettings(ambit_personal_settings_t *settings)
+{
+ Q_UNUSED(settings);
+}
+
+void MovesCount::writeLog(LogEntry *logEntry)
+{
+ QByteArray output;
+ QNetworkReply *reply;
+ QString moveId;
+
+ jsonParser.generateLogData(logEntry, output);
+
+ reply = syncPOST("/moves/", "", output, true);
+
+ if (reply->error() == QNetworkReply::NoError) {
+ QByteArray data = reply->readAll();
+ if (jsonParser.parseLogReply(data, moveId) == 0) {
+ emit logMoveID(logEntry->device, logEntry->time, moveId);
}
- xml.writeEndElement();
- xml.writeEndElement();
- xml.writeTextElement("UTC", dateTimeString(dateTime));
- xml.writeEndElement();
- break;
}
- case ambit_log_sample_type_lapinfo:
- {
- xml.writeStartElement("Sample");
- QDateTime dateTime(QDate(sample->utc_time.year, sample->utc_time.month, sample->utc_time.day), QTime(sample->utc_time.hour, sample->utc_time.minute, 0).addMSecs(sample->utc_time.msec));
- dateTime.setTimeSpec(Qt::UTC);
- xml.writeTextElement("UTC", dateTimeString(dateTime));
- xml.writeTextElement("Time", QString::number((double)sample->time/1000.0, 'g', 16));
- xml.writeStartElement("Events");
- if (sample->u.lapinfo.event_type == 0x1e || sample->u.lapinfo.event_type == 0x1f) {
- xml.writeStartElement("Pause");
- xml.writeTextElement("Type", QString("%1").arg(sample->u.lapinfo.event_type));
- xml.writeTextElement("Duration", QString::number((double)sample->u.lapinfo.duration/1000.0, 'g', 16));
- xml.writeTextElement("Distance", QString("%1").arg(sample->u.lapinfo.distance));
- xml.writeTextElement("State", sample->u.lapinfo.event_type == 0x1e ? "True" : "False");
- xml.writeEndElement();
- }
- else {
- xml.writeStartElement("Lap");
- xml.writeStartElement("Type");
- for (name_lookup = &sampleLapEventTypeNames[0]; name_lookup->XMLName != ""; name_lookup++) {
- if (name_lookup->id == sample->u.lapinfo.event_type) {
- xml.writeCharacters(QString(name_lookup->XMLName));
+}
+
+void MovesCount::firmwareReplyFinished()
+{
+ u_int8_t fw_version[4];
+
+ if (firmwareCheckReply != NULL) {
+ if (firmwareCheckReply->error() == QNetworkReply::NoError) {
+ QByteArray data = firmwareCheckReply->readAll();
+ if (jsonParser.parseFirmwareVersionReply(data, fw_version) == 0) {
+ if (fw_version[0] > device_info.fw_version[0] ||
+ (fw_version[0] == device_info.fw_version[0] && (fw_version[1] > device_info.fw_version[1] ||
+ (fw_version[1] == device_info.fw_version[1] && ((fw_version[2] | (fw_version[3] << 8)) > (device_info.fw_version[2] | (device_info.fw_version[3] << 8))))))) {
+ emit newerFirmwareExists(QByteArray((const char*)fw_version, 4));
}
}
- xml.writeEndElement();
- xml.writeTextElement("Duration", QString::number((double)sample->u.lapinfo.duration/1000.0, 'g', 16));
- xml.writeTextElement("Distance", QString("%1").arg(sample->u.lapinfo.distance));
- xml.writeEndElement();
- }
- xml.writeEndElement();
- xml.writeEndElement();
- break;
- }
- case ambit_log_sample_type_altitude_source:
- {
- xml.writeStartElement("Sample");
- xml.writeTextElement("Time", QString::number((double)sample->time/1000.0, 'g', 16));
- xml.writeStartElement("Events");
- xml.writeStartElement("Altitude");
- xml.writeStartElement("Source");
- for (name_lookup = &sampleAltitudeSourceNames[0]; name_lookup->XMLName != ""; name_lookup++) {
- if (name_lookup->id == sample->u.altitude_source.source_type) {
- xml.writeCharacters(QString(name_lookup->XMLName));
- break;
- }
}
- xml.writeEndElement();
- xml.writeTextElement("AltitudeOffset", QString("%1").arg(sample->u.altitude_source.altitude_offset));
- xml.writeTextElement("PressureOffset", QString("%1").arg(sample->u.altitude_source.pressure_offset*10));
- QDateTime dateTime(QDate(sample->utc_time.year, sample->utc_time.month, sample->utc_time.day), QTime(sample->utc_time.hour, sample->utc_time.minute, 0).addMSecs(sample->utc_time.msec));
- dateTime.setTimeSpec(Qt::UTC);
- xml.writeTextElement("UTC", dateTimeString(dateTime));
- xml.writeEndElement();
- xml.writeEndElement();
- xml.writeTextElement("UTC", dateTimeString(dateTime));
- xml.writeEndElement();
- break;
- }
- case ambit_log_sample_type_gps_base:
- {
- xml.writeStartElement("Sample");
- QString sprintfer;
- QString navtype = sprintfer.sprintf("0x%04x", sample->u.gps_base.navtype);
- xml.writeTextElement("NavType", navtype);
- if (sample->u.gps_base.navvalid == 0x0000) {
- xml.writeTextElement("NavValid", "validated");
- }
- else {
- xml.writeTextElement("NavValid", "not validated");
- }
- QString navTypeExplanation;
- if ((sample->u.gps_base.navtype & 0x0007) == 0) {
- navTypeExplanation = "no fix";
- }
- else {
- switch ((sample->u.gps_base.navtype & 0x0007)) {
- case 0x01:
- navTypeExplanation = "1-SV KF solution";
- break;
- case 0x02:
- navTypeExplanation = "2-SV KF solution";
- break;
- case 0x03:
- navTypeExplanation = "3-SV KF solution";
- break;
- case 0x04:
- navTypeExplanation = "4 or more SV KF solution";
- break;
- case 0x05:
- navTypeExplanation = "2-D least-squares solution";
- break;
- case 0x06:
- navTypeExplanation = "3-D least-squares solution";
- break;
- case 0x07:
- navTypeExplanation = "DR solution (see bits 8, 14-15)";
- break;
- }
- if ((sample->u.gps_base.navtype & 0x0008)) {
- navTypeExplanation += ", trickle";
- }
- switch ((sample->u.gps_base.navtype & 0x0030) >> 4) {
- case 0x01:
- navTypeExplanation += ", KF alti hold";
- break;
- case 0x02:
- navTypeExplanation += ", user alti hold";
- break;
- case 0x03:
- navTypeExplanation += ", always alti hold";
- break;
- }
- if ((sample->u.gps_base.navtype & 0x0040)) {
- navTypeExplanation += ", DOP exceeded";
- }
- if ((sample->u.gps_base.navtype & 0x0080)) {
- navTypeExplanation += ", DGPS corr";
- }
- if ((sample->u.gps_base.navtype & 0x0200)) {
- navTypeExplanation += ", overdetermined";
- }
- if ((sample->u.gps_base.navtype & 0x0400)) {
- navTypeExplanation += ", velo DR timeout";
- }
- if ((sample->u.gps_base.navtype & 0x1000)) {
- navTypeExplanation += ", invalid velocity";
- }
- if ((sample->u.gps_base.navtype & 0x2000)) {
- navTypeExplanation += ", alti hold disabled";
- }
- }
- xml.writeTextElement("NavTypeExplanation", navTypeExplanation);
- xml.writeStartElement("Satellites");
- ambit_log_gps_satellite_t *satellite;
- for (i=0; i<sample->u.gps_base.satellites_count; i++) {
- xml.writeStartElement("Satellite");
- satellite = &sample->u.gps_base.satellites[i];
- xml.writeTextElement("SV", QString("%1").arg(satellite->sv));
- xml.writeTextElement("SNR", QString("%1").arg(satellite->snr));
- //! TODO: What parts of state should be used to determine this!?
- if (satellite->state & 0x20) {
- xml.writeTextElement("CodeLocked", "true");
- }
- else {
- xml.writeTextElement("CodeLocked", "false");
- }
- if (satellite->state & 0x80) {
- xml.writeTextElement("Ephemeris", "true");
- }
- else {
- xml.writeTextElement("Ephemeris", "false");
- }
- QString stateText;
- if (satellite->state == 0) {
- stateText = "State 0";
- }
- else {
- stateText = sprintfer.sprintf("State 0x%02x", satellite->state);
- }
- xml.writeTextElement("Custom", stateText);
- xml.writeEndElement();
- }
- xml.writeEndElement();
- xml.writeTextElement("GPSAltitude", QString::number((double)sample->u.gps_base.altitude/100.0, 'g', 16));
- xml.writeTextElement("GPSHeading", QString::number((double)sample->u.gps_base.heading*M_PI/180/100, 'g', 16));
- xml.writeTextElement("GPSSpeed", QString::number((double)sample->u.gps_base.speed/100.0, 'g', 16));
- xml.writeTextElement("GpsHDOP", QString::number((double)sample->u.gps_base.hdop/5.0, 'g', 16));
- xml.writeTextElement("NumberOfSatellites", QString("%1").arg(sample->u.gps_base.noofsatellites));
- xml.writeTextElement("Latitude", QString::number((double)sample->u.gps_base.latitude*M_PI/180/10000000, 'g', 16)); // degrees -> radians
- xml.writeTextElement("Longitude", QString::number((double)sample->u.gps_base.longitude*M_PI/180/10000000, 'g', 16)); // degrees -> radians
- xml.writeTextElement("EHPE", QString::number((double)sample->u.gps_base.ehpe/100.0, 'g', 16));
- xml.writeTextElement("Time", QString::number((double)sample->time/1000.0, 'g', 16));
- QDateTime dateTime(QDate(sample->u.gps_base.utc_base_time.year, sample->u.gps_base.utc_base_time.month, sample->u.gps_base.utc_base_time.day), QTime(sample->u.gps_base.utc_base_time.hour, sample->u.gps_base.utc_base_time.minute, 0).addMSecs(sample->u.gps_base.utc_base_time.msec));
- dateTime.setTimeSpec(Qt::UTC);
- xml.writeTextElement("UTC", dateTimeString(dateTime));
- xml.writeTextElement("SampleType", "gps-base");
- xml.writeEndElement();
- break;
- }
- case ambit_log_sample_type_gps_small:
- {
- xml.writeStartElement("Sample");
- xml.writeTextElement("NumberOfSatellites", QString("%1").arg(sample->u.gps_small.noofsatellites));
- xml.writeTextElement("Latitude", QString::number((double)sample->u.gps_small.latitude*M_PI/180/10000000, 'g', 16));
- xml.writeTextElement("Longitude", QString::number((double)sample->u.gps_small.longitude*M_PI/180/10000000, 'g', 16));
- xml.writeTextElement("EHPE", QString::number((double)sample->u.gps_small.ehpe/100.0, 'g', 16));
- xml.writeTextElement("Time", QString::number((double)sample->time/1000.0, 'g', 16));
- // "Mimic" moveslinks strange second handling
- int seconds = sample->utc_time.msec/1000;
- if ((sample->utc_time.msec % 1000) >= 100) {
- seconds++;
- }
- QDateTime dateTime(QDate(sample->utc_time.year, sample->utc_time.month, sample->utc_time.day), QTime(sample->utc_time.hour, sample->utc_time.minute, 0).addSecs(seconds));
- dateTime.setTimeSpec(Qt::UTC);
- xml.writeTextElement("UTC", dateTimeString(dateTime));
- xml.writeTextElement("SampleType", "gps-small");
- xml.writeEndElement();
- break;
- }
- case ambit_log_sample_type_gps_tiny:
- {
- xml.writeStartElement("Sample");
- xml.writeTextElement("Latitude", QString::number((double)sample->u.gps_tiny.latitude*M_PI/180/10000000, 'g', 16));
- xml.writeTextElement("Longitude", QString::number((double)sample->u.gps_tiny.longitude*M_PI/180/10000000, 'g', 16));
- xml.writeTextElement("EHPE", QString::number((double)sample->u.gps_tiny.ehpe/100.0, 'g', 16));
- xml.writeTextElement("Time", QString::number((double)sample->time/1000.0, 'g', 16));
- // "Mimic" moveslinks strange second handling
- int seconds = sample->utc_time.msec/1000;
- if ((sample->utc_time.msec % 1000) >= 100) {
- seconds++;
- }
- QDateTime dateTime(QDate(sample->utc_time.year, sample->utc_time.month, sample->utc_time.day), QTime(sample->utc_time.hour, sample->utc_time.minute, 0).addSecs(seconds));
- dateTime.setTimeSpec(Qt::UTC);
- xml.writeTextElement("UTC", dateTimeString(dateTime));
- xml.writeTextElement("SampleType", "gps-tiny");
- xml.writeEndElement();
- break;
- }
- case ambit_log_sample_type_time:
- {
- //! TODO: Unknown representation!
- break;
+ firmwareCheckReply->deleteLater();
+ firmwareCheckReply = NULL;
}
- case ambit_log_sample_type_activity:
- {
- xml.writeStartElement("Sample");
- xml.writeTextElement("Time", QString::number((double)sample->time/1000.0, 'g', 16));
- xml.writeStartElement("Events");
- xml.writeStartElement("Activity");
- xml.writeTextElement("CustomModeId", QString("%1").arg(sample->u.activity.custommode));
- xml.writeStartElement("Type");
- typename_lookup_entry_t *name_lookup;
- for (name_lookup = &sampleActivityNames[0]; name_lookup->XMLName != ""; name_lookup++) {
- if (name_lookup->id == sample->u.activity.activitytype) {
- xml.writeCharacters(QString(name_lookup->XMLName));
- break;
- }
- }
- xml.writeEndElement();
- xml.writeEndElement();
- xml.writeEndElement();
- QDateTime dateTime(QDate(sample->utc_time.year, sample->utc_time.month, sample->utc_time.day), QTime(sample->utc_time.hour, sample->utc_time.minute, 0).addMSecs(sample->utc_time.msec));
- dateTime.setTimeSpec(Qt::UTC);
- xml.writeTextElement("UTC", dateTimeString(dateTime));
- xml.writeEndElement();
- break;
+}
+
+void MovesCount::recheckAuthorization()
+{
+ getDeviceSettings();
+}
+
+MovesCount::MovesCount()
+{
+ this->manager = new QNetworkAccessManager(this);
+}
+
+QNetworkReply *MovesCount::asyncGET(QString path, QString additionalHeaders, bool auth)
+{
+ QNetworkRequest req;
+ QString url = this->baseAddress + path + "?appkey=" + this->appkey;
+
+ if (auth) {
+ url += "&userkey=" + this->userkey + "&email=" + this->username;
}
- case ambit_log_sample_type_position:
- //! TODO: Unknown representation!
- break;
- default:
- break;
+ if (additionalHeaders.length() > 0) {
+ url += "&" + additionalHeaders;
}
- return true;
+ req.setRawHeader("User-Agent", "ArREST v1.0");
+ req.setUrl(QUrl(url));
+
+ return this->manager->get(req);
}
-bool MovesCount::XMLWriter::writePeriodicSample(ambit_log_sample_t *sample)
+QNetworkReply *MovesCount::syncGET(QString path, QString additionalHeaders, bool auth)
{
- int i;
- ambit_log_sample_periodic_value_t *value;
-
- for (i=0; i<sample->u.periodic.value_count; i++) {
- value = &sample->u.periodic.values[i];
-
- switch(value->type) {
- case ambit_log_sample_periodic_type_latitude:
- xml.writeTextElement("Latitude", QString::number((double)value->u.latitude*M_PI/180/10000000, 'g', 16));
- break;
- case ambit_log_sample_periodic_type_longitude:
- xml.writeTextElement("Longitude", QString::number((double)value->u.longitude*M_PI/180/10000000, 'g', 16));
- break;
- case ambit_log_sample_periodic_type_distance:
- xml.writeTextElement("Distance", QString("%1").arg(value->u.distance));
- break;
- case ambit_log_sample_periodic_type_speed:
- xml.writeTextElement("Speed", QString::number((double)value->u.speed/100.0, 'g', 16));
- break;
- case ambit_log_sample_periodic_type_hr:
- xml.writeTextElement("HR", QString::number((double)value->u.hr/logEntry->personalSettings->rest_hr, 'g', 16));
- break;
- case ambit_log_sample_periodic_type_time:
- xml.writeTextElement("Time", QString::number((double)value->u.time/1000.0, 'g', 16));
- break;
- case ambit_log_sample_periodic_type_gpsspeed:
- xml.writeTextElement("GPSSpeed", QString::number((double)value->u.gpsspeed/100.0, 'g', 16));
- break;
- case ambit_log_sample_periodic_type_wristaccspeed:
- xml.writeTextElement("WristAccSpeed", QString::number((double)value->u.wristaccspeed/100.0, 'g', 16));
- break;
- case ambit_log_sample_periodic_type_bikepodspeed:
- xml.writeTextElement("BikePodSpeed", QString::number((double)value->u.bikepodspeed/100.0, 'g', 16));
- break;
- case ambit_log_sample_periodic_type_ehpe:
- xml.writeTextElement("EHPE", QString("%1").arg(value->u.ehpe));
- break;
- case ambit_log_sample_periodic_type_evpe:
- xml.writeTextElement("EVPE", QString("%1").arg(value->u.evpe));
- break;
- case ambit_log_sample_periodic_type_altitude:
- xml.writeTextElement("Altitude", QString("%1").arg(value->u.altitude));
- break;
- case ambit_log_sample_periodic_type_abspressure:
- xml.writeTextElement("AbsPressure", QString("%1").arg(value->u.abspressure*10));
- break;
- case ambit_log_sample_periodic_type_energy:
- xml.writeTextElement("EnergyConsumption", QString::number((double)value->u.energy*6.978, 'g', 16)); // WTF is this unit!?
- break;
- case ambit_log_sample_periodic_type_temperature:
- xml.writeTextElement("Temperature", QString::number((double)value->u.temperature/10.0 + 273.15, 'g', 16));
- break;
- case ambit_log_sample_periodic_type_charge:
- xml.writeTextElement("BatteryCharge", QString::number((double)value->u.charge/100.0, 'g', 16));
- break;
- case ambit_log_sample_periodic_type_gpsaltitude:
- xml.writeTextElement("GPSAltitude", QString("%1").arg(value->u.gpsaltitude));
- break;
- case ambit_log_sample_periodic_type_gpsheading:
- xml.writeTextElement("GPSHeading", QString::number((double)value->u.gpsheading*M_PI/180/10000000, 'g', 16));
- break;
- case ambit_log_sample_periodic_type_gpshdop:
- xml.writeTextElement("GpsHDOP", QString("%1").arg(value->u.gpshdop));
- break;
- case ambit_log_sample_periodic_type_gpsvdop:
- xml.writeTextElement("GpsVDOP", QString("%1").arg(value->u.gpsvdop));
- break;
- case ambit_log_sample_periodic_type_wristcadence:
- xml.writeTextElement("WristCadence", QString("%1").arg(value->u.wristcadence));
- break;
- case ambit_log_sample_periodic_type_snr:
- {
- QString snr = QString("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x")
- .arg(value->u.snr[0])
- .arg(value->u.snr[1])
- .arg(value->u.snr[2])
- .arg(value->u.snr[3])
- .arg(value->u.snr[4])
- .arg(value->u.snr[5])
- .arg(value->u.snr[6])
- .arg(value->u.snr[7])
- .arg(value->u.snr[8])
- .arg(value->u.snr[9])
- .arg(value->u.snr[10])
- .arg(value->u.snr[11])
- .arg(value->u.snr[12])
- .arg(value->u.snr[13])
- .arg(value->u.snr[14])
- .arg(value->u.snr[15]);
- xml.writeTextElement("SNR", snr);
- break;
- }
- case ambit_log_sample_periodic_type_noofsatellites:
- xml.writeTextElement("NumberOfSatellites", QString("%1").arg(value->u.noofsatellites));
- break;
- case ambit_log_sample_periodic_type_sealevelpressure:
- xml.writeTextElement("SeaLevelPressure", QString("%1").arg(value->u.sealevelpressure*10));
- break;
- case ambit_log_sample_periodic_type_verticalspeed:
- xml.writeTextElement("VerticalSpeed", QString::number((double)value->u.verticalspeed/100.0, 'g', 16));
- break;
- case ambit_log_sample_periodic_type_cadence:
- xml.writeTextElement("Cadence", QString("%1").arg(value->u.cadence));
- break;
- case ambit_log_sample_periodic_type_bikepower:
- xml.writeTextElement("BikePower", QString("%1").arg(value->u.bikepower));
- break;
- case ambit_log_sample_periodic_type_swimingstrokecnt:
- xml.writeTextElement("SwimmingStrokeCount", QString("%1").arg(value->u.swimingstrokecnt));
- break;
- case ambit_log_sample_periodic_type_ruleoutput1:
- xml.writeTextElement("RuleOutput1", QString("%1").arg(value->u.ruleoutput1));
- break;
- case ambit_log_sample_periodic_type_ruleoutput2:
- xml.writeTextElement("RuleOutput2", QString("%1").arg(value->u.ruleoutput2));
- break;
- case ambit_log_sample_periodic_type_ruleoutput3:
- xml.writeTextElement("RuleOutput3", QString("%1").arg(value->u.ruleoutput3));
- break;
- case ambit_log_sample_periodic_type_ruleoutput4:
- xml.writeTextElement("RuleOutput4", QString("%1").arg(value->u.ruleoutput4));
- break;
- case ambit_log_sample_periodic_type_ruleoutput5:
- xml.writeTextElement("RuleOutput5", QString("%1").arg(value->u.ruleoutput5));
- break;
- }
- }
+ QNetworkReply *reply;
- xml.writeTextElement("Time", QString::number((double)sample->time/1000.0, 'g', 16));
- xml.writeTextElement("SampleType", "periodic");
- QDateTime dateTime(QDate(sample->utc_time.year, sample->utc_time.month, sample->utc_time.day), QTime(sample->utc_time.hour, sample->utc_time.minute, 0).addMSecs(sample->utc_time.msec));
- dateTime.setTimeSpec(Qt::UTC);
- xml.writeTextElement("UTC", dateTimeString(dateTime));
+ reply = asyncGET(path, additionalHeaders, auth);
+ QEventLoop loop;
+ connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
+ loop.exec();
- return true;
+ return reply;
}
-QString MovesCount::XMLWriter::dateTimeString(QDateTime &dateTime)
+QNetworkReply *MovesCount::asyncPOST(QString path, QString additionalHeaders, QByteArray &postData, bool auth)
{
- if (dateTime.time().msec() != 0) {
- return dateTime.toString("yyyy-MM-ddThh:mm:ss.zzzZ");
+ QNetworkRequest req;
+ QString url = this->baseAddress + path + "?appkey=" + this->appkey;
+
+ if (auth) {
+ url += "&userkey=" + this->userkey + "&email=" + this->username;
}
- else {
- return dateTime.toString("yyyy-MM-ddThh:mm:ssZ");
+ if (additionalHeaders.length() > 0) {
+ url += "&" + additionalHeaders;
}
+
+ req.setRawHeader("User-Agent", "ArREST v1.0");
+ req.setRawHeader("Content-Type", "application/json");
+ req.setUrl(QUrl(url));
+
+ return this->manager->post(req, postData);
}
-QList<int> MovesCount::XMLWriter::rearrangeSamples()
+QNetworkReply *MovesCount::syncPOST(QString path, QString additionalHeaders, QByteArray &postData, bool auth)
{
- QList<int> sampleList;
- u_int32_t index = 0;
- u_int32_t lastMatching = 0;
-
- while (index < logEntry->logEntry->samples_count) {
- // First find all entries with the same time
- lastMatching = index;
- while (lastMatching + 1 < logEntry->logEntry->samples_count &&
- logEntry->logEntry->samples[index].time == logEntry->logEntry->samples[lastMatching+1].time) {
- lastMatching++;
- }
+ QNetworkReply *reply;
- // Put start/stop at top
- for (u_int32_t i=index; i<=lastMatching; i++) {
- if (logEntry->logEntry->samples[i].type == ambit_log_sample_type_lapinfo &&
- (logEntry->logEntry->samples[i].u.lapinfo.event_type == 0x1e ||
- logEntry->logEntry->samples[i].u.lapinfo.event_type == 0x1f)) {
- sampleList.append(i);
- }
- }
-
- // Then any gps-entries
- for (u_int32_t i=index; i<=lastMatching; i++) {
- if (logEntry->logEntry->samples[i].type == ambit_log_sample_type_gps_base ||
- logEntry->logEntry->samples[i].type == ambit_log_sample_type_gps_small ||
- logEntry->logEntry->samples[i].type == ambit_log_sample_type_gps_tiny) {
- sampleList.append(i);
- }
- }
+ reply = asyncPOST(path, additionalHeaders, postData, auth);
+ QEventLoop loop;
+ connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
+ loop.exec();
- // Then periodic samples
- for (u_int32_t i=index; i<=lastMatching; i++) {
- if (logEntry->logEntry->samples[i].type == ambit_log_sample_type_periodic) {
- sampleList.append(i);
- }
- }
+ return reply;
+}
- // Then any other!
- for (u_int32_t i=index; i<=lastMatching; i++) {
- if (logEntry->logEntry->samples[i].type != ambit_log_sample_type_gps_base &&
- logEntry->logEntry->samples[i].type != ambit_log_sample_type_gps_small &&
- logEntry->logEntry->samples[i].type != ambit_log_sample_type_gps_tiny &&
- logEntry->logEntry->samples[i].type != ambit_log_sample_type_periodic &&
- !(logEntry->logEntry->samples[i].type == ambit_log_sample_type_lapinfo &&
- (logEntry->logEntry->samples[i].u.lapinfo.event_type == 0x1e ||
- logEntry->logEntry->samples[i].u.lapinfo.event_type == 0x1f))) {
- sampleList.append(i);
- }
- }
- index = lastMatching + 1;
+bool MovesCount::checkReplyAuthorization(QNetworkReply *reply)
+{
+ if (reply->error() == QNetworkReply::AuthenticationRequiredError) {
+ authorized = false;
+ emit movesCountAuth(false);
+ QTimer::singleShot(AUTH_CHECK_TIMEOUT, this, SLOT(recheckAuthorization()));
+ }
+ else if(reply->error() == QNetworkReply::NoError) {
+ authorized = true;
+ emit movesCountAuth(true);
}
- return sampleList;
+ return authorized;
}
diff --git a/src/openambit/movescount.h b/src/openambit/movescount.h
index 626c8a5..ebc410c 100644
--- a/src/openambit/movescount.h
+++ b/src/openambit/movescount.h
@@ -23,44 +23,71 @@
#define MOVESCOUNT_H
#include <QObject>
-#include <QList>
-#include <QIODevice>
-#include <QXmlStreamWriter>
+#include <QtNetwork/QNetworkAccessManager>
+#include <QtNetwork/QNetworkReply>
+#include <QTimer>
+#include <libambit.h>
#include "logentry.h"
+#include "movescountjson.h"
class MovesCount : public QObject
{
Q_OBJECT
public:
- explicit MovesCount(QObject *parent = 0);
-
+ static MovesCount* instance();
+
+ void setBaseAddress(QString baseAddress);
+ void setAppkey(QString appkey);
+ void setUsername(QString username);
+ void setUserkey(QString userkey);
+ QString generateUserkey();
+ void setDevice(ambit_device_info_t *device_info);
+
+ bool isAuthorized();
+ int getOrbitalData(u_int8_t **data);
+ int getPersonalSettings(ambit_personal_settings_t *settings);
+ int getDeviceSettings();
signals:
+ void newerFirmwareExists(QByteArray fw_version);
+ void movesCountAuth(bool authorized);
+ void logMoveID(QString device, QDateTime time, QString moveID);
public slots:
- void sendLog(LogEntry *logEntry);
+ void checkLatestFirmwareVersion();
+ void writePersonalSettings(ambit_personal_settings_t *settings);
+ void writeLog(LogEntry *logEntry);
+
+private slots:
+ void firmwareReplyFinished();
+ void recheckAuthorization();
private:
- QString logEntryPath(LogEntry *logEntry);
+ MovesCount();
+ MovesCount(const MovesCount &);
+ MovesCount& operator=(const MovesCount &);
+
+ QNetworkReply *asyncGET(QString path, QString additionalHeaders, bool auth);
+ QNetworkReply *syncGET(QString path, QString additionalHeaders, bool auth);
+
+ QNetworkReply *asyncPOST(QString path, QString additionalHeaders, QByteArray &postData, bool auth);
+ QNetworkReply *syncPOST(QString path, QString additionalHeaders, QByteArray &postData, bool auth);
- QString storagePath;
+ bool checkReplyAuthorization(QNetworkReply *reply);
- class XMLWriter
- {
- public:
- XMLWriter(LogEntry *logEntry);
- bool write(QIODevice *device);
+ bool authorized = false;
- private:
- bool writeLogEntry();
- bool writeLogSample(ambit_log_sample_t *sample, QList<quint16> *ibis);
- bool writePeriodicSample(ambit_log_sample_t *sample);
+ QString baseAddress;
+ QString appkey;
+ QString username;
+ QString userkey;
+ QString model;
+ QString serial;
+ ambit_device_info_t device_info;
- QString dateTimeString(QDateTime &dateTime);
- QList<int> rearrangeSamples();
+ QNetworkAccessManager *manager;
+ QNetworkReply *firmwareCheckReply = NULL;
- LogEntry *logEntry;
- QXmlStreamWriter xml;
- };
+ MovesCountJSON jsonParser;
};
#endif // MOVESCOUNT_H
diff --git a/src/openambit/movescountjson.cpp b/src/openambit/movescountjson.cpp
new file mode 100644
index 0000000..b67ae10
--- /dev/null
+++ b/src/openambit/movescountjson.cpp
@@ -0,0 +1,502 @@
+/*
+ * (C) Copyright 2013 Emil Ljungdahl
+ *
+ * This file is part of Openambit.
+ *
+ * Openambit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Contributors:
+ *
+ */
+#include "movescountjson.h"
+
+#include <QRegExp>
+#include <QVariantMap>
+#include <QVariantList>
+#include <qjson/parser.h>
+#include <qjson/serializer.h>
+#include <zlib.h>
+#include <math.h>
+
+MovesCountJSON::MovesCountJSON(QObject *parent) :
+ QObject(parent)
+{
+}
+
+int MovesCountJSON::parseFirmwareVersionReply(QByteArray &input, u_int8_t fw_version[4])
+{
+ QJson::Parser parser;
+ bool ok;
+ QRegExp rx("([0-9]+)\\.([0-9]+)\\.([0-9]+)");
+
+ if (input.length() <= 0) {
+ return -1;
+ }
+
+ QVariantMap result = parser.parse(input, &ok).toMap();
+
+ if (ok && result["LatestFirmwareVersion"].toString().length() > 0) {
+ if (rx.indexIn(result["LatestFirmwareVersion"].toString()) >= 0) {
+ fw_version[0] = rx.cap(1).toInt();
+ fw_version[1] = rx.cap(2).toInt();
+ fw_version[2] = rx.cap(3).toInt() & 0xff;
+ fw_version[3] = (rx.cap(3).toInt() >> 8) & 0xff;
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+int MovesCountJSON::parseLogReply(QByteArray &input, QString &moveId)
+{
+ QJson::Parser parser;
+ bool ok;
+
+ if (input.length() <= 0) {
+ return -1;
+ }
+
+ QVariantMap result = parser.parse(input, &ok).toMap();
+
+ if (ok && result["MoveID"].toString().length() > 0 && result["MoveID"].toString() != "0") {
+ moveId = result["MoveID"].toString();
+ return 0;
+ }
+
+ return -1;
+}
+
+int MovesCountJSON::generateLogData(LogEntry *logEntry, QByteArray &output)
+{
+ QJson::Serializer serializer;
+ bool ok;
+ QVariantMap content;
+ QVariantList IBIContent;
+ QVariantList marksContent;
+ QVariantList periodicSamplesContent;
+ QVariantList GPSSamplesContent;
+ QByteArray uncompressedData, compressedData;
+ ambit_log_sample_t *sample;
+
+ QDateTime localBaseTime(QDate(logEntry->logEntry->header.date_time.year,
+ logEntry->logEntry->header.date_time.month,
+ logEntry->logEntry->header.date_time.day),
+ QTime(logEntry->logEntry->header.date_time.hour,
+ logEntry->logEntry->header.date_time.minute, 0).addMSecs(logEntry->logEntry->header.date_time.msec));
+
+ // Loop through content
+ QList<int> order = rearrangeSamples(logEntry);
+ foreach(int index, order) {
+ sample = &logEntry->logEntry->samples[index];
+
+ switch(sample->type) {
+ case ambit_log_sample_type_periodic:
+ {
+ QVariantMap tmpMap;
+ tmpMap.insert("LocalTime", dateTimeString(localBaseTime.addMSecs(sample->time)));
+ writePeriodicSample(sample, tmpMap);
+ periodicSamplesContent.append(tmpMap);
+ break;
+ }
+ case ambit_log_sample_type_ibi:
+ for (int j=0; j<sample->u.ibi.ibi_count; j++) {
+ IBIContent.append(sample->u.ibi.ibi[j]);
+ }
+ break;
+ case ambit_log_sample_type_gps_base:
+ {
+ QVariantMap tmpMap;
+ tmpMap.insert("Altitude", (double)sample->u.gps_base.altitude/100.0);
+ tmpMap.insert("EHPE", (double)sample->u.gps_base.ehpe/100.0);
+ tmpMap.insert("Latitude", (double)sample->u.gps_base.latitude/10000000);
+ tmpMap.insert("LocalTime", dateTimeString(localBaseTime.addMSecs(sample->time)));
+ tmpMap.insert("Longitude", (double)sample->u.gps_base.longitude/10000000);
+ GPSSamplesContent.append(tmpMap);
+ break;
+ }
+ case ambit_log_sample_type_gps_small:
+ {
+ QVariantMap tmpMap;
+ tmpMap.insert("Altitude", (double)0);
+ tmpMap.insert("EHPE", (double)sample->u.gps_small.ehpe/100.0);
+ tmpMap.insert("Latitude", (double)sample->u.gps_small.latitude/10000000);
+ tmpMap.insert("LocalTime", dateTimeString(localBaseTime.addMSecs(sample->time)));
+ tmpMap.insert("Longitude", (double)sample->u.gps_small.longitude/10000000);
+ GPSSamplesContent.append(tmpMap);
+ break;
+ }
+ case ambit_log_sample_type_gps_tiny:
+ {
+ QVariantMap tmpMap;
+ tmpMap.insert("Altitude", (double)0);
+ tmpMap.insert("EHPE", (double)sample->u.gps_tiny.ehpe/100.0);
+ tmpMap.insert("Latitude", (double)sample->u.gps_tiny.latitude/10000000);
+ tmpMap.insert("LocalTime", dateTimeString(localBaseTime.addMSecs(sample->time)));
+ tmpMap.insert("Longitude", (double)sample->u.gps_tiny.longitude/10000000);
+ GPSSamplesContent.append(tmpMap);
+ break;
+ }
+ case ambit_log_sample_type_lapinfo:
+ switch (sample->u.lapinfo.event_type) {
+ case 0x01: /* manual = 0 */
+ case 0x16: /* interval = 0 */
+ {
+ QVariantMap tmpMap;
+ tmpMap.insert("LocalTime", dateTimeString(localBaseTime.addMSecs(sample->time)));
+ tmpMap.insert("Type", 0);
+ marksContent.append(tmpMap);
+ break;
+ }
+ case 0x1f: /* start = 1 */
+ {
+ QVariantMap tmpMap;
+ tmpMap.insert("LocalTime", dateTimeString(localBaseTime.addMSecs(sample->time)));
+ if (sample->time > 0) {
+ tmpMap.insert("Type", 1);
+ }
+ marksContent.append(tmpMap);
+ break;
+ }
+ case 0x1e: /* pause = 2 */
+ {
+ QVariantMap tmpMap;
+ tmpMap.insert("LocalTime", dateTimeString(localBaseTime.addMSecs(sample->time)));
+ tmpMap.insert("Type", 2);
+ marksContent.append(tmpMap);
+ break;
+ }
+ case 0x14: /* high interval = 3 */
+ case 0x15: /* low interval = 3 */
+ {
+ QVariantMap tmpMap;
+ tmpMap.insert("LocalTime", dateTimeString(localBaseTime.addMSecs(sample->time)));
+ tmpMap.insert("Type", 3);
+ marksContent.append(tmpMap);
+ break;
+ }
+ };
+ break;
+ case ambit_log_sample_type_activity:
+ {
+ QVariantMap tmpMap;
+ tmpMap.insert("LocalTime", dateTimeString(localBaseTime.addMSecs(sample->time)));
+ tmpMap.insert("NextActivityID", sample->u.activity.activitytype);
+ tmpMap.insert("Type", 8);
+ marksContent.append(tmpMap);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ serializer.setDoublePrecision(16);
+ serializer.setIndentMode(QJson::IndentCompact);
+
+ content.insert("ActivityID", logEntry->logEntry->header.activity_type);
+ content.insert("AscentAltitude", (double)logEntry->logEntry->header.ascent);
+ content.insert("AscentTime", (double)logEntry->logEntry->header.ascent_time/1000.0);
+ content.insert("AvgCadence", QVariant::Invalid);
+ content.insert("AvgHR", logEntry->logEntry->header.heartrate_avg);
+ content.insert("AvgSpeed", (double)logEntry->logEntry->header.speed_avg/3600.0);
+ content.insert("DescentAltitude", (double)logEntry->logEntry->header.descent);
+ content.insert("DescentTime", (double)logEntry->logEntry->header.descent_time/1000.0);
+ content.insert("DeviceName", logEntry->deviceInfo->model);
+ content.insert("DeviceSerialNumber", logEntry->deviceInfo->serial);
+ content.insert("Distance", logEntry->logEntry->header.distance);
+ content.insert("Duration", (double)logEntry->logEntry->header.duration/1000.0);
+ content.insert("Energy", logEntry->logEntry->header.energy_consumption);
+ content.insert("FlatTime", QVariant::Invalid);
+ content.insert("HighAltitude", (double)logEntry->logEntry->header.altitude_max);
+ uncompressedData = serializer.serialize(IBIContent);
+ compressData(uncompressedData, compressedData);
+ QVariantMap IBIDataMap;
+ IBIDataMap.insert("CompressedValues", compressedData.toBase64());
+ content.insert("IBIData", IBIDataMap); /* compressed */
+ content.insert("LocalStartTime", dateTimeString(localBaseTime));
+ content.insert("LowAltitude", (double)logEntry->logEntry->header.altitude_min);
+ content.insert("Marks", marksContent);
+ content.insert("MaxCadence", QVariant::Invalid);
+ content.insert("MaxSpeed", (double)logEntry->logEntry->header.speed_max/3600.0);
+ content.insert("MaxTemp", (double)logEntry->logEntry->header.temperature_max/10.0);
+ content.insert("MinHR", logEntry->logEntry->header.heartrate_min);
+ content.insert("MinTemp", (double)logEntry->logEntry->header.temperature_min/10.0);
+ content.insert("PeakHR", logEntry->logEntry->header.heartrate_max);
+ content.insert("PeakTrainingEffect", (double)logEntry->logEntry->header.peak_training_effect/10.0);
+ content.insert("RecoveryTime", (double)logEntry->logEntry->header.recovery_time/1000.0);
+ uncompressedData = serializer.serialize(periodicSamplesContent);
+ compressData(uncompressedData, compressedData);
+ QVariantMap periodicSamplesDataMap;
+ periodicSamplesDataMap.insert("CompressedSampleSets", compressedData.toBase64());
+ content.insert("Samples", periodicSamplesDataMap); /* compressed */
+ content.insert("SerialNumber", QVariant::Invalid);
+ content.insert("StartLatitude", QVariant::Invalid);
+ content.insert("StartLongitude", QVariant::Invalid);
+ uncompressedData = serializer.serialize(GPSSamplesContent);
+ compressData(uncompressedData, compressedData);
+ QVariantMap GPSSamplesDataMap;
+ GPSSamplesDataMap.insert("CompressedTrackPoints", compressedData.toBase64());
+ content.insert("Track", GPSSamplesDataMap); /* compressed */
+
+ output = serializer.serialize(content, &ok);
+
+ return (ok ? 0 : -1);
+}
+
+bool MovesCountJSON::writePeriodicSample(ambit_log_sample_t *sample, QVariantMap &output)
+{
+ int i;
+ ambit_log_sample_periodic_value_t *value;
+
+ for (i=0; i<sample->u.periodic.value_count; i++) {
+ value = &sample->u.periodic.values[i];
+
+ switch(value->type) {
+ case ambit_log_sample_periodic_type_latitude:
+ output.insert("Latitude", (double)value->u.latitude/10000000);
+ break;
+ case ambit_log_sample_periodic_type_longitude:
+ output.insert("Longitude", (double)value->u.longitude/10000000);
+ break;
+ case ambit_log_sample_periodic_type_distance:
+ output.insert("Distance", value->u.distance);
+ break;
+ case ambit_log_sample_periodic_type_speed:
+ output.insert("Speed", (double)value->u.speed/100.0);
+ break;
+ case ambit_log_sample_periodic_type_hr:
+ output.insert("HeartRate", value->u.hr);
+ break;
+ case ambit_log_sample_periodic_type_time:
+ output.insert("Time", (double)value->u.time/1000.0);
+ break;
+ case ambit_log_sample_periodic_type_gpsspeed:
+ output.insert("GPSSpeed", (double)value->u.gpsspeed/100.0);
+ break;
+ case ambit_log_sample_periodic_type_wristaccspeed:
+ output.insert("WristAccSpeed", (double)value->u.wristaccspeed/100.0);
+ break;
+ case ambit_log_sample_periodic_type_bikepodspeed:
+ output.insert("BikePodSpeed", (double)value->u.bikepodspeed/100.0);
+ break;
+ case ambit_log_sample_periodic_type_ehpe:
+ output.insert("EHPE", value->u.ehpe);
+ break;
+ case ambit_log_sample_periodic_type_evpe:
+ output.insert("EVPE", value->u.evpe);
+ break;
+ case ambit_log_sample_periodic_type_altitude:
+ output.insert("Altitude", (double)value->u.altitude);
+ break;
+ case ambit_log_sample_periodic_type_abspressure:
+ output.insert("AbsPressure", (int)round((double)value->u.abspressure/10.0));
+ break;
+ case ambit_log_sample_periodic_type_energy:
+ output.insert("EnergyConsumption", (double)value->u.energy/10.0);
+ break;
+ case ambit_log_sample_periodic_type_temperature:
+ output.insert("Temperature", (double)value->u.temperature/10.0);
+ break;
+ case ambit_log_sample_periodic_type_charge:
+ output.insert("BatteryCharge", (double)value->u.charge/100.0);
+ break;
+ case ambit_log_sample_periodic_type_gpsaltitude:
+ output.insert("GPSAltitude", value->u.gpsaltitude);
+ break;
+ case ambit_log_sample_periodic_type_gpsheading:
+ output.insert("GPSHeading", (double)value->u.gpsheading/10000000);
+ break;
+ case ambit_log_sample_periodic_type_gpshdop:
+ output.insert("GpsHDOP", value->u.gpshdop);
+ break;
+ case ambit_log_sample_periodic_type_gpsvdop:
+ output.insert("GpsVDOP", value->u.gpsvdop);
+ break;
+ case ambit_log_sample_periodic_type_wristcadence:
+ output.insert("WristCadence", value->u.wristcadence);
+ break;
+ case ambit_log_sample_periodic_type_snr:
+ {
+ QString snr = QString("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x")
+ .arg(value->u.snr[0])
+ .arg(value->u.snr[1])
+ .arg(value->u.snr[2])
+ .arg(value->u.snr[3])
+ .arg(value->u.snr[4])
+ .arg(value->u.snr[5])
+ .arg(value->u.snr[6])
+ .arg(value->u.snr[7])
+ .arg(value->u.snr[8])
+ .arg(value->u.snr[9])
+ .arg(value->u.snr[10])
+ .arg(value->u.snr[11])
+ .arg(value->u.snr[12])
+ .arg(value->u.snr[13])
+ .arg(value->u.snr[14])
+ .arg(value->u.snr[15]);
+ output.insert("SNR", snr);
+ break;
+ }
+ case ambit_log_sample_periodic_type_noofsatellites:
+ output.insert("NumberOfSatellites", value->u.noofsatellites);
+ break;
+ case ambit_log_sample_periodic_type_sealevelpressure:
+ output.insert("SeaLevelPressure", (int)round((double)value->u.sealevelpressure/10.0));
+ break;
+ case ambit_log_sample_periodic_type_verticalspeed:
+ output.insert("VerticalSpeed", (double)value->u.verticalspeed/100.0);
+ break;
+ case ambit_log_sample_periodic_type_cadence:
+ output.insert("Cadence", value->u.cadence);
+ break;
+ case ambit_log_sample_periodic_type_bikepower:
+ output.insert("BikePower", value->u.bikepower);
+ break;
+ case ambit_log_sample_periodic_type_swimingstrokecnt:
+ output.insert("SwimmingStrokeCount", value->u.swimingstrokecnt);
+ break;
+ case ambit_log_sample_periodic_type_ruleoutput1:
+ output.insert("RuleOutput1", value->u.ruleoutput1);
+ break;
+ case ambit_log_sample_periodic_type_ruleoutput2:
+ output.insert("RuleOutput2", value->u.ruleoutput2);
+ break;
+ case ambit_log_sample_periodic_type_ruleoutput3:
+ output.insert("RuleOutput3", value->u.ruleoutput3);
+ break;
+ case ambit_log_sample_periodic_type_ruleoutput4:
+ output.insert("RuleOutput4", value->u.ruleoutput4);
+ break;
+ case ambit_log_sample_periodic_type_ruleoutput5:
+ output.insert("RuleOutput5", value->u.ruleoutput5);
+ break;
+ }
+ }
+
+ return true;
+}
+
+int MovesCountJSON::compressData(QByteArray &content, QByteArray &output)
+{
+ int ret = -1, res, deflate_res;
+ z_stream strm;
+ gz_header header;
+ size_t destLen = compressBound(content.length());
+
+ memset(&strm, 0, sizeof(z_stream));
+ memset(&header, 0, sizeof(gz_header));
+
+ if (destLen > 0) {
+ u_int8_t *buf = (u_int8_t*)malloc(destLen);
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ header.os = 0x00; // FAT
+
+ res = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 31, 8, Z_DEFAULT_STRATEGY);
+ res = deflateSetHeader(&strm, &header);
+
+ strm.next_in = reinterpret_cast<uint8_t *>(content.data());
+ strm.avail_in = content.length();
+ strm.next_out = buf;
+ strm.avail_out = destLen;
+
+ res = deflate(&strm, Z_NO_FLUSH);
+
+ if (res == Z_OK) {
+ deflate_res = Z_OK;
+ while (deflate_res == Z_OK) {
+ deflate_res = deflate(&strm, Z_FINISH);
+ }
+
+ if (deflate_res == Z_STREAM_END) {
+ output.setRawData((char*)buf, destLen - strm.avail_out);
+ ret = 0;
+ }
+ }
+
+ deflateEnd(&strm);
+ }
+
+ return ret;
+}
+
+QList<int> MovesCountJSON::rearrangeSamples(LogEntry *logEntry)
+{
+ QList<int> sampleList;
+ u_int32_t index = 0;
+ u_int32_t lastMatching = 0;
+
+ while (index < logEntry->logEntry->samples_count) {
+ // First find all entries with the same time
+ lastMatching = index;
+ while (lastMatching + 1 < logEntry->logEntry->samples_count &&
+ logEntry->logEntry->samples[index].time == logEntry->logEntry->samples[lastMatching+1].time) {
+ lastMatching++;
+ }
+
+ // Put start/stop at top
+ for (u_int32_t i=index; i<=lastMatching; i++) {
+ if (logEntry->logEntry->samples[i].type == ambit_log_sample_type_lapinfo &&
+ (logEntry->logEntry->samples[i].u.lapinfo.event_type == 0x1e ||
+ logEntry->logEntry->samples[i].u.lapinfo.event_type == 0x1f)) {
+ sampleList.append(i);
+ }
+ }
+
+ // Then any gps-entries
+ for (u_int32_t i=index; i<=lastMatching; i++) {
+ if (logEntry->logEntry->samples[i].type == ambit_log_sample_type_gps_base ||
+ logEntry->logEntry->samples[i].type == ambit_log_sample_type_gps_small ||
+ logEntry->logEntry->samples[i].type == ambit_log_sample_type_gps_tiny) {
+ sampleList.append(i);
+ }
+ }
+
+ // Then periodic samples
+ for (u_int32_t i=index; i<=lastMatching; i++) {
+ if (logEntry->logEntry->samples[i].type == ambit_log_sample_type_periodic) {
+ sampleList.append(i);
+ }
+ }
+
+ // Then any other!
+ for (u_int32_t i=index; i<=lastMatching; i++) {
+ if (logEntry->logEntry->samples[i].type != ambit_log_sample_type_gps_base &&
+ logEntry->logEntry->samples[i].type != ambit_log_sample_type_gps_small &&
+ logEntry->logEntry->samples[i].type != ambit_log_sample_type_gps_tiny &&
+ logEntry->logEntry->samples[i].type != ambit_log_sample_type_periodic &&
+ !(logEntry->logEntry->samples[i].type == ambit_log_sample_type_lapinfo &&
+ (logEntry->logEntry->samples[i].u.lapinfo.event_type == 0x1e ||
+ logEntry->logEntry->samples[i].u.lapinfo.event_type == 0x1f))) {
+ sampleList.append(i);
+ }
+ }
+
+ index = lastMatching + 1;
+ }
+
+ return sampleList;
+}
+
+QString MovesCountJSON::dateTimeString(QDateTime dateTime)
+{
+ if (dateTime.time().msec() != 0) {
+ return dateTime.toString("yyyy-MM-ddThh:mm:ss.zzz");
+ }
+ else {
+ return dateTime.toString("yyyy-MM-ddThh:mm:ss");
+ }
+}
diff --git a/src/openambit/movescount.h b/src/openambit/movescountjson.h
similarity index 53%
copy from src/openambit/movescount.h
copy to src/openambit/movescountjson.h
index 626c8a5..04b6c44 100644
--- a/src/openambit/movescount.h
+++ b/src/openambit/movescountjson.h
@@ -19,48 +19,36 @@
* Contributors:
*
*/
-#ifndef MOVESCOUNT_H
-#define MOVESCOUNT_H
+#ifndef MOVESCOUNTJSON_H
+#define MOVESCOUNTJSON_H
#include <QObject>
#include <QList>
-#include <QIODevice>
-#include <QXmlStreamWriter>
+#include <QVariantMap>
+#include <libambit.h>
#include "logentry.h"
-class MovesCount : public QObject
+class MovesCountJSON : public QObject
{
Q_OBJECT
public:
- explicit MovesCount(QObject *parent = 0);
+ explicit MovesCountJSON(QObject *parent = 0);
+
+ int parseFirmwareVersionReply(QByteArray &input, u_int8_t fw_version[4]);
+ int parseLogReply(QByteArray &input, QString &moveId);
+
+ int generateLogData(LogEntry *logEntry, QByteArray &output);
signals:
public slots:
- void sendLog(LogEntry *logEntry);
private:
- QString logEntryPath(LogEntry *logEntry);
-
- QString storagePath;
-
- class XMLWriter
- {
- public:
- XMLWriter(LogEntry *logEntry);
- bool write(QIODevice *device);
-
- private:
- bool writeLogEntry();
- bool writeLogSample(ambit_log_sample_t *sample, QList<quint16> *ibis);
- bool writePeriodicSample(ambit_log_sample_t *sample);
-
- QString dateTimeString(QDateTime &dateTime);
- QList<int> rearrangeSamples();
+ bool writePeriodicSample(ambit_log_sample_t *sample, QVariantMap &output);
- LogEntry *logEntry;
- QXmlStreamWriter xml;
- };
+ int compressData(QByteArray &content, QByteArray &output);
+ QList<int> rearrangeSamples(LogEntry *logEntry);
+ QString dateTimeString(QDateTime dateTime);
};
-#endif // MOVESCOUNT_H
+#endif // MOVESCOUNTJSON_H
diff --git a/src/openambit/movescount.cpp b/src/openambit/movescountxml.cpp
similarity index 98%
copy from src/openambit/movescount.cpp
copy to src/openambit/movescountxml.cpp
index 37cc842..b23b6e2 100644
--- a/src/openambit/movescount.cpp
+++ b/src/openambit/movescountxml.cpp
@@ -19,7 +19,7 @@
* Contributors:
*
*/
-#include "movescount.h"
+#include "movescountxml.h"
#include <QFile>
#define _USE_MATH_DEFINES
@@ -159,13 +159,13 @@ static typename_lookup_entry_t sampleActivityNames[] = {
{ 0, "" }
};
-MovesCount::MovesCount(QObject *parent) :
+MovesCountXML::MovesCountXML(QObject *parent) :
QObject(parent)
{
storagePath = QString(getenv("HOME")) + "/.openambit/movescount";
}
-void MovesCount::sendLog(LogEntry *logEntry)
+void MovesCountXML::writeLog(LogEntry *logEntry)
{
XMLWriter writer(logEntry);
QFile logfile(logEntryPath(logEntry));
@@ -176,19 +176,19 @@ void MovesCount::sendLog(LogEntry *logEntry)
logfile.close();
}
-QString MovesCount::logEntryPath(LogEntry *logEntry)
+QString MovesCountXML::logEntryPath(LogEntry *logEntry)
{
return storagePath + "/log-" + logEntry->device + "-" + logEntry->time.toString("yyyy-MM-ddThh_mm_ss") + "-0.log";
}
-MovesCount::XMLWriter::XMLWriter(LogEntry *logEntry) :
+MovesCountXML::XMLWriter::XMLWriter(LogEntry *logEntry) :
logEntry(logEntry)
{
xml.setAutoFormatting(true);
xml.setAutoFormattingIndent(-1);
}
-bool MovesCount::XMLWriter::write(QIODevice *device)
+bool MovesCountXML::XMLWriter::write(QIODevice *device)
{
bool ret = true;
@@ -201,7 +201,7 @@ bool MovesCount::XMLWriter::write(QIODevice *device)
return ret;
}
-bool MovesCount::XMLWriter::writeLogEntry()
+bool MovesCountXML::XMLWriter::writeLogEntry()
{
u_int32_t i;
@@ -285,7 +285,7 @@ bool MovesCount::XMLWriter::writeLogEntry()
return true;
}
-bool MovesCount::XMLWriter::writeLogSample(ambit_log_sample_t *sample, QList<quint16> *ibis)
+bool MovesCountXML::XMLWriter::writeLogSample(ambit_log_sample_t *sample, QList<quint16> *ibis)
{
typename_lookup_entry_t *name_lookup;
int i;
@@ -598,7 +598,7 @@ bool MovesCount::XMLWriter::writeLogSample(ambit_log_sample_t *sample, QList<qui
return true;
}
-bool MovesCount::XMLWriter::writePeriodicSample(ambit_log_sample_t *sample)
+bool MovesCountXML::XMLWriter::writePeriodicSample(ambit_log_sample_t *sample)
{
int i;
ambit_log_sample_periodic_value_t *value;
@@ -737,7 +737,7 @@ bool MovesCount::XMLWriter::writePeriodicSample(ambit_log_sample_t *sample)
return true;
}
-QString MovesCount::XMLWriter::dateTimeString(QDateTime &dateTime)
+QString MovesCountXML::XMLWriter::dateTimeString(QDateTime &dateTime)
{
if (dateTime.time().msec() != 0) {
return dateTime.toString("yyyy-MM-ddThh:mm:ss.zzzZ");
@@ -747,7 +747,7 @@ QString MovesCount::XMLWriter::dateTimeString(QDateTime &dateTime)
}
}
-QList<int> MovesCount::XMLWriter::rearrangeSamples()
+QList<int> MovesCountXML::XMLWriter::rearrangeSamples()
{
QList<int> sampleList;
u_int32_t index = 0;
diff --git a/src/openambit/movescount.h b/src/openambit/movescountxml.h
similarity index 88%
copy from src/openambit/movescount.h
copy to src/openambit/movescountxml.h
index 626c8a5..717f19d 100644
--- a/src/openambit/movescount.h
+++ b/src/openambit/movescountxml.h
@@ -19,8 +19,8 @@
* Contributors:
*
*/
-#ifndef MOVESCOUNT_H
-#define MOVESCOUNT_H
+#ifndef MOVESCOUNTXML_H
+#define MOVESCOUNTXML_H
#include <QObject>
#include <QList>
@@ -28,16 +28,16 @@
#include <QXmlStreamWriter>
#include "logentry.h"
-class MovesCount : public QObject
+class MovesCountXML : public QObject
{
Q_OBJECT
public:
- explicit MovesCount(QObject *parent = 0);
+ explicit MovesCountXML(QObject *parent = 0);
signals:
public slots:
- void sendLog(LogEntry *logEntry);
+ void writeLog(LogEntry *logEntry);
private:
QString logEntryPath(LogEntry *logEntry);
@@ -63,4 +63,4 @@ private:
};
};
-#endif // MOVESCOUNT_H
+#endif // MOVESCOUNTXML_H
diff --git a/src/openambit/openambit.pro b/src/openambit/openambit.pro
index 9f6c5c4..a039ae2 100644
--- a/src/openambit/openambit.pro
+++ b/src/openambit/openambit.pro
@@ -4,7 +4,7 @@
#
#-------------------------------------------------
-QT += core gui
+QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
@@ -19,6 +19,8 @@ SOURCES += main.cpp\
settings.cpp \
logstore.cpp \
logentry.cpp \
+ movescountxml.cpp \
+ movescountjson.cpp \
movescount.cpp
HEADERS += mainwindow.h \
@@ -27,6 +29,8 @@ HEADERS += mainwindow.h \
settings.h \
logstore.h \
logentry.h \
+ movescountxml.h \
+ movescountjson.h \
movescount.h
FORMS += mainwindow.ui \
@@ -35,4 +39,4 @@ FORMS += mainwindow.ui \
INCLUDEPATH += ../libambit
QMAKE_LIBDIR += ../libambit-build
-LIBS += -lambit
+LIBS += -lambit -lqjson -lz
diff --git a/src/openambit/settingsdialog.cpp b/src/openambit/settingsdialog.cpp
index 5d65e4e..583f2b6 100644
--- a/src/openambit/settingsdialog.cpp
+++ b/src/openambit/settingsdialog.cpp
@@ -98,4 +98,6 @@ void SettingsDialog::writeSettings()
}
settings.setValue("storeDebugFiles", ui->checkBoxDebugFiles->isChecked());
settings.endGroup();
+
+ emit settingsSaved();
}
diff --git a/src/openambit/settingsdialog.h b/src/openambit/settingsdialog.h
index d05d4f0..2f8aae0 100644
--- a/src/openambit/settingsdialog.h
+++ b/src/openambit/settingsdialog.h
@@ -39,6 +39,9 @@ public:
explicit SettingsDialog(QWidget *parent = 0);
~SettingsDialog();
+signals:
+ void settingsSaved();
+
public slots:
void changePage(QListWidgetItem *current, QListWidgetItem *previous);
void accept();
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-running/openambit.git
More information about the Pkg-running-devel
mailing list