implemented update-protocoll

This commit is contained in:
dorian 2019-10-06 19:02:47 +02:00
parent 99ebdaa992
commit 79b3c346fa
4 changed files with 104 additions and 54 deletions

View file

@ -55,8 +55,6 @@ private:
QString readBuffer;
QSemaphore remoteSessions;
int nextConnectionId;
struct waitingRequest {
@ -76,6 +74,8 @@ signals:
void gotUnexpectedReply(QString reply);
void gotUpdate(QVariant data);
void connectionsChanged();
void connectionSlotReleased();

View file

@ -63,7 +63,7 @@ private slots:
void refreshMode();
void refreshTimerText();
bool refreshRemoteTimers();
bool refreshRemoteTimers(QVariantList timers);
signals:
void nextStartActionChanged(int nextStartAction);
@ -80,7 +80,9 @@ public slots:
Q_INVOKABLE int stopRace(int type);
Q_INVOKABLE int resetRace();
// base station sync
void syncWithBaseStation();
void handleBaseStationUpdate(QVariant data);
// functions for qml
Q_INVOKABLE int getState();

View file

@ -47,6 +47,16 @@ bool BaseConn::init() {
connect(this->socket, &QTcpSocket::readyRead, this, &BaseConn::readyRead);
this->connection_progress = 50;
this->setState("connected");
// init remote session
QJsonArray updateSubs = {"onRaceStateChanged", "onTimersChanged"};
QJsonObject sessionParams = {{"updateSubs", updateSubs}};
if(this->sendCommand(1, sessionParams)["status"] != 200) {
return false;
}
return true;
}
@ -115,10 +125,7 @@ void BaseConn::socketStateChanged(QAbstractSocket::SocketState socketState) {
}
case QAbstractSocket::ConnectedState:
{
if(this->init()) {
this->setState("connected");
}
else {
if(!this->init()) {
this->closeConnection();
}
@ -274,11 +281,16 @@ void BaseConn::socketReplyRecieved(QString reply) {
QJsonDocument jsonReply = QJsonDocument::fromJson(reply.toUtf8());
QJsonObject replyObj = jsonReply.object();
//qDebug() << "got: " << reply;
if(!replyObj.isEmpty()){
id = replyObj.value("id").toInt();
if(id == -1) {
// this message is an update!!
emit this->gotUpdate(replyObj.toVariantMap());
return;
}
// this message is the reply to a command!
for(int i = 0; i < this->waitingRequests.length(); i++){
if(this->waitingRequests[i].id == id){
this->waitingRequests[i].reply = replyObj;

View file

@ -22,6 +22,7 @@ ClimbingRace::ClimbingRace(QObject *parent) : QObject(parent)
connect(this->baseConn, &BaseConn::stateChanged, this, &ClimbingRace::baseStationStateChanged);
connect(this->baseConn, &BaseConn::stateChanged, this, &ClimbingRace::refreshMode);
connect(this->baseConn, &BaseConn::connectionsChanged, this, &ClimbingRace::baseStationConnectionsChanged);
connect(this->baseConn, &BaseConn::gotUpdate, this, &ClimbingRace::handleBaseStationUpdate);
this->speedTimers.append( new SpeedTimer(this) );
@ -32,7 +33,7 @@ ClimbingRace::ClimbingRace(QObject *parent) : QObject(parent)
nextStartActionTimer->setSingleShot(true);
this->baseStationSyncTimer = new QTimer(this);
this->baseStationSyncTimer->setInterval(100);
this->baseStationSyncTimer->setInterval(1000);
this->baseStationSyncTimer->setSingleShot(true);
this->baseStationSyncTimer->connect(this->baseStationSyncTimer, &QTimer::timeout, this, &ClimbingRace::syncWithBaseStation);
this->baseStationSyncTimer->start();
@ -213,7 +214,17 @@ void ClimbingRace::syncWithBaseStation() {
case 1:
{
// case STARTING
this->refreshRemoteTimers();
// refresh remote timers
tmpReply = this->baseConn->sendCommand(2007);
if(tmpReply["status"].toInt() != 200){
//handle error!!
qDebug() << "+ --- getting timers from basestation failed";
}
else {
this->refreshRemoteTimers(tmpReply["data"].toList());
}
tmpReply = this->baseConn->sendCommand(2005);
if(tmpReply["status"] != 200){
@ -232,7 +243,15 @@ void ClimbingRace::syncWithBaseStation() {
default:
{
this->refreshRemoteTimers();
tmpReply = this->baseConn->sendCommand(2007);
if(tmpReply["status"].toInt() != 200){
//handle error!!
qDebug() << "+ --- getting timers from basestation failed";
}
else {
this->refreshRemoteTimers(tmpReply["data"].toList());
}
break;
}
@ -241,6 +260,65 @@ void ClimbingRace::syncWithBaseStation() {
this->baseStationSyncTimer->start();
}
/**
* @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) {
qDebug() << "got update: " << data;
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;
}
}
}
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;
}
// ------------------------
// --- helper functions ---
// ------------------------
@ -435,48 +513,6 @@ void ClimbingRace::refreshTimerText() {
this->timerTextRefreshTimer->start();
}
bool ClimbingRace::refreshRemoteTimers() {
// get current time
QVariantMap tmpReply = this->baseConn->sendCommand(2007);
if(tmpReply["status"].toInt() != 200){
//handle error!!
qDebug() << "+ --- getting timers from basestation failed";
this->baseStationSyncTimer->start();
return false;
}
else {
QVariantList timers = tmpReply["data"].toList();
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;
}
}
// - athlete management -
QVariant ClimbingRace::getAthletes() {