#include "../headers/scstwappbackend.h" ScStwAppBackend::ScStwAppBackend(QObject *parent) : QObject(parent) { this->appSettings = new AppSettings(this); this->scStwClient = new ScStwClient(); this->localRace = new ScStwRace(this); this->scStwClient->setIP(pGlobalAppSettings->loadSetting("baseStationIpAdress")); connect(this->scStwClient, &ScStwClient::stateChanged, this, &ScStwAppBackend::baseStationStateChanged); connect(this->scStwClient, &ScStwClient::stateChanged, this, &ScStwAppBackend::refreshMode); //connect(this->scStwClient, &ScStwClient::gotSignal, this, &ScStwAppBackend::handleBaseStationSignal); connect(this, &ScStwAppBackend::baseStationStateChanged, this, &ScStwAppBackend::baseStationPropertiesChanged); this->localRace->addTimer(new ScStwTimer(this)); this->reloadRaceSettings(); this->timerTextRefreshTimer = new QTimer(this); this->timerTextRefreshTimer->setInterval(1); this->timerTextRefreshTimer->setSingleShot(true); this->timerTextRefreshTimer->connect(this->timerTextRefreshTimer, &QTimer::timeout, this, &ScStwAppBackend::refreshTimerText); 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 --- // ------------------------ void ScStwAppBackend::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 local race this->getRace()->reset(); } this->mode = newMode; emit this->modeChanged(); } } void ScStwAppBackend::refreshTimerText() { // --- refresh timer text --- if(this->getRace()->getState() == ScStwRace::RUNNING) { emit this->getRace()->timersChanged(); } // --- refresh next start action delay progress --- if(this->getRace()->getState() == ScStwRace::STARTING) { emit this->getRace()->nextStartActionDetailsChanged(); } this->timerTextRefreshTimer->start(); } bool ScStwAppBackend::pairConnectedUsbExtensions() { QVariantMap ret = this->scStwClient->sendCommand(5002, "", 10000); qDebug() << ret; return ret["status"] == 200; } // - athlete management - QVariant ScStwAppBackend::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 ScStwAppBackend::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 ScStwAppBackend::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 ScStwAppBackend::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 ScStwAppBackend::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 --- // ------------------------- ScStwRace* ScStwAppBackend::getRace() { switch (this->mode) { case LOCAL: return this->localRace; default: return nullptr; } } int ScStwAppBackend::getMode() { return this->mode; } void ScStwAppBackend::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); } this->reloadRaceSettings(); } void ScStwAppBackend::writeSetting(ScStw::BaseStationSetting key, QVariant value) { if(ScStw::baseStationSettingToString(key) != "Invalid" ){ this->writeSetting(ScStw::baseStationSettingToString(key), value); } } QString ScStwAppBackend::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 ScStwAppBackend::readSetting(ScStw::BaseStationSetting key) { if(ScStw::baseStationSettingToString(key) != "Invalid") { return this->readSetting(ScStw::baseStationSettingToString(key)); } return "false"; } void ScStwAppBackend::reloadRaceSettings() { this->getRace()->writeStartActionSetting( ScStwRace::AtYourMarks, this->appSettings->loadSetting(ScStw::baseStationSettingToString(ScStw::AtYourMarksSoundEnableSetting)) == "true", this->appSettings->loadSetting(ScStw::baseStationSettingToString(ScStw::AtYourMarksSoundDelaySetting)).toDouble() ); this->getRace()->writeStartActionSetting( ScStwRace::Ready, this->appSettings->loadSetting(ScStw::baseStationSettingToString(ScStw::ReadySoundEnableSetting)) == "true", this->appSettings->loadSetting(ScStw::baseStationSettingToString(ScStw::ReadySoundDelaySetting)).toDouble() ); 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(); } 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; }