This repository has been archived on 2024-06-03. You can view files and clone it, but cannot push or open issues or pull requests.
app/ScStwSrc/sources/scstwappbackend.cpp
2020-04-17 19:57:33 +02:00

347 lines
10 KiB
C++

#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;
}