From 9d7e26aff06f48997984420cae8bab73f2d3df53 Mon Sep 17 00:00:00 2001 From: Dorian Zedler Date: Sun, 19 Apr 2020 13:09:46 +0200 Subject: [PATCH] fixed remote base station stuff --- ScStwSrc/headers/buzzerconn.h | 79 --- ScStwSrc/headers/climbingrace.h | 116 ---- ScStwSrc/headers/scstwappbackend.h | 30 +- ScStwSrc/headers/speedtimer.h | 48 -- .../SettingsBaseStationConnectionsPage.qml | 6 +- .../SettingsBaseStationPage.qml | 42 +- .../qml/components/ConnectionDelegate.qml | 1 + ScStwSrc/resources/qml/main.qml | 34 +- ScStwSrc/sources/buzzerconn.cpp | 367 ---------- ScStwSrc/sources/climbingrace.cpp | 656 ------------------ ScStwSrc/sources/main.cpp | 2 + ScStwSrc/sources/scstwappbackend.cpp | 146 +--- ScStwSrc/sources/speedtimer.cpp | 211 ------ 13 files changed, 83 insertions(+), 1655 deletions(-) delete mode 100644 ScStwSrc/headers/buzzerconn.h delete mode 100644 ScStwSrc/headers/climbingrace.h delete mode 100644 ScStwSrc/headers/speedtimer.h delete mode 100644 ScStwSrc/sources/buzzerconn.cpp delete mode 100644 ScStwSrc/sources/climbingrace.cpp delete mode 100644 ScStwSrc/sources/speedtimer.cpp diff --git a/ScStwSrc/headers/buzzerconn.h b/ScStwSrc/headers/buzzerconn.h deleted file mode 100644 index 8255edb..0000000 --- a/ScStwSrc/headers/buzzerconn.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef BUZZERCONN_H -#define BUZZERCONN_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct strReturnData{ - int status_code; - QString text; -}ReturnData_t; - -class BuzzerConn : public QObject -{ - Q_OBJECT -public: - explicit BuzzerConn(QObject *parent = nullptr, QString ip = "http://192.168.4.1", int port = 80); - double offset; - QList latest_offsets; - double latest_button_pressed; - double starttime; - bool connected; - int connection_progress; - QString ip; - int port; - int errors; - int errors_until_disconnect = 4; - - - -private: - QNetworkAccessManager *networkManager; - QNetworkAccessManager *reloadNetworkManager; - QDateTime *date; - QTcpSocket *socket; - QStringList pending_commands; - //QSemaphore dataPipe(1); -signals: - -public slots: - ReturnData_t senddata(QNetworkAccessManager * NetMan, QUrl serviceUrl, int timeout); - //function to communicate with the buzzer - Q_INVOKABLE signed long sendCommand(QString command, int timeout); - //function to send commands to the sensor - //Can be: - //command - return - //GET_TIMESTAMP - timestamp of the sensor - //GET_LASTPRESSED - timestamp of the sensor when it was triggered the last time - // - //error codes: - //(-1) : timeout - //(-2) : invalid data was recieved - Q_INVOKABLE QList gettimes(int timeout); - //function to get the times from the buzzer as a list with the normal network manager - Q_INVOKABLE bool connect(); - //function to connect to buzzer - Q_INVOKABLE bool calcoffset(QList times); - //function that calculates the average time offset between the buzzer and the device - Q_INVOKABLE bool buzzer_triggered(); - //function that checks ih the buzzer has been pushed since the last call of this function - Q_INVOKABLE bool start(); - //syncs the buzzer and the base to make a start possible - Q_INVOKABLE double get(QString key); - //can return some things (offset, lastpressed, currtime, connection_progress, connected) - Q_INVOKABLE QString test(); - Q_INVOKABLE bool refresh(); - //refreshed the connection to the buzzer - Q_INVOKABLE void appendCommand(QString command); - - -}; - -#endif // BUZZERCONN_H diff --git a/ScStwSrc/headers/climbingrace.h b/ScStwSrc/headers/climbingrace.h deleted file mode 100644 index 0c2258c..0000000 --- a/ScStwSrc/headers/climbingrace.h +++ /dev/null @@ -1,116 +0,0 @@ -#ifndef CLIMBINGRACE_H -#define CLIMBINGRACE_H - -#include -#include -#include -#include - -#include -#include - -#include "headers/appsettings.h" -#include "headers/speedtimer.h" - -class ClimbingRace : public QObject -{ - Q_OBJECT - - Q_PROPERTY(int state READ getState NOTIFY stateChanged) - Q_PROPERTY(int mode READ getMode NOTIFY modeChanged) - Q_PROPERTY(QVariant timers READ getTimerTextList NOTIFY timerTextChanged) - Q_PROPERTY(QString baseStationState READ getBaseStationState NOTIFY baseStationStateChanged) - Q_PROPERTY(QVariant baseStationConnections READ getBaseStationConnections NOTIFY baseStationConnectionsChanged) - Q_PROPERTY(double nextStartActionDelayProgress READ getNextStartActionDelayProgress NOTIFY nextStartActionDelayProgressChanged) - Q_PROPERTY(int nextStartAction READ getNextStartAction NOTIFY nextStartActionChanged) - Q_PROPERTY(QVariantMap baseStationProperties READ getBaseStationProperties NOTIFY baseStationPropertiesChanged) - -public: - explicit ClimbingRace(QObject *parent = nullptr); - - enum RaceMode { LOCAL, REMOTE }; - RaceMode mode; - -private: - AppSettings * appSettings; - ScStwClient * scStwClient; - - QMediaPlayer * player; - - QTimer * timerTextRefreshTimer; - QTimer * nextStartActionTimer; - - QDateTime *date; - - QList speedTimers; - - double nextStartActionDelayProgress; - // only used in remote mode: - double nextStartActionDelayStartedAt; - double nextStartActionTotalDelay; - - // helper vars - QVariantList qmlTimers; - -private slots: - // helper functions - void playSoundsAndStartRace(); - bool playSound(QString path); - void setState(ScStw::RaceState newState); - void refreshMode(); - void refreshTimerText(); - - bool refreshRemoteTimers(QVariantList timers); - -signals: - void nextStartActionChanged(); - void nextStartActionDelayProgressChanged(); - - void stateChanged(int state); - void modeChanged(); - void timerTextChanged(); - void baseStationStateChanged(); - void baseStationConnectionsChanged(); - void baseStationPropertiesChanged(); - -public slots: - Q_INVOKABLE int startRace(); - Q_INVOKABLE int stopRace(int type); - Q_INVOKABLE int resetRace(); - - // base station sync - void handleBaseStationSignal(ScStw::SignalKey key, QVariant data); - Q_INVOKABLE bool pairConnectedUsbExtensions(); - - // functions for qml - Q_INVOKABLE int getState(); - Q_INVOKABLE int getMode(); - Q_INVOKABLE QVariant getTimerTextList(); - Q_INVOKABLE double getNextStartActionDelayProgress(); - Q_INVOKABLE int getNextStartAction(); - - Q_INVOKABLE void writeSetting(QString key, QVariant value); - Q_INVOKABLE void writeSetting(ScStw::BaseStationSetting key, QVariant value); - Q_INVOKABLE QString readSetting(QString key); - Q_INVOKABLE QString readSetting(ScStw::BaseStationSetting key); - - Q_INVOKABLE void connectBaseStation(); - Q_INVOKABLE void disconnectBaseStation(); - Q_INVOKABLE QString getBaseStationState(); - Q_INVOKABLE QVariant getBaseStationConnections(); - Q_INVOKABLE QVariantMap getBaseStationProperties(); - - Q_INVOKABLE bool updateBasestationFirmware(); - Q_INVOKABLE bool updateBasestationTime(); - - // athlete management - Q_INVOKABLE QVariant getAthletes(); - Q_INVOKABLE bool createAthlete( QString userName, QString fullName ); - Q_INVOKABLE bool deleteAthlete( QString userName ); - Q_INVOKABLE bool selectAthlete( QString userName, int timerId ); - Q_INVOKABLE QVariant getResults( QString userName ); - - Q_INVOKABLE bool reloadBaseStationIpAdress(); -}; - -#endif // CLIMBINGRACE_H diff --git a/ScStwSrc/headers/scstwappbackend.h b/ScStwSrc/headers/scstwappbackend.h index 4776ca7..14a67bd 100644 --- a/ScStwSrc/headers/scstwappbackend.h +++ b/ScStwSrc/headers/scstwappbackend.h @@ -6,19 +6,18 @@ #include #include #include +#include #include "headers/appsettings.h" + class ScStwAppBackend : public QObject { Q_OBJECT - //Q_PROPERTY(int state READ getState NOTIFY stateChanged) Q_PROPERTY(int mode READ getMode NOTIFY modeChanged) - //Q_PROPERTY(QString baseStationState READ getBaseStationState NOTIFY baseStationStateChanged) Q_PROPERTY(ScStwRace* race READ getRace NOTIFY raceChanged) - Q_PROPERTY(QVariant baseStationConnections READ getBaseStationConnections NOTIFY baseStationConnectionsChanged) - Q_PROPERTY(QVariantMap baseStationProperties READ getBaseStationProperties NOTIFY baseStationPropertiesChanged) + Q_PROPERTY(ScStwClient *scStwClient READ getScStwClient NOTIFY scStwClientChanged) public: explicit ScStwAppBackend(QObject *parent = nullptr); @@ -35,15 +34,12 @@ private: // TODO: DOINEED? QTimer * nextStartActionTimer; ScStwRace * localRace; + ScStwRemoteMonitorRace * remoteRace; public slots: - // base station sync - //void handleBaseStationSignal(ScStw::SignalKey key, QVariant data); - Q_INVOKABLE bool pairConnectedUsbExtensions(); - // functions for qml Q_INVOKABLE ScStwRace *getRace(); - //Q_INVOKABLE int getState(); + Q_INVOKABLE ScStwClient *getScStwClient(); Q_INVOKABLE int getMode(); Q_INVOKABLE void writeSetting(QString key, QVariant value); @@ -51,15 +47,6 @@ public slots: Q_INVOKABLE QString readSetting(QString key); Q_INVOKABLE QString readSetting(ScStw::BaseStationSetting key); - Q_INVOKABLE void connectBaseStation(); - Q_INVOKABLE void disconnectBaseStation(); - Q_INVOKABLE QString getBaseStationState(); - Q_INVOKABLE QVariant getBaseStationConnections(); - Q_INVOKABLE QVariantMap getBaseStationProperties(); - - Q_INVOKABLE bool updateBasestationFirmware(); - Q_INVOKABLE bool updateBasestationTime(); - // athlete management Q_INVOKABLE QVariant getAthletes(); Q_INVOKABLE bool createAthlete( QString userName, QString fullName ); @@ -67,23 +54,20 @@ public slots: Q_INVOKABLE bool selectAthlete( QString userName, int timerId ); Q_INVOKABLE QVariant getResults( QString userName ); - Q_INVOKABLE bool reloadBaseStationIpAdress(); - - private slots: void refreshTimerText(); void refreshMode(); void reloadRaceSettings(); + void reloadBaseStationIpAdress(); signals: void modeChanged(); void raceChanged(); + void scStwClientChanged(); void baseStationStateChanged(); void baseStationConnectionsChanged(); void baseStationPropertiesChanged(); - - }; #endif // SCSTWAPPBACKEND_H diff --git a/ScStwSrc/headers/speedtimer.h b/ScStwSrc/headers/speedtimer.h deleted file mode 100644 index 1beca26..0000000 --- a/ScStwSrc/headers/speedtimer.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef SPEEDTIMER_H -#define SPEEDTIMER_H - -#include -#include -#include -#include -#include - -class SpeedTimer : public QObject -{ - Q_OBJECT -public: - explicit SpeedTimer(QObject *parent = nullptr); - - enum timerState { IDLE, STARTING, WAITING, RUNNING, WON, LOST, FAILED, CANCELLED, DISABLED }; - timerState state; - - // variables for capturing the time - double startTime; - double stopTime; - double stoppedTime; - double reactionTime; - -signals: - void stateChanged(timerState newState); - void startCanceled(bool falseStart); - -public slots: - bool start(bool force = false); - bool stop(int type, bool force = false); - bool reset(bool force = false); - - void setState(timerState newState); - QString getState(); - double getCurrTime(); - QString getText(); - - //helper functions - - void delay(int mSecs); - - timerState stateFromString(QString state); -private: - QDateTime *date; -}; - -#endif // SPEEDTIMER_H diff --git a/ScStwSrc/resources/qml/SettingsDialog/SettingsBaseStationConnectionsPage.qml b/ScStwSrc/resources/qml/SettingsDialog/SettingsBaseStationConnectionsPage.qml index 919e9a8..e1448a1 100644 --- a/ScStwSrc/resources/qml/SettingsDialog/SettingsBaseStationConnectionsPage.qml +++ b/ScStwSrc/resources/qml/SettingsDialog/SettingsBaseStationConnectionsPage.qml @@ -16,7 +16,7 @@ ListView { spacing: parentObj.rowSpacing boundsBehavior: Flickable.StopAtBounds - model: speedBackend.baseStationConnections.length + model: speedBackend.scStwClient.extensions.length delegate: ConnectionDelegate { opacity: 1 @@ -24,7 +24,7 @@ ListView { width: parent.width height: parentObj.delegateHeight - text: speedBackend.baseStationConnections[index]["name"] - status: {'status': speedBackend.baseStationConnections[index]["state"], 'progress': speedBackend.baseStationConnections[index]["progress"]} + text: speedBackend.scStwClient.extensions[index]["name"] + status: {'status': speedBackend.scStwClient.extensions[index]["state"], 'progress': speedBackend.scStwClient.extensions[index]["progress"]} } } diff --git a/ScStwSrc/resources/qml/SettingsDialog/SettingsBaseStationPage.qml b/ScStwSrc/resources/qml/SettingsDialog/SettingsBaseStationPage.qml index 1aaa321..d4f4488 100644 --- a/ScStwSrc/resources/qml/SettingsDialog/SettingsBaseStationPage.qml +++ b/ScStwSrc/resources/qml/SettingsDialog/SettingsBaseStationPage.qml @@ -6,6 +6,9 @@ import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 import QtQuick.Controls.Styles 1.4 import QtQuick.Templates 2.12 as T + +import com.itsblue.speedclimbingstopwatch 2.0 + import "../components" Column { @@ -13,7 +16,7 @@ Column { property string title: qsTr("base station") - property bool baseConnected: speedBackend.baseStationState === "connected" + property bool baseConnected: speedBackend.scStwClient.state === ScStwClient.CONNECTED property var parentObj opacity: 0 @@ -31,18 +34,32 @@ Column { onTriggered: { busyDl.open() - var ret = speedBackend.updateBasestationFirmware() + var ret = speedBackend.scStwClient.updateFirmware() busyDl.displayMessageAndClose(ret ? "OK":"error", ret ? "#6bd43b":"#e03b2f" ) } } ConnectionDelegate { id: connectToBaseDel + + function clientStateToString(state) { + switch(state) { + case ScStwClient.DISCONNECTED: + return "disconnected" + case ScStwClient.CONNECTING: + return "connecting" + case ScStwClient.INITIALISING: + return "connecting" + case ScStwClient.CONNECTED: + return "connected" + } + } + text: status.status === "connected" ? qsTr("disconnect"): status.status === "disconnected" ? qsTr("connect"):qsTr("connecting...") - status: { "status": speedBackend.baseStationState, "progress": 100 } - connect: speedBackend.connectBaseStation - disconnect: speedBackend.disconnectBaseStation + status: { "status": clientStateToString(speedBackend.scStwClient.state), "progress": 100 } + connect: speedBackend.scStwClient.connectToHost + disconnect: speedBackend.scStwClient.closeConnection type: "baseStation" width: parent.width @@ -136,7 +153,6 @@ Column { onInputTextChanged: { speedBackend.writeSetting("baseStationIpAdress", inputText) - speedBackend.reloadBaseStationIpAdress() } width: parent.width @@ -246,8 +262,8 @@ Column { onClicked: { busyDl.open() - var ret = speedBackend.pairConnectedUsbExtensions() - busyDl.displayMessageAndClose(ret ? "OK":"error", ret ? "#6bd43b":"#e03b2f" ) + var ret = speedBackend.scStwClient.pairConnectedUsbExtensions() + busyDl.displayMessageAndClose(ret === ScStw.Success ? "OK":"error", ret ? "#6bd43b":"#e03b2f" ) } } @@ -255,8 +271,8 @@ Column { id: baseStationUpdateDel // 0: hidden 1: update firmware 2: sync time - property int mode: speedBackend.baseStationProperties["firmware"]["upToDate"] ? - (Math.abs(parseInt(speedBackend.baseStationProperties["timeOffset"])) > 10000 ? 2:0) + property int mode: speedBackend.scStwClient.isFirmwareUpToDate() ? + (Math.abs(parseInt(speedBackend.scStwClient.getTimeOffset())) > 10000 ? 2:0) :1 width: parent.width @@ -272,7 +288,7 @@ Column { } else if(mode === 2){ busyDl.open() - var ret = speedBackend.updateBasestationTime() + var ret = speedBackend.scStwClient.updateTime() busyDl.displayMessageAndClose(ret ? "OK":"error", ret ? "#6bd43b":"#e03b2f" ) } @@ -312,12 +328,12 @@ Column { minimumPixelSize: 1 color: appTheme.style.lineColor - text: "version: " + speedBackend.baseStationProperties["firmware"]["version"] + text: "version: " + speedBackend.scStwClient.getFirmwareVersion() } Label { - property var date: new Date(new Date().getTime() + parseInt(speedBackend.baseStationProperties["timeOffset"])) + property var date: new Date(new Date().getTime() + parseInt(speedBackend.scStwClient.getTimeOffset())) anchors { top: parent.top diff --git a/ScStwSrc/resources/qml/components/ConnectionDelegate.qml b/ScStwSrc/resources/qml/components/ConnectionDelegate.qml index 90f9021..54fc7b0 100644 --- a/ScStwSrc/resources/qml/components/ConnectionDelegate.qml +++ b/ScStwSrc/resources/qml/components/ConnectionDelegate.qml @@ -10,6 +10,7 @@ SmoothItemDelegate { property var disconnect property string type + text: qsTr(type) enabled: (status.status === "disconnected" && control.connect !== undefined) || ( status.status === "connected" && control.disconnect !== undefined ) diff --git a/ScStwSrc/resources/qml/main.qml b/ScStwSrc/resources/qml/main.qml index 5868836..d8efa41 100644 --- a/ScStwSrc/resources/qml/main.qml +++ b/ScStwSrc/resources/qml/main.qml @@ -67,8 +67,8 @@ Window { target: speedBackend.race onStateChanged: { var stateString - console.log("race state changed to: " + state) - switch (state){ + console.log("race state changed to: " + speedBackend.race.state) + switch (speedBackend.race.state){ case ScStwRace.IDLE: stateString = "IDLE" break; @@ -200,8 +200,8 @@ Window { height: parent.height elide: "ElideRight" - color: ["WON"].includes(speedBackend.timers[index]["state"]) ? appTheme.style.successColor : - ["LOST", "FAILED"].includes(speedBackend.timers[index]["state"]) ? appTheme.style.errorColor: + color: [ScStwTimer.WON].includes(speedBackend.race.timers[index]["state"]) ? appTheme.style.successColor : + [ScStwTimer.LOST, ScStwTimer.FAILED].includes(speedBackend.race.timers[index]["state"]) ? appTheme.style.errorColor: appTheme.style.textColor enabled: speedBackend.race.timers[index]["state"] !== ScStwTimer.DISABLED @@ -282,7 +282,21 @@ Window { ConnectionIcon { id: baseConnConnIcon - status: speedBackend.baseStationState + + function clientStateToString(state) { + switch(state) { + case ScStwClient.DISCONNECTED: + return "disconnected" + case ScStwClient.CONNECTING: + return "connecting" + case ScStwClient.INITIALISING: + return "connecting" + case ScStwClient.CONNECTED: + return "connected" + } + } + + status: clientStateToString(speedBackend.scStwClient.state) source: appTheme.style.baseStationIcon anchors { @@ -311,14 +325,14 @@ Window { Repeater { id: connectedExtensionsRep anchors.fill: parent - model: speedBackend.baseStationConnections.length + model: speedBackend.scStwClient.extensions.lenght delegate: ConnectionIcon { id: buzzerConnIcon - status: speedBackend.baseStationConnections[index]["state"] + status: speedBackend.extensions[index]["state"] source: { var source - switch(speedBackend.baseStationConnections[index]["type"]){ + switch(speedBackend.extensions[index]["type"]){ case "STARTPAD": source = appTheme.style.startpadIcon break @@ -373,7 +387,7 @@ Window { text: "start" property int size: app.landscape() ? parent.width * 0.5:parent.height * 0.5 property color backgroundColor: appTheme.style.buttonColor - property bool progressControlActivated: speedBackend.baseStationState === "connected" && app.state === "RUNNING" + property bool progressControlActivated: speedBackend.scStwClient.state === ScStwClient.CONNECTED && app.state === "RUNNING" delay: progressControlActivated ? 2000:0 anchors { @@ -681,7 +695,7 @@ Window { enabled: height > 0 - state: speedBackend.baseStationState === "connected" ? "visible":"hidden" + state: speedBackend.scStwClient.state === ScStwClient.CONNECTED ? "visible":"hidden" width: height onClicked: { diff --git a/ScStwSrc/sources/buzzerconn.cpp b/ScStwSrc/sources/buzzerconn.cpp deleted file mode 100644 index b3c30aa..0000000 --- a/ScStwSrc/sources/buzzerconn.cpp +++ /dev/null @@ -1,367 +0,0 @@ -/* - Speed Climbing Stopwatch - Simple Stopwatch for Climbers - Copyright (C) 2018 Itsblue Development - Dorian Zeder - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, version 3 of the License. - - 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ - -#include "headers/buzzerconn.h" - -BuzzerConn::BuzzerConn(QObject *parent, QString ip, int port) : QObject(parent) -{ - this->networkManager = new QNetworkAccessManager(); - this->reloadNetworkManager = new QNetworkAccessManager(); - - this->socket = new QTcpSocket(); - - this->date = new QDateTime; - this->latest_button_pressed = 0; - this->connected = false; - - this->ip = ip; - this->port = port; - // "http://192.168.4.1" -} - -bool BuzzerConn::connect() -{ - qDebug() << "connecting..."; - - //wait until the request has finished - QEventLoop loop; - QTimer timer; - - timer.setSingleShot(true); - loop.connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); - loop.connect(this->socket, SIGNAL(connected()), &loop, SLOT(quit())); - - timer.start(3000); - this->socket->connectToHost(this->ip, this->port); - loop.exec(); - timer.stop(); - - if(timer.remainingTime() == 0){ - //the time has been triggered -> timeout - return(false); - } - - - QList times = gettimes(2000); - qDebug() << times[0]; - if(times[0] == 200.0){ - this->latest_button_pressed = times[2]; - for(int i=0;i<=100;i++){ - this->connection_progress = i; - if(!calcoffset(this->gettimes(1000))){ - this->connection_progress = 100; - this->connected = false; - return(false); - } - } - this->connected = true; - return(true); - } - else{ - this->connected = false; - return(false); - } -} - -bool BuzzerConn::calcoffset(QList times) -{ - if(times.length() != 3){ - return(false); - } - if(times[0] == 200.0){ - this->latest_button_pressed = times[2]; - double offset = date->currentMSecsSinceEpoch() - times[1]; - if(this->latest_offsets.length()>=100){ - this->latest_offsets.removeFirst(); - } - this->latest_offsets.append(offset); - - double mem = 0; - for(int i=0;ioffset = mem / double(latest_offsets.length()); - qDebug("%20f", this->offset); - return(true); - } - else { - //this->connected = false; - return(false); - } -} - -QList BuzzerConn::gettimes(int timeout) -{ - // QList times; - // ReturnData_t ret = senddata(this->networkManager, QUrl(this->ip), timeout); - // times.append(double(ret.status_code)); - - // if(ret.status_code == 200){ - // ret.text.replace("\n",""); - // ret.text.replace("\r",""); - // QStringList times_cache = ret.text.split("
"); - // times.append(times_cache[0].toDouble()); - // times.append(times_cache[1].toDouble()); - - // return(times); - // } - // else{ - // return(times); - // } - - QList times; - signed long ret; - ret = this->sendCommand("GET_TIMESTAMP", timeout); - if(ret >= 0){ - times.append(double(200)); - times.append(double(ret)); - ret = this->sendCommand("GET_LASTPRESSED", timeout); - if(ret >= 0){ - times.append(double(ret)); - return(times); - } - else { - times[0] = ret; - } - - } - else { - times.append(ret); - } - return(times); - -} - -bool BuzzerConn::buzzer_triggered() -{ - - if(!this->connected){ - return(false); - } - - if(pending_commands.length() > 0){ - QString command = this->pending_commands.first(); - - signed long retval = this->sendCommand(command, 800); - if(retval > 0){ - this->pending_commands.removeFirst(); - } - } - - QList times = this->gettimes(1000); - if(times[0] == 200.0){ - if(times[2] > this->latest_button_pressed){ - this->latest_button_pressed = times[2]; - - return(true); - } - else { - return(false); - } - } - else{ - //this->connected = false; - return(false); - } -} - -bool BuzzerConn::start() -{ - if(!this->connected){ - return(false); - } - QList times = this->gettimes(1000); - if(times[0] == 200.0 && this->connected){ - this->latest_button_pressed = times[2]; - return(true); - } - else{ - this->connected = false; - return(false); - } -} - -double BuzzerConn::get(QString key) -{ - if(key == "offset"){ - return(this->offset); - } - else if (key == "lastpressed") { - return(this->latest_button_pressed); - } - else if( key == "currtime") { - return(this->date->currentMSecsSinceEpoch()); - } - else if( key == "connection_progress") { - return(this->connection_progress); - } - else if( key == "connected") { - if(this->connected){ - return(1); - } - return(0); - } -} - -QString BuzzerConn::test() -{ - ReturnData_t ret = this->senddata(this->networkManager, QUrl("http://www.google.de"), 500); - return(ret.text); -} - -bool BuzzerConn::refresh() -{ - if(!this->connected){ - return(false); - } -// QList times; -// ReturnData_t ret = senddata(this->reloadNetworkManager, QUrl(this->ip), 1000); -// times.append(double(ret.status_code)); - -// if(ret.status_code == 200){ -// ret.text.replace("\n",""); -// ret.text.replace("\r",""); -// QStringList times_cache = ret.text.split("
"); -// times.append(times_cache[0].toDouble()); -// times.append(times_cache[1].toDouble()); -// calcoffset(times); -// return(true); -// } -// else{ -// //this->connected = false; -// return(false); -// } - - if(pending_commands.length() > 0){ - QString command = this->pending_commands.first(); - - signed long retval = this->sendCommand(command, 800); - if(retval > 0){ - this->pending_commands.removeFirst(); - } - } - - //refresh the times - QList ret = this->gettimes(800); - if(ret[0] >= 0){ - this->errors = 0; - return(this->calcoffset(ret)); - } - else { - this->errors ++; - if(this->errors > errors_until_disconnect){ - this->socket->disconnectFromHost(); - this->connected = false; - } - return(false); - } - -} - -ReturnData_t BuzzerConn::senddata(QNetworkAccessManager * NetMan, QUrl serviceUrl, int timeout) -{ - - ReturnData_t ret; //this is a custom type to store the returned data - // Call the webservice - - QNetworkRequest request(serviceUrl); - request.setHeader(QNetworkRequest::ContentTypeHeader, - "application/x-www-form-urlencoded"); - - //send a POST request with the given url and data to the server - QUrlQuery pdata; - QNetworkReply* reply; - - //wait until the request has finished - QEventLoop loop; - QTimer timer; - - timer.setSingleShot(true); - loop.connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); - loop.connect(NetMan, SIGNAL(finished(QNetworkReply*)), SLOT(quit())); - - timer.start(timeout); - reply = NetMan->post(request, pdata.toString(QUrl::FullyEncoded).toUtf8()); - loop.exec(); - timer.stop(); - - //get the status code - QVariant status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); - - ret.status_code = status_code.toInt(); - if(ret.status_code == 0){ //if the statuscode is zero, the connecion to the server was not possible - ret.status_code = 444; - } - //get the full text response - ret.text = QString::fromUtf8(reply->readAll()); - - //return the data - return(ret); -} - -signed long BuzzerConn::sendCommand(QString command, int timeout){ - - //if there is any data in the storage, clear it - if(this->socket->bytesAvailable() > 0){ - this->socket->readAll(); - } - - //send request to the socket server - QByteArray arrBlock; - QDataStream out(&arrBlock, QIODevice::WriteOnly); - //out.setVersion(QDataStream::Qt_5_10); - out << quint16(0) << command; - - out.device()->seek(0); - out << quint16(arrBlock.size() - sizeof(quint16)); - - this->socket->write(arrBlock); - - //now wait for the server of the sensor to answer - QEventLoop loop; - QTimer timer; - - timer.setSingleShot(true); - loop.connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); - loop.connect(socket, SIGNAL(readyRead()), &loop, SLOT(quit())); - timer.start(timeout); - loop.exec(); - - //loop finished - timer.stop(); - if(timer.remainingTime() == 0){ - //the time has been triggered -> timeout - return(-1); - } - - //if the data is not 4 bites long if is invalid -> clear and terminate - if(this->socket->bytesAvailable() != 4){ - this->socket->readAll(); - return(-2); - } - long data = 0; - this->socket->read((char*)&data,4); - - qDebug() << data; - qDebug() << this->socket->bytesAvailable(); - - return data; -} - -void BuzzerConn::appendCommand(QString command){ - this->pending_commands.append(command); -} diff --git a/ScStwSrc/sources/climbingrace.cpp b/ScStwSrc/sources/climbingrace.cpp deleted file mode 100644 index cd16ef7..0000000 --- a/ScStwSrc/sources/climbingrace.cpp +++ /dev/null @@ -1,656 +0,0 @@ -#include "headers/climbingrace.h" - -/* - * manages: - * - global state - * - timers - * - sounds - * - next start action - * - next start action delay progress - * - settings (remote and local) - */ - -ClimbingRace::ClimbingRace(QObject *parent) : QObject(parent) -{ - this->state = ScStw::ScStw::IDLE; - this->mode = LOCAL; - - this->appSettings = new AppSettings(this); - this->scStwClient = new ScStwClient(); - - this->scStwClient->setIP(pGlobalAppSettings->loadSetting("baseStationIpAdress")); - connect(this->scStwClient, &ScStwClient::stateChanged, this, &ClimbingRace::baseStationStateChanged); - connect(this->scStwClient, &ScStwClient::stateChanged, this, &ClimbingRace::refreshMode); - connect(this->scStwClient, &ScStwClient::gotSignal, this, &ClimbingRace::handleBaseStationSignal); - connect(this, &ClimbingRace::baseStationStateChanged, this, &ClimbingRace::baseStationPropertiesChanged); - - this->speedTimers.append( new SpeedTimer(this) ); - - this->player = new QMediaPlayer; - this->date = new QDateTime; - - this->nextStartActionTimer = new QTimer(this); - nextStartActionTimer->setSingleShot(true); - - this->timerTextRefreshTimer = new QTimer(this); - this->timerTextRefreshTimer->setInterval(1); - this->timerTextRefreshTimer->setSingleShot(true); - this->timerTextRefreshTimer->connect(this->timerTextRefreshTimer, &QTimer::timeout, this, &ClimbingRace::refreshTimerText); - this->refreshTimerText(); -} - -// -------------------------- -// --- Main Functionality --- -// -------------------------- - -int ClimbingRace::startRace() { - - if(this->state != ScStw::IDLE) { - return 904; - } - - qDebug() << "+ --- starting race"; - - int returnCode = 900; - - switch (this->mode) { - case LOCAL: - { - - this->setState(ScStw::STARTING); - - this->nextStartAction = ScStw::None; - this->playSoundsAndStartRace(); - - returnCode = 200; - - break; - } - case REMOTE: - { - QVariantMap reply = this->scStwClient->sendCommand(1000); - - if(reply["status"] != 200){ - //handle Error!! - returnCode = reply["status"].toInt(); - } - else { - - returnCode = 200; - - } - - break; - } - } - - return returnCode; -} - -int ClimbingRace::stopRace(int type) { - - if(this->state != ScStw::RUNNING && this->state != ScStw::STARTING) { - return 904; - } - - // type can be: - // 0: stopp - // 1: cancel - // 2: fail (fase start) - - qDebug() << "+ --- stopping race"; - - int returnCode = 900; - - switch (this->mode) { - case LOCAL: - { - - if(type == 1){ - this->nextStartActionTimer->stop(); - this->player->stop(); - this->nextStartAction = ScStw::None; - } - - returnCode = this->speedTimers[0]->stop(type) ? 200:904; - - if(returnCode == 200) { - this->setState(ScStw::STOPPED); - } - - break; - } - case REMOTE: - { - QVariantMap reply = this->scStwClient->sendCommand(1001); - - if(reply["status"] != 200){ - returnCode = reply["status"].toInt(); - } - else { - returnCode = 200; - } - - break; - } - } - - return returnCode; -} - -int ClimbingRace::resetRace() { - - if(this->state != ScStw::STOPPED) { - return 904; - } - - qDebug() << "+ --- resetting race"; - - int returnCode = 900; - - - switch (this->mode) { - case LOCAL: - { - returnCode = this->speedTimers[0]->reset() ? 200:904; - - if(returnCode == 200){ - this->setState(ScStw::IDLE); - } - - break; - } - case REMOTE: - { - - QVariantMap reply = this->scStwClient->sendCommand(1002); - - if(reply["status"] != 200){ - //handle Error!! - returnCode = reply["status"].toInt(); - } - else { - returnCode = 200; - } - - break; - } - } - - return returnCode; -} - -// ------------------------- -// --- Base Station sync --- -// ------------------------- - -/** - * @brief ClimbingRace::handleBaseStationUpdate - * - * Function to handle an update, sent by the base station, which indicates - * that some remote value (like a state) has changed - * - * @param data - */ -void ClimbingRace::handleBaseStationSignal(ScStw::SignalKey key, QVariant data) { - qDebug() << "got signal: " << data; - switch (key) { - case ScStw::RaceStateChanged: - { - // the remote race state has changed - this->setState( ScStw::RaceState( data.toInt() ) ); - break; - } - case ScStw::TimersChanged: - { - // the remote timers have changed - this->refreshRemoteTimers(data.toList()); - break; - } - case ScStw::NextStartActionChanged: - { - // the next start action has changed - this->nextStartActionTotalDelay = data.toMap()["nextActionDelay"].toDouble(); - this->nextStartActionDelayStartedAt = this->date->currentMSecsSinceEpoch() - (this->nextStartActionTotalDelay * data.toMap()["nextActionDelayProg"].toDouble()); - this->nextStartAction = ScStw::NextStartAction( data.toMap()["nextAction"].toInt() ); - - emit this->nextStartActionChanged(); - break; - } - case ScStw::ExtensionsChanged: - { - emit this->baseStationConnectionsChanged(); - break; - } - case ScStw::InvalidSignal: - return; - - } -} - -bool ClimbingRace::refreshRemoteTimers(QVariantList timers) { - - if(timers.length() != speedTimers.length()){ - // local timers are out of sync - - // delete all current timers - foreach(SpeedTimer * locTimer, this->speedTimers){ - delete locTimer; - } - - speedTimers.clear(); - - foreach(QVariant remTimer, timers){ - // create a local timer for each remote timer - this->speedTimers.append(new SpeedTimer(this)); - } - } - - foreach(QVariant remTimer, timers){ - int currId = remTimer.toMap()["id"].toInt(); - speedTimers[currId]->startTime = this->date->currentMSecsSinceEpoch() - remTimer.toMap()["currentTime"].toDouble(); - speedTimers[currId]->stoppedTime = remTimer.toMap()["currentTime"].toDouble(); - speedTimers[currId]->reactionTime = remTimer.toMap()["reactionTime"].toDouble(); - - speedTimers[currId]->setState(SpeedTimer::timerState(remTimer.toMap()["state"].toInt())); - } - - return true; - -} - -// ------------------------ -// --- helper functions --- -// ------------------------ - -void ClimbingRace::playSoundsAndStartRace() { - qDebug() << "next Action: " << nextStartAction; - - nextStartActionTimer->disconnect(nextStartActionTimer, SIGNAL(timeout()), this, SLOT(playSoundsAndStartRace())); - - switch (this->nextStartAction) { - case ScStw::AtYourMarks: - { - if(!playSound("qrc:/sounds/at_marks_1.wav")){ - return; - } - if(appSettings->loadSetting("ready_en") == "true"){ - nextStartAction = ScStw::Ready; - nextStartActionTimer->setInterval(appSettings->loadSetting("ready_delay").toInt() <= 0 ? 1:appSettings->loadSetting("ready_delay").toInt()); - } - else{ - nextStartAction = ScStw::Start; - nextStartActionTimer->setInterval(1); - } - - break; - } - case ScStw::Ready: - { - if(!playSound("qrc:/sounds/ready_1.wav")){ - return; - } - nextStartAction = ScStw::Start; - nextStartActionTimer->setInterval(1); - - break; - } - case ScStw::Start: - { - if(!playSound("qrc:/sounds/IFSC_STARTSIGNAL_SINE.wav")){ - return; - } - nextStartAction = ScStw::None; - nextStartActionTimer->disconnect(nextStartActionTimer, SIGNAL(timeout()), this, SLOT(playSoundsAndStartRace())); - - this->setState(ScStw::RUNNING); - speedTimers[0]->start(); - - emit this->nextStartActionChanged(); - - return; - } - case ScStw::None: - { - this->speedTimers[0]->setState(SpeedTimer::STARTING); - if(appSettings->loadSetting("at_marks_en") == "true"){ - nextStartAction = ScStw::AtYourMarks; - nextStartActionTimer->setInterval(appSettings->loadSetting("at_marks_delay").toInt() <= 0 ? 1:appSettings->loadSetting("at_marks_delay").toInt()); - } - else if(appSettings->loadSetting("ready_en") == "true"){ - nextStartAction = ScStw::Ready; - nextStartActionTimer->setInterval(appSettings->loadSetting("ready_delay").toInt() <= 0 ? 1:appSettings->loadSetting("ready_delay").toInt()); - } - else{ - nextStartAction = ScStw::Start; - nextStartActionTimer->setInterval(1); - } - - break; - } - } - - emit this->nextStartActionChanged(); - - nextStartActionTimer->connect(nextStartActionTimer, SIGNAL(timeout()), this, SLOT(playSoundsAndStartRace())); - nextStartActionTimer->start(); -} - -bool ClimbingRace::playSound(QString path) { - - player->setMedia(QUrl(path)); - player->setVolume(50); - player->play(); - - QTimer timer; - timer.setInterval(1); - timer.setSingleShot(true); - - QEventLoop loop; - loop.connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); - - while (player->mediaStatus() == QMediaPlayer::LoadingMedia || player->mediaStatus() == QMediaPlayer::BufferingMedia || player->mediaStatus() == QMediaPlayer::BufferedMedia) { - timer.start(); - loop.exec(); - } - - if(player->mediaStatus() == QMediaPlayer::EndOfMedia){ - return true; - } - else { - return false; - } -} - -void ClimbingRace::setState(ScStw::RaceState newState) { - if(newState != this->state) { - this->state = newState; - this->stateChanged(newState); - } -} - -void ClimbingRace::refreshMode() { - RaceMode newMode; - if(this->scStwClient->getState() == ScStwClient::CONNECTED){ - newMode = REMOTE; - } - else { - newMode = LOCAL; - } - - if(this->mode != newMode){ - - if(newMode == LOCAL){ - // if the new mode is local -> connection to base station has been lost - - // reset race - // reset state - this->setState(ScStw::IDLE); - - // reset timers - // go back to one timer - for (int i = 0;ispeedTimers.length();i++) { - delete this->speedTimers[i]; - } - - this->speedTimers.clear(); - - this->speedTimers.append(new SpeedTimer); - } - - this->mode = newMode; - emit this->modeChanged(); - } - -} - -void ClimbingRace::refreshTimerText() { - - // --- refresh timer text --- - - QVariantList newTimerTextList; - - foreach(SpeedTimer * timer, this->speedTimers){ - QVariantMap timerMap = {{"text",timer->getText()}, {"reacttime", timer->reactionTime}, {"state", timer->getState()}, {"id", this->speedTimers.indexOf(timer)}}; - newTimerTextList.append(timerMap); - } - - if(newTimerTextList != this->qmlTimers){ - this->qmlTimers = newTimerTextList; - emit timerTextChanged(); - } - - // --- refresh next start action delay progress --- - double nextStartActionRemainingDelay = 0; - - switch (this->mode) { - case LOCAL: { - - // get remaining and total next start action delay time - if(nextStartAction == 0){ - this->nextStartActionTotalDelay = appSettings->loadSetting("at_marks_delay").toDouble(); - } - else if (nextStartAction == 1) { - this->nextStartActionTotalDelay = appSettings->loadSetting("ready_delay").toDouble(); - } - - nextStartActionRemainingDelay = this->nextStartActionTimer->remainingTime(); - - break; - } - case REMOTE: { - - // calculate remaining next start action delay time - nextStartActionRemainingDelay = this->nextStartActionTotalDelay - ( this->date->currentMSecsSinceEpoch() - this->nextStartActionDelayStartedAt ); - break; - } - } - - // calculate next start action delay progress - if(nextStartActionRemainingDelay > 0){ - this->nextStartActionDelayProgress = nextStartActionRemainingDelay / this->nextStartActionTotalDelay; - emit this->nextStartActionDelayProgressChanged(); - } - else { - this->nextStartActionDelayProgress = 0; - emit this->nextStartActionDelayProgressChanged(); - } - - - /*if (this->mode == REMOTE && this->state == ScStw::IDLE) { - this->nextStartActionDelayProgress = 0; - emit this->nextStartActionDelayProgressChanged(); - }*/ - - this->timerTextRefreshTimer->start(); -} - -bool ClimbingRace::pairConnectedUsbExtensions() { - QVariantMap ret = this->scStwClient->sendCommand(5002, "", 10000); - qDebug() << ret; - return ret["status"] == 200; -} - -// - athlete management - - -QVariant ClimbingRace::getAthletes() { - QVariantMap reply = this->scStwClient->sendCommand(4003); - - if(reply["status"] != 200){ - //handle Error!! - qDebug() << "+ --- error getting athletes: " << reply["status"]; - return false; - } - - QVariantMap tmpAthletes = reply["data"].toMap(); - - //qDebug() << tmpAthletes; - - return tmpAthletes; -} - -bool ClimbingRace::createAthlete(QString userName, QString fullName) { - - QVariant requestData = QVariantMap({{"fullName", fullName}, {"userName", userName}}); - - QVariantMap reply = this->scStwClient->sendCommand(4001, requestData.toJsonValue()); - - if(reply["status"] != 200){ - //handle Error!! - qDebug() << "+ --- error creating athlete: " << reply["status"]; - return false; - } - - return true; -} - -bool ClimbingRace::deleteAthlete( QString userName ){ - - QVariant requestData = QVariantMap({{"userName", userName}}); - - QVariantMap reply = this->scStwClient->sendCommand(4002, requestData.toJsonValue()); - - if(reply["status"] != 200){ - //handle Error!! - qDebug() << "+ --- error deleting athlete: " << reply["status"]; - return false; - } - - return true; - -} - -bool ClimbingRace::selectAthlete( QString userName, int timerId ){ - - QVariant requestData = QVariantMap({{"userName", userName}, {"timerId", timerId}}); - - QVariantMap reply = this->scStwClient->sendCommand(4000, requestData.toJsonValue()); - - if(reply["status"] != 200){ - //handle Error!! - qDebug() << "+ --- error selecting athlete: " << reply["status"]; - return false; - } - - return true; - -} - -QVariant ClimbingRace::getResults( QString userName ){ - QVariantMap reply = this->scStwClient->sendCommand(4004, userName); - - if(reply["status"] != 200){ - //handle Error!! - qDebug() << "+ --- error getting results: " << reply["status"]; - return false; - } - - QVariantList tmpAthletes = reply["data"].toList(); - - //qDebug() << tmpAthletes; - - return tmpAthletes; -} - -// ------------------------- -// --- functions for qml --- -// ------------------------- - -int ClimbingRace::getState() { - return this->state; -} - -int ClimbingRace::getMode() { - return this->mode; -} - -QVariant ClimbingRace::getTimerTextList() { - return this->qmlTimers; -} - -double ClimbingRace::getNextStartActionDelayProgress() { - return this->nextStartActionDelayProgress; -} - -int ClimbingRace::getNextStartAction() { - return this->nextStartAction; -} - -void ClimbingRace::writeSetting(QString key, QVariant value) { - if(this->mode == REMOTE && ScStw::baseStationSettingFromString(key) != ScStw::InvalidSetting ){ - this->scStwClient->writeRemoteSetting(ScStw::baseStationSettingFromString(key), value.toString()); - } - else { - this->appSettings->writeSetting(key, value); - } -} - -void ClimbingRace::writeSetting(ScStw::BaseStationSetting key, QVariant value) { - if(ScStw::baseStationSettingToString(key) != "Invalid" ){ - this->writeSetting(ScStw::baseStationSettingToString(key), value); - } -} - -QString ClimbingRace::readSetting(QString key) { - if(this->mode == REMOTE && ScStw::baseStationSettingFromString(key) != ScStw::InvalidSetting){ - return this->scStwClient->readRemoteSetting(ScStw::baseStationSettingFromString(key)); - } - else { - return this->appSettings->loadSetting(key); - } -} - -QString ClimbingRace::readSetting(ScStw::BaseStationSetting key) { - if(ScStw::baseStationSettingToString(key) != "Invalid") { - return this->readSetting(ScStw::baseStationSettingToString(key)); - } - return "false"; -} - -void ClimbingRace::connectBaseStation() { - this->reloadBaseStationIpAdress(); - this->scStwClient->connectToHost(); -} - -void ClimbingRace::disconnectBaseStation() { - this->scStwClient->closeConnection(); -} - -QString ClimbingRace::getBaseStationState() { - switch (this->scStwClient->getState()) { - case ScStwClient::CONNECTED: - return "connected"; - case ScStwClient::CONNECTING: - return "connecting"; - case ScStwClient::DISCONNECTED: - return "disconnected"; - case ScStwClient::INITIALISING: - return "initialising"; - } - return ""; -} - -QVariant ClimbingRace::getBaseStationConnections() { - return scStwClient->getConnections(); -} - -QVariantMap ClimbingRace::getBaseStationProperties() { - QVariantMap firmware = {{"version", this->scStwClient->getFirmwareVersion()}, {"upToDate", this->scStwClient->isFirmwareUpToDate()}}; - return {{"firmware", firmware}, {"timeOffset", this->scStwClient->getTimeOffset()}}; -} - -bool ClimbingRace::updateBasestationFirmware() { - return this->scStwClient->updateFirmware(); -} - -bool ClimbingRace::updateBasestationTime() { - return this->scStwClient->updateTime(); -} - -bool ClimbingRace::reloadBaseStationIpAdress() { - if(this->scStwClient->getState() == ScStwClient::DISCONNECTED){ - this->scStwClient->setIP(pGlobalAppSettings->loadSetting("baseStationIpAdress")); - return true; - } - return false; -} diff --git a/ScStwSrc/sources/main.cpp b/ScStwSrc/sources/main.cpp index e38fe85..f539554 100644 --- a/ScStwSrc/sources/main.cpp +++ b/ScStwSrc/sources/main.cpp @@ -58,6 +58,7 @@ #include #include #include +#include #include int main(int argc, char *argv[]) @@ -93,6 +94,7 @@ int main(int argc, char *argv[]) qmlRegisterType("com.itsblue.speedclimbingstopwatch", 2, 0, "AppTheme"); //qmlRegisterUncreatableType("com.itsblue.speedclimbingstopwatch", 2, 0, "ScStw", "This is a static class and therefore not instantiable"); qmlRegisterType("com.itsblue.speedclimbingstopwatch", 2, 0, "ScStw"); + qmlRegisterType("com.itsblue.speedclimbingstopwatch", 2, 0, "ScStwClient"); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); diff --git a/ScStwSrc/sources/scstwappbackend.cpp b/ScStwSrc/sources/scstwappbackend.cpp index 83f23a2..daf878e 100644 --- a/ScStwSrc/sources/scstwappbackend.cpp +++ b/ScStwSrc/sources/scstwappbackend.cpp @@ -5,6 +5,7 @@ ScStwAppBackend::ScStwAppBackend(QObject *parent) : QObject(parent) this->appSettings = new AppSettings(this); this->scStwClient = new ScStwClient(); this->localRace = new ScStwRace(this); + this->remoteRace = new ScStwRemoteMonitorRace(this->scStwClient, this); this->scStwClient->setIP(pGlobalAppSettings->loadSetting("baseStationIpAdress")); connect(this->scStwClient, &ScStwClient::stateChanged, this, &ScStwAppBackend::baseStationStateChanged); @@ -22,86 +23,6 @@ ScStwAppBackend::ScStwAppBackend(QObject *parent) : QObject(parent) this->refreshTimerText(); } -// ------------------------- -// --- Base Station sync --- -// ------------------------- - -/** - * @brief ScStwAppBackend::handleBaseStationUpdate - * - * Function to handle an update, sent by the base station, which indicates - * that some remote value (like a state) has changed - * - * @param data - */ -/* -void ScStwAppBackend::handleBaseStationSignal(ScStw::SignalKey key, QVariant data) { - qDebug() << "got signal: " << data; - switch (key) { - case ScStw::RaceStateChanged: - { - // the remote race state has changed - this->setState( ScStw::RaceState( data.toInt() ) ); - break; - } - case ScStw::TimersChanged: - { - // the remote timers have changed - this->refreshRemoteTimers(data.toList()); - break; - } - case ScStw::NextStartActionChanged: - { - // the next start action has changed - this->nextStartActionTotalDelay = data.toMap()["nextActionDelay"].toDouble(); - this->nextStartActionDelayStartedAt = this->date->currentMSecsSinceEpoch() - (this->nextStartActionTotalDelay * data.toMap()["nextActionDelayProg"].toDouble()); - this->nextStartAction = ScStw::NextStartAction( data.toMap()["nextAction"].toInt() ); - - emit this->nextStartActionChanged(); - break; - } - case ScStw::ExtensionsChanged: - { - emit this->baseStationConnectionsChanged(); - break; - } - case ScStw::InvalidSignal: - return; - - } -} - -bool ScStwAppBackend::refreshRemoteTimers(QVariantList timers) { - - if(timers.length() != speedTimers.length()){ - // local timers are out of sync - - // delete all current timers - foreach(SpeedTimer * locTimer, this->speedTimers){ - delete locTimer; - } - - speedTimers.clear(); - - foreach(QVariant remTimer, timers){ - // create a local timer for each remote timer - this->speedTimers.append(new SpeedTimer(this)); - } - } - - foreach(QVariant remTimer, timers){ - int currId = remTimer.toMap()["id"].toInt(); - speedTimers[currId]->startTime = this->date->currentMSecsSinceEpoch() - remTimer.toMap()["currentTime"].toDouble(); - speedTimers[currId]->stoppedTime = remTimer.toMap()["currentTime"].toDouble(); - speedTimers[currId]->reactionTime = remTimer.toMap()["reactionTime"].toDouble(); - - speedTimers[currId]->setState(SpeedTimer::timerState(remTimer.toMap()["state"].toInt())); - } - - return true; - -} -*/ // ------------------------ // --- helper functions --- // ------------------------ @@ -126,6 +47,8 @@ void ScStwAppBackend::refreshMode() { this->mode = newMode; emit this->modeChanged(); + emit this->raceChanged(); + emit this->getRace()->stateChanged(this->getRace()->getState()); } } @@ -145,14 +68,9 @@ void ScStwAppBackend::refreshTimerText() { this->timerTextRefreshTimer->start(); } -bool ScStwAppBackend::pairConnectedUsbExtensions() { - QVariantMap ret = this->scStwClient->sendCommand(5002, "", 10000); - qDebug() << ret; - return ret["status"] == 200; -} - // - athlete management - +// TODO: move to client QVariant ScStwAppBackend::getAthletes() { QVariantMap reply = this->scStwClient->sendCommand(4003); @@ -240,9 +158,14 @@ ScStwRace* ScStwAppBackend::getRace() { switch (this->mode) { case LOCAL: return this->localRace; - default: - return nullptr; + case REMOTE: + return this->remoteRace; } + return nullptr; +} + +ScStwClient* ScStwAppBackend::getScStwClient() { + return this->scStwClient; } int ScStwAppBackend::getMode() { @@ -258,6 +181,7 @@ void ScStwAppBackend::writeSetting(QString key, QVariant value) { } this->reloadRaceSettings(); + this->reloadBaseStationIpAdress(); } void ScStwAppBackend::writeSetting(ScStw::BaseStationSetting key, QVariant value) { @@ -298,50 +222,14 @@ void ScStwAppBackend::reloadRaceSettings() { this->getRace()->setSoundVolume(1); } -void ScStwAppBackend::connectBaseStation() { - this->reloadBaseStationIpAdress(); - this->scStwClient->connectToHost(); -} - -void ScStwAppBackend::disconnectBaseStation() { - this->scStwClient->closeConnection(); -} - -QString ScStwAppBackend::getBaseStationState() { - switch (this->scStwClient->getState()) { - case ScStwClient::CONNECTED: - return "connected"; - case ScStwClient::CONNECTING: - return "connecting"; - case ScStwClient::DISCONNECTED: - return "disconnected"; - case ScStwClient::INITIALISING: - return "initialising"; - } - return ""; -} - -QVariant ScStwAppBackend::getBaseStationConnections() { - return scStwClient->getConnections(); -} +// TODO: move to client +/* QVariantMap ScStwAppBackend::getBaseStationProperties() { QVariantMap firmware = {{"version", this->scStwClient->getFirmwareVersion()}, {"upToDate", this->scStwClient->isFirmwareUpToDate()}}; return {{"firmware", firmware}, {"timeOffset", this->scStwClient->getTimeOffset()}}; } - -bool ScStwAppBackend::updateBasestationFirmware() { - return this->scStwClient->updateFirmware(); -} - -bool ScStwAppBackend::updateBasestationTime() { - return this->scStwClient->updateTime(); -} - -bool ScStwAppBackend::reloadBaseStationIpAdress() { - if(this->scStwClient->getState() == ScStwClient::DISCONNECTED){ - this->scStwClient->setIP(pGlobalAppSettings->loadSetting("baseStationIpAdress")); - return true; - } - return false; +*/ +void ScStwAppBackend::reloadBaseStationIpAdress() { + this->scStwClient->setIP(pGlobalAppSettings->loadSetting("baseStationIpAdress")); } diff --git a/ScStwSrc/sources/speedtimer.cpp b/ScStwSrc/sources/speedtimer.cpp deleted file mode 100644 index 40c9392..0000000 --- a/ScStwSrc/sources/speedtimer.cpp +++ /dev/null @@ -1,211 +0,0 @@ -#include "headers/speedtimer.h" - -SpeedTimer::SpeedTimer(QObject *parent) : QObject(parent) -{ - - this->date = new QDateTime; - - this->startTime = 0; - this->stopTime = 0; - this->stoppedTime = 0; - this->reactionTime = 0; - this->state = IDLE; -} - -bool SpeedTimer::start(bool force) { - if(this->state != STARTING && !force){ - return false; - } - qDebug() << "starting timer"; - if(!force){ - this->stopTime = 0; - this->stoppedTime = 0; - this->reactionTime = 0; - this->startTime = this->date->currentMSecsSinceEpoch(); - } - - this->setState(RUNNING); - - return true; -} - -bool SpeedTimer::stop(int type, bool force) { - - // type can be: - // 0: stopped - // 1: cancelled - // 2: failed (fase start) - - if( ( this->state != SpeedTimer::STARTING && this->state != SpeedTimer::RUNNING && this->state ) && !force ){ - return false; - } - - //qDebug() << "Stopping: " << "start Time: " << startTime << " stopTime: " << stopTime << " stoppedTime: " << stoppedTime << " reactionTime: " << reactionTime; - - switch (type) { - case 0: - { - this->stopTime = this->date->currentMSecsSinceEpoch(); - this->stoppedTime = this->stopTime - this->startTime; - this->setState(WON); - break; - } - case 1: - { - this->stoppedTime = 0; - this->setState(CANCELLED); - break; - } - case 2: - { - this->stoppedTime = this->reactionTime; - this->setState(FAILED); - break; - } - } - - qDebug() << "Stopped: " << "start Time: " << startTime << " stopTime: " << stopTime << " stoppedTime: " << stoppedTime << " reactionTime: " << reactionTime; - - return true; - //this->startPad->appendCommand("SET_LED_STARTING"); -} - -bool SpeedTimer::reset(bool force){ - if( ( this->state < WON ) && !force){ - return false; - } - - this->startTime = 0; - this->stopTime = 0; - this->stoppedTime = 0; - this->reactionTime = 0; - this->setState(IDLE); - - return true; - //this->startPad->appendCommand("SET_LED_STARTING"); -} - -void SpeedTimer::setState(timerState newState){ - if(this->state != newState){ - this->state = newState; - qDebug() << "+--- timer state changed: " << newState; - emit this->stateChanged(newState); - } -} - -QString SpeedTimer::getState(){ - switch(state){ - case IDLE: - return "IDLE"; - case STARTING: - return "STARTING"; - case WAITING: - return "WAITING"; - case RUNNING: - return "RUNNING"; - case WON: - return "WON"; - case LOST: - return "LOST"; - case FAILED: - return "FAILED"; - case CANCELLED: - return "CANCELLED"; - case DISABLED: - return "DISABLED"; - } - return "ERROR"; -} - -double SpeedTimer::getCurrTime() { - double currTime; - if(this->state == RUNNING && this->startTime > 0){ - currTime = this->date->currentMSecsSinceEpoch() - this->startTime; - } - else { - currTime = this->stoppedTime; - } - - return(currTime); -} - -QString SpeedTimer::getText() { - //qDebug() << this->getState(); - QString newText; - switch (this->state) { - case SpeedTimer::IDLE: - newText = "0.000 sec"; - break; - case SpeedTimer::STARTING: - newText = "0.000 sec"; - break; - case SpeedTimer::WAITING: - newText = "please wait..."; - break; - case SpeedTimer::RUNNING: - newText = QString::number( this->getCurrTime() / 1000.0, 'f', 3 ) + " sec"; - break; - case SpeedTimer::WON: - newText = QString::number( this->stoppedTime / 1000.0, 'f', 3 ) + " sec"; - break; - case SpeedTimer::LOST: - newText = QString::number( this->stoppedTime / 1000.0, 'f', 3 ) + " sec"; - break; - case SpeedTimer::FAILED: - newText = "false start"; - break; - case SpeedTimer::CANCELLED: - newText = "cancelled"; - break; - case SpeedTimer::DISABLED: - newText = "---"; - break; - } - - return newText; -} - -void SpeedTimer::delay(int mSecs){ - QEventLoop loop; - QTimer timer; - - timer.setSingleShot(true); - // quit the loop when the timer times out - loop.connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); - //quit the loop when the connection was established - // start the timer before starting to connect - timer.start(mSecs); - //connect - - //wait for the connection to finish (programm gets stuck in here) - loop.exec(); -} - -SpeedTimer::timerState SpeedTimer::stateFromString(QString state){ - - if(state == "IDLE"){ - return IDLE; - } - else if (state == "STARTING") { - return STARTING; - } - else if (state == "RUNNING") { - return RUNNING; - } - else if (state == "WON") { - return WON; - } - else if (state == "LOST") { - return LOST; - } - else if (state == "FAILED") { - return FAILED; - } - else if(state == "DISABLED") { - return DISABLED; - } - else { - return CANCELLED; - } -} -