2019-03-07 17:18:24 +01:00
|
|
|
#include "headers/climbingrace.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* manages:
|
|
|
|
* - global state
|
|
|
|
* - timers
|
|
|
|
* - sounds
|
|
|
|
* - next start action
|
|
|
|
* - next start action delay progress
|
2019-03-27 22:23:12 +01:00
|
|
|
* - settings (remote and local)
|
2019-03-07 17:18:24 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
ClimbingRace::ClimbingRace(QObject *parent) : QObject(parent)
|
|
|
|
{
|
|
|
|
this->state = IDLE;
|
|
|
|
this->mode = LOCAL;
|
|
|
|
|
2019-08-20 10:19:35 +02:00
|
|
|
this->appSettings = new AppSettings(this);
|
|
|
|
this->baseConn = new BaseConn(this);
|
2019-03-07 17:18:24 +01:00
|
|
|
|
2019-03-29 23:42:56 +01:00
|
|
|
this->baseConn->setIP(pGlobalAppSettings->loadSetting("baseStationIpAdress"));
|
2019-03-07 17:18:24 +01:00
|
|
|
connect(this->baseConn, &BaseConn::stateChanged, this, &ClimbingRace::baseStationStateChanged);
|
2019-08-19 15:14:11 +02:00
|
|
|
connect(this->baseConn, &BaseConn::stateChanged, this, &ClimbingRace::refreshMode);
|
2019-03-29 23:42:56 +01:00
|
|
|
connect(this->baseConn, &BaseConn::connectionsChanged, this, &ClimbingRace::baseStationConnectionsChanged);
|
2019-10-06 19:02:47 +02:00
|
|
|
connect(this->baseConn, &BaseConn::gotUpdate, this, &ClimbingRace::handleBaseStationUpdate);
|
2019-03-07 17:18:24 +01:00
|
|
|
|
2019-08-20 10:19:35 +02:00
|
|
|
this->speedTimers.append( new SpeedTimer(this) );
|
2019-03-07 17:18:24 +01:00
|
|
|
|
|
|
|
this->player = new QMediaPlayer;
|
2019-03-24 21:16:16 +01:00
|
|
|
this->date = new QDateTime;
|
2019-03-07 17:18:24 +01:00
|
|
|
|
2019-03-07 22:31:23 +01:00
|
|
|
this->nextStartActionTimer = new QTimer(this);
|
|
|
|
nextStartActionTimer->setSingleShot(true);
|
|
|
|
|
2019-08-20 10:19:35 +02:00
|
|
|
this->timerTextRefreshTimer = new QTimer(this);
|
2019-03-07 17:18:24 +01:00
|
|
|
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 != IDLE) {
|
|
|
|
return 904;
|
|
|
|
}
|
|
|
|
|
|
|
|
qDebug() << "+ --- starting race";
|
|
|
|
|
|
|
|
int returnCode = 900;
|
|
|
|
|
|
|
|
switch (this->mode) {
|
|
|
|
case LOCAL:
|
|
|
|
{
|
|
|
|
|
|
|
|
this->setState(STARTING);
|
|
|
|
|
2019-10-13 16:42:38 +02:00
|
|
|
this->nextStartAction = None;
|
2019-03-07 17:18:24 +01:00
|
|
|
this->playSoundsAndStartRace();
|
|
|
|
|
|
|
|
returnCode = 200;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case REMOTE:
|
|
|
|
{
|
|
|
|
QVariantMap reply = this->baseConn->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 != RUNNING && this->state != 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();
|
2019-10-13 16:42:38 +02:00
|
|
|
this->nextStartAction = None;
|
2019-03-07 17:18:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
returnCode = this->speedTimers[0]->stop(type) ? 200:904;
|
|
|
|
|
|
|
|
if(returnCode == 200) {
|
|
|
|
this->setState(STOPPED);
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case REMOTE:
|
|
|
|
{
|
|
|
|
QVariantMap reply = this->baseConn->sendCommand(1001);
|
|
|
|
|
|
|
|
if(reply["status"] != 200){
|
|
|
|
returnCode = reply["status"].toInt();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
returnCode = 200;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return returnCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ClimbingRace::resetRace() {
|
|
|
|
|
|
|
|
if(this->state != 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(IDLE);
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case REMOTE:
|
|
|
|
{
|
|
|
|
|
|
|
|
QVariantMap reply = this->baseConn->sendCommand(1002);
|
|
|
|
|
|
|
|
if(reply["status"] != 200){
|
|
|
|
//handle Error!!
|
|
|
|
returnCode = reply["status"].toInt();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
returnCode = 200;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return returnCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -------------------------
|
|
|
|
// --- Base Station sync ---
|
|
|
|
// -------------------------
|
|
|
|
|
2019-10-06 19:02:47 +02:00
|
|
|
/**
|
|
|
|
* @brief ClimbingRace::handleBaseStationUpdate
|
|
|
|
*
|
|
|
|
* Function to handle a update, sent by the base station, which indicates
|
|
|
|
* that some remote value (like a state) has changed
|
|
|
|
*
|
|
|
|
* @param data
|
|
|
|
*/
|
|
|
|
void ClimbingRace::handleBaseStationUpdate(QVariant data) {
|
2019-10-13 16:42:38 +02:00
|
|
|
//qDebug() << "got update: " << data;
|
2019-10-06 19:02:47 +02:00
|
|
|
int header = data.toMap()["header"].toInt();
|
|
|
|
switch (header) {
|
|
|
|
case 9000:
|
|
|
|
{
|
|
|
|
// the remote race state has changed
|
|
|
|
this->setState( raceState( data.toMap()["data"].toInt() ) );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 9001:
|
|
|
|
{
|
|
|
|
// the remote timers have changed
|
|
|
|
this->refreshRemoteTimers(data.toMap()["data"].toList());
|
|
|
|
break;
|
|
|
|
}
|
2019-10-07 19:52:39 +02:00
|
|
|
case 9002:
|
|
|
|
{
|
|
|
|
// the extension connections have changed
|
|
|
|
this->baseConn->setConnections(data.toMap()["data"].toList());
|
|
|
|
break;
|
|
|
|
}
|
2019-10-13 16:42:38 +02:00
|
|
|
case 9003:
|
|
|
|
{
|
|
|
|
// the next start action has changed
|
|
|
|
this->nextStartActionTotalDelay = data.toMap()["data"].toMap()["nextActionDelay"].toDouble();
|
|
|
|
this->nextStartActionDelayStartedAt = this->date->currentMSecsSinceEpoch() - (this->nextStartActionTotalDelay * data.toMap()["data"].toMap()["nextActionDelayProg"].toDouble());
|
|
|
|
this->nextStartAction = NextStartAction( data.toMap()["data"].toMap()["nextAction"].toInt() );
|
|
|
|
|
|
|
|
emit this->nextStartActionChanged();
|
|
|
|
}
|
2019-10-06 19:02:47 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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()["currTime"].toDouble();
|
|
|
|
speedTimers[currId]->stoppedTime = remTimer.toMap()["currTime"].toDouble();
|
|
|
|
speedTimers[currId]->reactionTime = remTimer.toMap()["reactTime"].toDouble();
|
|
|
|
|
|
|
|
speedTimers[currId]->setState(SpeedTimer::timerState(remTimer.toMap()["state"].toInt()));
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-03-07 17:18:24 +01:00
|
|
|
// ------------------------
|
|
|
|
// --- helper functions ---
|
|
|
|
// ------------------------
|
|
|
|
|
|
|
|
void ClimbingRace::playSoundsAndStartRace() {
|
|
|
|
qDebug() << "next Action: " << nextStartAction;
|
|
|
|
|
|
|
|
nextStartActionTimer->disconnect(nextStartActionTimer, SIGNAL(timeout()), this, SLOT(playSoundsAndStartRace()));
|
|
|
|
|
|
|
|
switch (this->nextStartAction) {
|
2019-10-13 16:42:38 +02:00
|
|
|
case AtYourMarks:
|
2019-03-07 17:18:24 +01:00
|
|
|
{
|
|
|
|
if(!playSound("qrc:/sounds/at_marks_1.wav")){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(appSettings->loadSetting("ready_en") == "true"){
|
2019-10-13 16:42:38 +02:00
|
|
|
nextStartAction = Ready;
|
2019-03-07 17:18:24 +01:00
|
|
|
nextStartActionTimer->setInterval(appSettings->loadSetting("ready_delay").toInt() <= 0 ? 1:appSettings->loadSetting("ready_delay").toInt());
|
|
|
|
}
|
|
|
|
else{
|
2019-10-13 16:42:38 +02:00
|
|
|
nextStartAction = Start;
|
2019-03-07 17:18:24 +01:00
|
|
|
nextStartActionTimer->setInterval(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2019-10-13 16:42:38 +02:00
|
|
|
case Ready:
|
2019-03-07 17:18:24 +01:00
|
|
|
{
|
|
|
|
if(!playSound("qrc:/sounds/ready_1.wav")){
|
|
|
|
return;
|
|
|
|
}
|
2019-10-13 16:42:38 +02:00
|
|
|
nextStartAction = Start;
|
2019-03-07 17:18:24 +01:00
|
|
|
nextStartActionTimer->setInterval(1);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2019-10-13 16:42:38 +02:00
|
|
|
case Start:
|
2019-03-07 17:18:24 +01:00
|
|
|
{
|
2019-09-16 00:06:12 +02:00
|
|
|
if(!playSound("qrc:/sounds/IFSC_STARTSIGNAL_SINE.wav")){
|
2019-03-07 17:18:24 +01:00
|
|
|
return;
|
|
|
|
}
|
2019-10-13 16:42:38 +02:00
|
|
|
nextStartAction = None;
|
2019-03-07 17:18:24 +01:00
|
|
|
nextStartActionTimer->disconnect(nextStartActionTimer, SIGNAL(timeout()), this, SLOT(playSoundsAndStartRace()));
|
|
|
|
|
|
|
|
this->setState(RUNNING);
|
|
|
|
speedTimers[0]->start();
|
|
|
|
|
2019-10-13 16:42:38 +02:00
|
|
|
emit this->nextStartActionChanged();
|
|
|
|
|
2019-03-07 17:18:24 +01:00
|
|
|
return;
|
|
|
|
}
|
2019-10-13 16:42:38 +02:00
|
|
|
case None:
|
2019-03-07 17:18:24 +01:00
|
|
|
{
|
|
|
|
this->speedTimers[0]->setState(SpeedTimer::STARTING);
|
|
|
|
if(appSettings->loadSetting("at_marks_en") == "true"){
|
2019-10-13 16:42:38 +02:00
|
|
|
nextStartAction = AtYourMarks;
|
2019-03-07 17:18:24 +01:00
|
|
|
nextStartActionTimer->setInterval(appSettings->loadSetting("at_marks_delay").toInt() <= 0 ? 1:appSettings->loadSetting("at_marks_delay").toInt());
|
|
|
|
}
|
|
|
|
else if(appSettings->loadSetting("ready_en") == "true"){
|
2019-10-13 16:42:38 +02:00
|
|
|
nextStartAction = Ready;
|
2019-03-07 17:18:24 +01:00
|
|
|
nextStartActionTimer->setInterval(appSettings->loadSetting("ready_delay").toInt() <= 0 ? 1:appSettings->loadSetting("ready_delay").toInt());
|
|
|
|
}
|
|
|
|
else{
|
2019-10-13 16:42:38 +02:00
|
|
|
nextStartAction = Start;
|
2019-03-07 17:18:24 +01:00
|
|
|
nextStartActionTimer->setInterval(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-13 16:42:38 +02:00
|
|
|
emit this->nextStartActionChanged();
|
|
|
|
|
2019-03-07 17:18:24 +01:00
|
|
|
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(raceState newState) {
|
|
|
|
|
|
|
|
if(newState != this->state) {
|
|
|
|
this->state = newState;
|
|
|
|
this->stateChanged(newState);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ClimbingRace::refreshMode() {
|
2019-03-24 21:16:16 +01:00
|
|
|
raceMode newMode;
|
2019-03-07 17:18:24 +01:00
|
|
|
if(this->baseConn->state == "connected"){
|
2019-03-24 21:16:16 +01:00
|
|
|
newMode = REMOTE;
|
2019-03-07 17:18:24 +01:00
|
|
|
}
|
|
|
|
else {
|
2019-03-24 21:16:16 +01:00
|
|
|
newMode = LOCAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(this->mode != newMode){
|
2019-06-12 14:53:37 +02:00
|
|
|
|
|
|
|
if(newMode == LOCAL){
|
|
|
|
// if the new mode is local -> connection to base station has been lost
|
|
|
|
|
2019-08-19 15:14:11 +02:00
|
|
|
// reset race
|
|
|
|
// reset state
|
|
|
|
this->setState(IDLE);
|
|
|
|
|
|
|
|
// reset timers
|
2019-06-12 14:53:37 +02:00
|
|
|
// go back to one timer
|
|
|
|
for (int i = 0;i<this->speedTimers.length();i++) {
|
|
|
|
delete this->speedTimers[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
this->speedTimers.clear();
|
|
|
|
|
|
|
|
this->speedTimers.append(new SpeedTimer);
|
|
|
|
|
2019-08-19 15:14:11 +02:00
|
|
|
// reset base conn
|
2019-06-12 14:53:37 +02:00
|
|
|
// clear extensions
|
|
|
|
this->baseConn->connections.clear();
|
|
|
|
}
|
|
|
|
|
2019-03-24 21:16:16 +01:00
|
|
|
this->mode = newMode;
|
|
|
|
emit this->modeChanged();
|
2019-03-07 17:18:24 +01:00
|
|
|
}
|
2019-03-24 21:16:16 +01:00
|
|
|
|
2019-03-07 17:18:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void ClimbingRace::refreshTimerText() {
|
|
|
|
|
|
|
|
// --- refresh timer text ---
|
|
|
|
|
|
|
|
QVariantList newTimerTextList;
|
|
|
|
|
|
|
|
foreach(SpeedTimer * timer, this->speedTimers){
|
2019-09-08 15:08:50 +02:00
|
|
|
QVariantMap timerMap = {{"text",timer->getText()}, {"reacttime", timer->reactionTime}, {"state", timer->getState()}, {"id", this->speedTimers.indexOf(timer)}};
|
2019-03-07 17:18:24 +01:00
|
|
|
newTimerTextList.append(timerMap);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(newTimerTextList != this->qmlTimers){
|
|
|
|
this->qmlTimers = newTimerTextList;
|
|
|
|
emit timerTextChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
// --- refresh next start action delay progress ---
|
2019-10-13 16:42:38 +02:00
|
|
|
double nextStartActionRemainingDelay = 0;
|
2019-03-07 17:18:24 +01:00
|
|
|
|
2019-10-13 16:42:38 +02:00
|
|
|
switch (this->mode) {
|
|
|
|
case LOCAL: {
|
2019-03-07 17:18:24 +01:00
|
|
|
|
2019-10-13 16:42:38 +02:00
|
|
|
// get remaining and total next start action delay time
|
2019-03-07 17:18:24 +01:00
|
|
|
if(nextStartAction == 0){
|
2019-10-13 16:42:38 +02:00
|
|
|
this->nextStartActionTotalDelay = appSettings->loadSetting("at_marks_delay").toDouble();
|
2019-03-07 17:18:24 +01:00
|
|
|
}
|
|
|
|
else if (nextStartAction == 1) {
|
2019-10-13 16:42:38 +02:00
|
|
|
this->nextStartActionTotalDelay = appSettings->loadSetting("ready_delay").toDouble();
|
2019-03-07 17:18:24 +01:00
|
|
|
}
|
|
|
|
|
2019-10-13 16:42:38 +02:00
|
|
|
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();
|
2019-03-07 17:18:24 +01:00
|
|
|
}
|
2019-10-13 16:42:38 +02:00
|
|
|
else {
|
2019-03-07 22:31:23 +01:00
|
|
|
this->nextStartActionDelayProgress = 0;
|
|
|
|
emit this->nextStartActionDelayProgressChanged();
|
|
|
|
}
|
2019-03-07 17:18:24 +01:00
|
|
|
|
2019-10-13 16:42:38 +02:00
|
|
|
|
|
|
|
/*if (this->mode == REMOTE && this->state == IDLE) {
|
|
|
|
this->nextStartActionDelayProgress = 0;
|
|
|
|
emit this->nextStartActionDelayProgressChanged();
|
|
|
|
}*/
|
|
|
|
|
2019-03-07 17:18:24 +01:00
|
|
|
this->timerTextRefreshTimer->start();
|
|
|
|
}
|
|
|
|
|
2019-05-02 22:39:22 +02:00
|
|
|
// - athlete management -
|
|
|
|
|
|
|
|
QVariant ClimbingRace::getAthletes() {
|
|
|
|
QVariantMap reply = this->baseConn->sendCommand(4003);
|
|
|
|
|
|
|
|
if(reply["status"] != 200){
|
|
|
|
//handle Error!!
|
|
|
|
qDebug() << "+ --- error getting athletes: " << reply["status"];
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-05-19 14:06:05 +02:00
|
|
|
QVariantMap tmpAthletes = reply["data"].toMap();
|
2019-05-02 22:39:22 +02:00
|
|
|
|
2019-06-08 11:14:18 +02:00
|
|
|
//qDebug() << tmpAthletes;
|
2019-05-02 22:39:22 +02:00
|
|
|
|
|
|
|
return tmpAthletes;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ClimbingRace::createAthlete(QString userName, QString fullName) {
|
|
|
|
|
|
|
|
QVariant requestData = QVariantMap({{"fullName", fullName}, {"userName", userName}});
|
|
|
|
|
|
|
|
QVariantMap reply = this->baseConn->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->baseConn->sendCommand(4002, requestData.toJsonValue());
|
|
|
|
|
|
|
|
if(reply["status"] != 200){
|
|
|
|
//handle Error!!
|
|
|
|
qDebug() << "+ --- error deleting athlete: " << reply["status"];
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-09-08 15:08:50 +02:00
|
|
|
bool ClimbingRace::selectAthlete( QString userName, int timerId ){
|
2019-05-02 22:39:22 +02:00
|
|
|
|
2019-09-08 15:08:50 +02:00
|
|
|
QVariant requestData = QVariantMap({{"userName", userName}, {"timerId", timerId}});
|
2019-05-02 22:39:22 +02:00
|
|
|
|
|
|
|
QVariantMap reply = this->baseConn->sendCommand(4000, requestData.toJsonValue());
|
|
|
|
|
|
|
|
if(reply["status"] != 200){
|
|
|
|
//handle Error!!
|
2019-05-03 22:54:32 +02:00
|
|
|
qDebug() << "+ --- error selecting athlete: " << reply["status"];
|
2019-05-02 22:39:22 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-05-03 22:54:32 +02:00
|
|
|
QVariant ClimbingRace::getResults( QString userName ){
|
|
|
|
QVariantMap reply = this->baseConn->sendCommand(4004, userName);
|
|
|
|
|
|
|
|
if(reply["status"] != 200){
|
|
|
|
//handle Error!!
|
|
|
|
qDebug() << "+ --- error getting results: " << reply["status"];
|
|
|
|
return false;
|
|
|
|
}
|
2019-05-02 22:39:22 +02:00
|
|
|
|
2019-05-03 22:54:32 +02:00
|
|
|
QVariantList tmpAthletes = reply["data"].toList();
|
|
|
|
|
|
|
|
//qDebug() << tmpAthletes;
|
|
|
|
|
|
|
|
return tmpAthletes;
|
|
|
|
}
|
2019-05-02 22:39:22 +02:00
|
|
|
|
2019-03-07 17:18:24 +01:00
|
|
|
// -------------------------
|
|
|
|
// --- functions for qml ---
|
|
|
|
// -------------------------
|
|
|
|
|
|
|
|
int ClimbingRace::getState() {
|
|
|
|
return this->state;
|
|
|
|
}
|
|
|
|
|
2019-03-24 21:16:16 +01:00
|
|
|
int ClimbingRace::getMode() {
|
|
|
|
return this->mode;
|
|
|
|
}
|
|
|
|
|
2019-03-07 17:18:24 +01:00
|
|
|
QVariant ClimbingRace::getTimerTextList() {
|
|
|
|
return this->qmlTimers;
|
|
|
|
}
|
|
|
|
|
|
|
|
double ClimbingRace::getNextStartActionDelayProgress() {
|
|
|
|
return this->nextStartActionDelayProgress;
|
|
|
|
}
|
|
|
|
|
2019-10-13 16:42:38 +02:00
|
|
|
int ClimbingRace::getNextStartAction() {
|
|
|
|
return this->nextStartAction;
|
|
|
|
}
|
|
|
|
|
2019-03-07 17:18:24 +01:00
|
|
|
void ClimbingRace::writeSetting(QString key, QVariant value) {
|
|
|
|
this->refreshMode();
|
2019-03-27 22:23:12 +01:00
|
|
|
|
2019-04-08 18:03:23 +02:00
|
|
|
if(this->mode == REMOTE && ( this->remoteSettings.contains(key) || this->remoteOnlySettings.contains(key) ) ){
|
2019-03-07 17:18:24 +01:00
|
|
|
this->baseConn->writeRemoteSetting(key, value.toString());
|
2019-03-27 22:23:12 +01:00
|
|
|
}
|
2019-04-08 18:03:23 +02:00
|
|
|
else if(!this->remoteOnlySettings.contains(key)){
|
2019-03-27 22:23:12 +01:00
|
|
|
this->appSettings->writeSetting(key, value);
|
2019-03-07 17:18:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QString ClimbingRace::readSetting(QString key) {
|
|
|
|
this->refreshMode();
|
2019-03-27 22:23:12 +01:00
|
|
|
|
2019-04-08 18:03:23 +02:00
|
|
|
if(this->mode == REMOTE && ( this->remoteSettings.contains(key) || this->remoteOnlySettings.contains(key) )){
|
2019-03-07 17:18:24 +01:00
|
|
|
QVariantMap reply = this->baseConn->sendCommand(3001, key);
|
|
|
|
if(reply["status"] != 200){
|
|
|
|
return "false";
|
|
|
|
}
|
|
|
|
return reply["data"].toString();
|
|
|
|
}
|
2019-04-08 18:03:23 +02:00
|
|
|
else if(!this->remoteOnlySettings.contains(key)){
|
2019-03-27 22:23:12 +01:00
|
|
|
return this->appSettings->loadSetting(key);
|
|
|
|
}
|
2019-04-08 18:03:23 +02:00
|
|
|
else {
|
|
|
|
return "false";
|
|
|
|
}
|
2019-03-07 17:18:24 +01:00
|
|
|
}
|
|
|
|
|
2019-08-20 22:55:37 +02:00
|
|
|
void ClimbingRace::connectBaseStation() {
|
2019-03-29 23:42:56 +01:00
|
|
|
this->reloadBaseStationIpAdress();
|
2019-08-20 22:55:37 +02:00
|
|
|
this->baseConn->connectToHost();
|
2019-03-07 17:18:24 +01:00
|
|
|
}
|
|
|
|
|
2019-03-29 23:42:56 +01:00
|
|
|
void ClimbingRace::disconnectBaseStation() {
|
|
|
|
this->baseConn->closeConnection();
|
|
|
|
}
|
|
|
|
|
2019-03-07 17:18:24 +01:00
|
|
|
QString ClimbingRace::getBaseStationState() {
|
|
|
|
return this->baseConn->getState();
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariant ClimbingRace::getBaseStationConnections() {
|
|
|
|
return baseConn->getConnections();
|
|
|
|
}
|
2019-03-29 23:42:56 +01:00
|
|
|
|
|
|
|
bool ClimbingRace::reloadBaseStationIpAdress() {
|
|
|
|
if(this->baseConn->state == "disconnected"){
|
|
|
|
this->baseConn->setIP(pGlobalAppSettings->loadSetting("baseStationIpAdress"));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|