continued to implement the base station connection

This commit is contained in:
Dorian Zedler 2018-10-14 18:39:39 +02:00
parent 1e09ebe027
commit 34f9d0f08e
13 changed files with 460 additions and 183 deletions

View file

@ -8,6 +8,10 @@
#include <QTimer> #include <QTimer>
#include <QEventLoop> #include <QEventLoop>
#include <QSemaphore> #include <QSemaphore>
#include <QThread>
#include <QFuture>
#include <QtConcurrent/QtConcurrent>
#include <string.h>
#include "headers/appsettings.h" #include "headers/appsettings.h"
#include "headers/speedtimer.h" #include "headers/speedtimer.h"
@ -20,6 +24,8 @@ class BaseConn : public QObject
Q_PROPERTY(QString state READ getState NOTIFY stateChanged) Q_PROPERTY(QString state READ getState NOTIFY stateChanged)
Q_PROPERTY(int progress READ getProgress NOTIFY progressChanged) Q_PROPERTY(int progress READ getProgress NOTIFY progressChanged)
Q_PROPERTY(QStringList connections READ getConnections NOTIFY connectionsChanged) Q_PROPERTY(QStringList connections READ getConnections NOTIFY connectionsChanged)
Q_PROPERTY(QString nextRemoteAction READ getNextRemoteAction NOTIFY nextRemoteActionChanged)
Q_PROPERTY(float nextRemoteActionDelayProg READ getNextRemoteActionDelayProg NOTIFY nextRemoteActionDelayProgChanged)
public: public:
explicit BaseConn(QObject *parent = nullptr); explicit BaseConn(QObject *parent = nullptr);
@ -53,6 +59,23 @@ private:
QList<SpeedTimer*> speedTimers; QList<SpeedTimer*> speedTimers;
QTimer *refreshTimer;
QSemaphore remoteSessions;
int nextConnectionId;
struct waitingRequest {
int id;
QEventLoop * loop;
QString reply;
};
QList<waitingRequest> waitingRequests;
QString nextRemoteAction;
float nextRemoteActionDelayProg;
signals: signals:
void stateChanged(); void stateChanged();
//is emitted, when the connection state changes //is emitted, when the connection state changes
@ -60,10 +83,16 @@ signals:
void progressChanged(); void progressChanged();
//is emmited during the connection process when the progress changes //is emmited during the connection process when the progress changes
void gotReply(); void gotUnexpectedReply(QString reply);
void connectionsChanged(); void connectionsChanged();
void connectionSlotReleased();
void nextRemoteActionChanged();
void nextRemoteActionDelayProgChanged();
public slots: public slots:
Q_INVOKABLE bool connectToHost(); Q_INVOKABLE bool connectToHost();
@ -77,7 +106,7 @@ public slots:
bool startTimers(); bool startTimers();
bool stopTimers(); bool stopTimers(QString type);
bool resetTimers(); bool resetTimers();
@ -92,12 +121,12 @@ public slots:
QStringList getConnections(); QStringList getConnections();
QString getNextRemoteAction();
float getNextRemoteActionDelayProg();
private slots: private slots:
void readyRead(); void readyRead();
private:
QTimer *refreshTimer;
QSemaphore remoteSessions;
}; };
#endif // BASECONN_H #endif // BASECONN_H

View file

@ -10,6 +10,7 @@
#include <QDesktopServices> #include <QDesktopServices>
#include <QDateTime> #include <QDateTime>
#include <QtDebug> #include <QtDebug>
#include <QtConcurrent/qtconcurrentthreadengine.h>
#include "appsettings.h" #include "appsettings.h"

View file

@ -22,6 +22,8 @@ public:
double stoppedTime; double stoppedTime;
double reactionTime; double reactionTime;
bool remoteControlled;
signals: signals:
void stateChanged(timerState newState); void stateChanged(timerState newState);
void startCanceled(bool falseStart); void startCanceled(bool falseStart);
@ -35,11 +37,14 @@ public slots:
QString getState(); QString getState();
double getCurrTime(); double getCurrTime();
void handleStartpadTrigger(); //void handleStartpadTrigger();
void handleToppadTrigger(); //void handleToppadTrigger();
//helper functions
void delay(int mSecs); void delay(int mSecs);
timerState stateFromString(QString state);
private: private:
QDateTime *date; QDateTime *date;
}; };

View file

@ -0,0 +1,52 @@
#ifndef SPEEDTIMERQMLADAPTER_H
#define SPEEDTIMERQMLADAPTER_H
#include <QObject>
#include <QTimer>
#include "speedtimer.h"
class SpeedTimerQmlAdapter : public QObject
{
Q_OBJECT
Q_PROPERTY(QString state READ getState NOTIFY stateChanged)
//Q_PROPERTY(int currtime READ getCurrTime)
Q_PROPERTY(QString text READ getText NOTIFY textChanged)
public:
explicit SpeedTimerQmlAdapter(QObject *parent = nullptr);
SpeedTimer::timerState state;
// variables for capturing the time
double startTime;
double stopTime;
double stoppedTime;
double reactionTime;
QString text;
signals:
void stateChanged(SpeedTimer::timerState newState);
Q_SIGNAL void startCanceled(bool falseStart);
void textChanged();
public slots:
Q_INVOKABLE bool setStarting();
Q_INVOKABLE bool start();
Q_INVOKABLE bool stop(QString type);
Q_INVOKABLE bool reset();
void setState(SpeedTimer::timerState newState);
Q_INVOKABLE QString getState();
Q_INVOKABLE QString getText();
// double getCurrTime();
private:
QTimer * refreshTimer;
private slots:
void refreshValues();
};
#endif // SPEEDTIMERQMLADAPTER_H

View file

@ -21,6 +21,7 @@ import QtQuick.Window 2.2
import QtQuick.Controls 2.2 import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
import com.itsblue.speedclimbingstopwatch 1.0 import com.itsblue.speedclimbingstopwatch 1.0
import "./components/ProgressCircle.qml"
Popup { Popup {

View file

@ -72,7 +72,7 @@ Popup {
Label { Label {
id: head_text id: head_text
text: options_stack.currentItem.title text: options_stack.currentItem.title
font.pixelSize: headlineUnderline.width * 0.1 font.pixelSize: headlineUnderline.width * 0.05
color: enabled ? StyleSettings.textColor:StyleSettings.disabledTextColor color: enabled ? StyleSettings.textColor:StyleSettings.disabledTextColor
anchors { anchors {
horizontalCenter: parent.horizontalCenter horizontalCenter: parent.horizontalCenter

View file

@ -5,6 +5,7 @@ import QtQuick.Controls 2.2
import "." import "."
import "./components" import "./components"
import "./styles" import "./styles"
import com.itsblue.speedclimbingstopwatch 1.0
Item { Item {
id: control id: control
@ -27,19 +28,20 @@ Item {
signal stopped() signal stopped()
signal startCanceled(bool falseStart) signal startCanceled(bool falseStart)
signal stateChanged(var newState)
anchors.fill: parent anchors.fill: parent
state: "IDLE" state: "IDLE"
Label { Label {
id: time id: time
text: parent.text text: timerBackend.state === "STARTING" ? control.text:timerBackend.text
scale: parent.scale scale: parent.scale
anchors.centerIn: parent anchors.centerIn: parent
font.pixelSize: parent.pixelSize font.pixelSize: parent.pixelSize
elide: parent.elide elide: parent.elide
color: StyleSettings.textColor color: StyleSettings.textColor
Behavior on text { Behavior on text {
enabled: control.state !== "RUNNING" enabled: timerBackend.state !== "RUNNING"
FadeAnimation { FadeAnimation {
target: time target: time
} }
@ -47,74 +49,38 @@ Item {
} }
SpeedTimerBackend {
id: timerBackend
onStateChanged: {
control.stateChanged(newState)
}
onStartCanceled: {
console.log("start cnaceled")
control.startCanceled(falseStart)
}
}
function getState(){
return(timerBackend.getState())
}
function setStarting(){ function setStarting(){
control.state = "STARTING" timerBackend.setStarting()
} }
function start(inMilliSeconds){ function start(inMilliSeconds){
control.state = "STARTING"
control.startTime = new Date().getTime() + inMilliSeconds //set the startime to be 0 after the starttone
startTimer.interval = inMilliSeconds startTimer.interval = inMilliSeconds
startTimer.start() startTimer.start()
} }
function stop(type){ function stop(type){
//_cppStartpadConn.appendCommand("SET_LED_STARTING"); timerBackend.stop(type)
switch(type){
case "toppad":
//the buzzer was pushed
control.stopTime = control.toppadConn.lastTriggered + control.toppadConn.offset
control.stoppedTime = control.stopTime - control.startTime
control.stopped()
//time.text = ( root.stoppedTime / 1000 ).toFixed(3) + " sec"
//console.log("STOPPED: "+control.stoppedTime + " started at: " + control.startTime + " offset: "+ control.buzzer_offset + "lastpressed: " + control.last_button_pressed)
break
case "manual":
//the stop button was pressed
if(baseConn.state === "connected"){
control.stoppedTime = baseConn.getTime("raw")
time.text = (control.stoppedTime / 1000).toFixed(3) + " sec"
return
}
control.stopTime = new Date().getTime()
control.stoppedTime = control.stopTime - control.startTime
control.stopped()
break
case "false":
//there was a false start
control.stoppedTime = -1
startTimer.stop()
control.state = "STOPPED"
control.startCanceled(true)
break
case "cancel":
//the cancel button was pressed
control.stoppedTime = 0
startTimer.stop()
control.state = "STOPPED"
control.startCanceled(false)
break
}
control.state = "STOPPED"
} }
function reset(){ function reset(){
timerBackend.reset()
control.startTime = 0
control.stopTime = 0
control.stoppedTime = 0
if(baseConn.state === "connected"){
var ret = baseConn.sendCommand("CMD_RESET_TIMER")
if(ret !== "OK"){
control.state = "IDLE"
return
}
}
control.state = "IDLE"
} }
function handleStartpad(){ function handleStartpad(){
@ -138,46 +104,8 @@ Item {
running: false running: false
repeat: false repeat: false
onTriggered: { onTriggered: {
timerBackend.start()
console.log("started") console.log("started")
control.state = "RUNNING"
} }
} }
Timer {
//timer that updates the currTime variable
running: true
repeat: true
interval: 1
onTriggered: {
control.currTime = new Date().getTime()
}
}
states: [
State {
name: "IDLE"
//state for the start page
PropertyChanges { target: time; text: qsTr("Click start to start");}
},
State {
name: "STARTING"
//state for the start sequence
PropertyChanges { target: time; text: control.text;}
},
State {
name: "RUNNING"
//state when the timer is running
PropertyChanges { target: time; text: Math.abs( ( ( control.currTime - control.startTime ) / 1000 ) ).toFixed(3) + " sec";}
},
State {
name: "STOPPED"
//state when the meassuring is over
PropertyChanges {
target: time;
text: control.stoppedTime >= 0 ? ( control.stoppedTime / 1000 ).toFixed(3) + " sec":qsTr("false start");
}
}
]
} }

View file

@ -119,25 +119,34 @@ Window {
BaseStationConn { BaseStationConn {
id: baseConn id: baseConn
ipAdress: "localhost"//"raspberrypi.local" ipAdress: "raspberrypi.local"
property var status: {'status': baseConn.state, 'progress': baseConn.progress, 'connections': baseConn.connections} property var status: {'status': baseConn.state, 'progress': baseConn.progress, 'connections': baseConn.connections}
onNextRemoteActionChanged: {
switch(nextRemoteAction){
case "at_marks":
timer_1.text = "at your\nmarks"
break
case "ready":
timer_1.text = "ready"
break
case "start":
timer_1.text = "0.000 sec"
break
}
}
function getTime(type){ onNextRemoteActionDelayProgChanged: {
var time = parseInt(sendCommand("GET_CURRTIME")) console.log(nextRemoteActionDelayProg)
if(type === "readable"){ prog.progress = baseConn.nextRemoteActionDelayProg * 100
return(time / 1000).toFixed(3) console.log(prog.progress)
}
else if(type === "raw"){
return(time)
}
} }
} }
Timer { Timer {
id: baseRefreshTimer id: baseRefreshTimer
running: baseConn.state === "connected" running: false
repeat: false repeat: false
interval: 1 interval: 1
@ -328,6 +337,11 @@ Window {
text: "0.000 sec" text: "0.000 sec"
onStateChanged: {
console.log(newState)
root.state = timer_1.getState()
}
onStopped: { onStopped: {
root.state = "STOPPED" root.state = "STOPPED"
} }
@ -473,6 +487,9 @@ Window {
arcEnd: baseConn.state !== "connected" ? 360 * (( next_actionTimer.interval - ( new Date().getTime() - next_actionTimer.started_at ) ) / next_actionTimer.interval) arcEnd: baseConn.state !== "connected" ? 360 * (( next_actionTimer.interval - ( new Date().getTime() - next_actionTimer.started_at ) ) / next_actionTimer.interval)
:(360/100) * progress :(360/100) * progress
colorCircle: "grey" colorCircle: "grey"
onProgressChanged: {
console.log(progress)
}
animationDuration: baseConn.state === "connected" ? 150:0 animationDuration: baseConn.state === "connected" ? 150:0
@ -482,6 +499,7 @@ Window {
interval: 1 interval: 1
repeat: true repeat: true
onTriggered: { onTriggered: {
console.log("prog refresh timer")
prog.arcEnd = 360 * (( next_actionTimer.interval - ( new Date().getTime() - next_actionTimer.started_at ) ) / next_actionTimer.interval) prog.arcEnd = 360 * (( next_actionTimer.interval - ( new Date().getTime() - next_actionTimer.started_at ) ) / next_actionTimer.interval)
} }
} }
@ -776,16 +794,10 @@ Window {
/*----Functions to control the stopwatch----*/ /*----Functions to control the stopwatch----*/
function start(){ function start(){
if(baseConn.state === "connected"){ if(baseConn.state === "connected"){
var ret = baseConn.sendCommand("CMD_START_TIMER") baseConn.startTimers()
if(ret === "OK"){ return;
root.state = "STARTING"
timer_1.setStarting()
return
}
} }
root.state = "STARTING"
timer_1.setStarting() timer_1.setStarting()
if(_cppAppSettings.loadSetting("at_marks_en") === "true"){ if(_cppAppSettings.loadSetting("at_marks_en") === "true"){
next_actionTimer.action = "at_marks" next_actionTimer.action = "at_marks"
@ -804,22 +816,30 @@ Window {
} }
function stop(type){ function stop(type){
if(type === "manual" || type === "cancel"){
if(baseConn.state === "connected"){ if(baseConn.state === "connected"){
baseConn.sendCommand("CMD_STOP_TIMER") baseConn.stopTimers(type)
} }
} else {
root.state = "STOPPED"
timer_1.stop(type) timer_1.stop(type)
} }
if(type === "manual" || type === "cancel"){
}
//root.state = "STOPPED"
//timer_1.stop(type)
}
function reset(){ function reset(){
if(baseConn.state === "connected"){ if(baseConn.state === "connected"){
baseConn.sendCommand("CMD_RESET_TIMER") baseConn.resetTimers()
}
else {
timer_1.reset()
} }
timer_1.reset() //
root.state = "IDLE" //root.state = "IDLE"
} }
} }
} }

View file

@ -4,7 +4,9 @@ BaseConn::BaseConn(QObject *parent) : QObject(parent)
{ {
socket = new QTcpSocket(); socket = new QTcpSocket();
this->setState("disconnected"); this->setState("disconnected");
remoteSessions.release(2); remoteSessions.release(1);
this->nextConnectionId = 1;
this->speedTimers.append(pGlobalSpeedTimer); this->speedTimers.append(pGlobalSpeedTimer);
@ -12,6 +14,7 @@ BaseConn::BaseConn(QObject *parent) : QObject(parent)
refreshTimer->setInterval(1); refreshTimer->setInterval(1);
refreshTimer->setSingleShot(true); refreshTimer->setSingleShot(true);
refreshTimer->connect(this->refreshTimer, &QTimer::timeout, this, &BaseConn::refreshTimers); refreshTimer->connect(this->refreshTimer, &QTimer::timeout, this, &BaseConn::refreshTimers);
refreshTimer->start();
} }
bool BaseConn::connectToHost() { bool BaseConn::connectToHost() {
@ -48,6 +51,7 @@ bool BaseConn::connectToHost() {
connect(this->socket, &QTcpSocket::readyRead, this, &BaseConn::readyRead); connect(this->socket, &QTcpSocket::readyRead, this, &BaseConn::readyRead);
this->connection_progress = 100; this->connection_progress = 100;
setState("connected"); setState("connected");
this->speedTimers[0]->remoteControlled = true;
return(true); return(true);
} }
@ -55,7 +59,15 @@ QString BaseConn::sendCommand(QString command){
if(this->state != "connected"){ if(this->state != "connected"){
return "ERR_NOT_CONNECTED"; return "ERR_NOT_CONNECTED";
} }
remoteSessions.acquire(1);
// generate id and witing requests entry
int thisId = nextConnectionId;
nextConnectionId ++;
QEventLoop loop;
this->waitingRequests.append({thisId, &loop, ""});
command = "ID:" + QString::number(thisId) + "_"+command;
QByteArray arrBlock; QByteArray arrBlock;
QDataStream out(&arrBlock, QIODevice::WriteOnly); QDataStream out(&arrBlock, QIODevice::WriteOnly);
//out.setVersion(QDataStream::Qt_5_10); //out.setVersion(QDataStream::Qt_5_10);
@ -64,14 +76,13 @@ QString BaseConn::sendCommand(QString command){
out.device()->seek(0); out.device()->seek(0);
out << quint16(arrBlock.size() - sizeof(quint16)); out << quint16(arrBlock.size() - sizeof(quint16));
QEventLoop loop;
QTimer timer; QTimer timer;
timer.setSingleShot(true); timer.setSingleShot(true);
// quit the loop when the timer times out // quit the loop when the timer times out
loop.connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); loop.connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
//quit the loop when the connection was established //quit the loop when the connection was established
loop.connect(this, &BaseConn::gotReply, &loop, &QEventLoop::quit); // loop.connect(this, &BaseConn::gotReply, &loop, &QEventLoop::quit);
// start the timer before starting to connect // start the timer before starting to connect
timer.start(3000); timer.start(3000);
@ -85,14 +96,25 @@ QString BaseConn::sendCommand(QString command){
//loop finished //loop finished
if(timer.remainingTime() == -1){ if(timer.remainingTime() == -1){
//the time has been triggered -> timeout //the time has been triggered -> timeout
return("timeout");
return("ERR_TIMEOUT");
}
QString reply;
for(int i = 0; i<this->waitingRequests.length(); i++){
if(this->waitingRequests[i].id == thisId){
reply = this->waitingRequests[i].reply;
}
} }
// stop the timer as the connection has been established // stop the timer as the connection has been established
timer.stop(); timer.stop();
remoteSessions.release(1); timer.deleteLater();
return(this->latestReadReply);
//remoteSessions.release(1);
return(reply);
} }
void BaseConn::readyRead() { void BaseConn::readyRead() {
@ -111,14 +133,32 @@ void BaseConn::readyRead() {
QString str; in >> str; QString str; in >> str;
// if (str == "0") // if (str == "0")
// { // {
// str = "Connection closed"; // str = "Connection closed";
// closeConnection(); // closeConnection();
// } // }
nextBlockSize = 0; nextBlockSize = 0;
QString reply = str;
int id = 0;
if(reply.startsWith("ID:")){
reply.replace("ID:", "");
QStringList temp = reply.split("_");
reply.replace(temp[0]+"_", "");
id = temp[0].toInt();
for(int i = 0; i<this->waitingRequests.length(); i++){
if(this->waitingRequests[i].id == id){
this->waitingRequests[i].reply = reply;
this->waitingRequests[i].loop->quit();
return;
}
}
}
latestReadReply = str; latestReadReply = str;
emit gotReply(); emit gotUnexpectedReply(str);
} }
} }
@ -127,33 +167,81 @@ void BaseConn::readyRead() {
void BaseConn::refreshTimers(){ void BaseConn::refreshTimers(){
if(this->state != "connected"){ if(this->state != "connected"){
this->refreshTimer->start();
return; return;
} }
QString remoteState; QString remoteState;
QString remoteTime;
QString tmpNextRemoteAction;
QString tmpNextRemoteActionDelayProg;
remoteState = sendCommand("GET_TIMER_STATE");
switch (speedTimers[0]->state) { switch (speedTimers[0]->state) {
case SpeedTimer::IDLE: case SpeedTimer::IDLE:
break; break;
case SpeedTimer::STARTING: case SpeedTimer::STARTING:
remoteState = sendCommand("GET_TIMER_STATE");
if(remoteState == "RUNNING"){ if(remoteState == "RUNNING"){
speedTimers[0]->start(); speedTimers[0]->start();
} }
else if (remoteState == "STOPPED") { else if (remoteState == "STOPPED") {
speedTimers[0]->stop("manual"); speedTimers[0]->stop("manual");
} }
tmpNextRemoteAction = sendCommand("GET_NEXT_ACTION");
if(tmpNextRemoteAction.startsWith("ERR")){
//handle Error!!
}
else {
if(this->nextRemoteAction != tmpNextRemoteAction){
this->nextRemoteAction = tmpNextRemoteAction;
this->nextRemoteActionChanged();
}
}
tmpNextRemoteActionDelayProg = sendCommand("GET_NEXT_ACTION_DELAY_PROG");
if(tmpNextRemoteActionDelayProg.startsWith("ERR")){
//handle error!!
}
else {
if(this->nextRemoteActionDelayProg != tmpNextRemoteActionDelayProg.toFloat()){
this->nextRemoteActionDelayProg = tmpNextRemoteActionDelayProg.toFloat();
this->nextRemoteActionDelayProgChanged();
}
}
break; break;
case SpeedTimer::RUNNING: case SpeedTimer::RUNNING:
remoteState = sendCommand("GET_TIMER_STATE");
if(remoteState == "STOPPED"){ if(remoteState == "STOPPED"){
speedTimers[0]->stop("manual"); speedTimers[0]->stop("manual");
} }
remoteTime = sendCommand("GET_CURRTIME");
if(remoteTime.startsWith("ERR")){
//handle error!!
}
else {
speedTimers[0]->stoppedTime = remoteTime.toInt();
}
break; break;
case SpeedTimer::STOPPED: case SpeedTimer::STOPPED:
remoteTime = sendCommand("GET_STOPPED_TIME");
if(remoteTime.startsWith("ERR")){
//handle error!!
}
else {
speedTimers[0]->stoppedTime = remoteTime.toInt();
}
break; break;
} }
if(speedTimers[0]->state != speedTimers[0]->stateFromString(remoteState)){
// speedTimers[0]->setState(speedTimers[0]->stateFromString(remoteState));
qWarning() << "WARNING: Remote State not matching!!" << " remote state: " << remoteState << " local state: " << this->speedTimers[0]->getState();
}
this->refreshTimer->start(); this->refreshTimer->start();
} }
@ -171,7 +259,7 @@ bool BaseConn::startTimers(){
return true; return true;
} }
bool BaseConn::stopTimers(){ bool BaseConn::stopTimers(QString type){
qDebug() << "stopping timers"; qDebug() << "stopping timers";
QString ret = this->sendCommand("CMD_STOP_TIMER"); QString ret = this->sendCommand("CMD_STOP_TIMER");
@ -181,10 +269,24 @@ bool BaseConn::stopTimers(){
return false; return false;
} }
this->speedTimers[0]->stop("manual"); this->speedTimers[0]->stop(type);
qDebug() << "stopped timers";
return true; return true;
} }
bool BaseConn::resetTimers(){
qDebug() << "resetting timers";
QString ret = this->sendCommand("CMD_RESET_TIMER");
if(ret.startsWith("ERR")){
//handle Error!
return false;
}
this->speedTimers[0]->reset();
return true;
}
void BaseConn::setIP(const QString &ipAdress){ void BaseConn::setIP(const QString &ipAdress){
this->ip = ipAdress; this->ip = ipAdress;
@ -224,3 +326,11 @@ QStringList BaseConn::getConnections() {
return(connections); return(connections);
} }
QString BaseConn::getNextRemoteAction() {
return this->nextRemoteAction;
}
float BaseConn::getNextRemoteActionDelayProg(){
return this->nextRemoteActionDelayProg;
}

View file

@ -54,6 +54,7 @@
#include "headers/appsettings.h" #include "headers/appsettings.h"
#include "headers/baseconn.h" #include "headers/baseconn.h"
#include "headers/speedtimer.h" #include "headers/speedtimer.h"
#include "headers/speedtimerqmladapter.h"
#include <QTranslator> #include <QTranslator>
static void connectToDatabase() static void connectToDatabase()
@ -123,6 +124,7 @@ int main(int argc, char *argv[])
qmlRegisterType<BuzzerConn>("com.itsblue.speedclimbingstopwatch", 1, 0, "BuzzerConn"); qmlRegisterType<BuzzerConn>("com.itsblue.speedclimbingstopwatch", 1, 0, "BuzzerConn");
qmlRegisterType<BuzzerConn>("com.itsblue.speedclimbingstopwatch", 1, 0, "StartpadConn"); qmlRegisterType<BuzzerConn>("com.itsblue.speedclimbingstopwatch", 1, 0, "StartpadConn");
qmlRegisterType<BaseConn>("com.itsblue.speedclimbingstopwatch", 1, 0, "BaseStationConn"); qmlRegisterType<BaseConn>("com.itsblue.speedclimbingstopwatch", 1, 0, "BaseStationConn");
qmlRegisterType<SpeedTimerQmlAdapter>("com.itsblue.speedclimbingstopwatch", 1, 0, "SpeedTimerBackend");
//setup translation engine //setup translation engine
//to the language of the system //to the language of the system

View file

@ -4,6 +4,7 @@ SpeedTimer * pGlobalSpeedTimer = nullptr;
SpeedTimer::SpeedTimer(QObject *parent) : QObject(parent) SpeedTimer::SpeedTimer(QObject *parent) : QObject(parent)
{ {
this->date = new QDateTime; this->date = new QDateTime;
this->startTime = 0; this->startTime = 0;
@ -11,16 +12,21 @@ SpeedTimer::SpeedTimer(QObject *parent) : QObject(parent)
this->stoppedTime = 0; this->stoppedTime = 0;
this->reactionTime = 0; this->reactionTime = 0;
this->state = IDLE; this->state = IDLE;
this->remoteControlled = false;
} }
void SpeedTimer::start() { void SpeedTimer::start() {
if(this->state != STARTING){ if(this->state != STARTING){
return; return;
} }
qDebug() << "starting timer";
if(!this->remoteControlled){
this->stopTime = 0; this->stopTime = 0;
this->stoppedTime = 0; this->stoppedTime = 0;
this->reactionTime = 0; this->reactionTime = 0;
this->startTime = this->date->currentMSecsSinceEpoch(); this->startTime = this->date->currentMSecsSinceEpoch();
}
this->setState(RUNNING); this->setState(RUNNING);
//this->startPad->appendCommand("SET_LED_RUNNING"); //this->startPad->appendCommand("SET_LED_RUNNING");
} }
@ -30,9 +36,18 @@ void SpeedTimer::stop(QString type) {
return; return;
} }
qDebug() << "Stopping: " << "start Time: " << startTime << " stopTime: " << stopTime << " stoppedTime: " << stoppedTime << " reactionTime: " << reactionTime; //qDebug() << "Stopping: " << "start Time: " << startTime << " stopTime: " << stopTime << " stoppedTime: " << stoppedTime << " reactionTime: " << reactionTime;
if(type == "manual"){ if(this->remoteControlled){
if(type == "cancel"){
emit startCanceled(false);
}
}
else if(type == "cancel"){
emit startCanceled(false);
this->stoppedTime = 0;
}
else if(type == "manual"){
if(this->state == STARTING){ if(this->state == STARTING){
emit startCanceled(false); emit startCanceled(false);
} }
@ -57,6 +72,7 @@ void SpeedTimer::reset(){
if(this->state != STOPPED){ if(this->state != STOPPED){
return; return;
} }
this->startTime = 0; this->startTime = 0;
this->stopTime = 0; this->stopTime = 0;
this->stoppedTime = 0; this->stoppedTime = 0;
@ -66,9 +82,8 @@ void SpeedTimer::reset(){
} }
void SpeedTimer::setState(timerState newState){ void SpeedTimer::setState(timerState newState){
this->state = newState; this->state = newState;
qDebug() << "tmer state changed: " << newState; qDebug() << "timer state changed: " << newState;
emit this->stateChanged(newState); emit this->stateChanged(newState);
} }
@ -87,7 +102,7 @@ QString SpeedTimer::getState(){
double SpeedTimer::getCurrTime() { double SpeedTimer::getCurrTime() {
double currTime; double currTime;
if(this->state == RUNNING){ if(this->state == RUNNING && !this->remoteControlled){
currTime = this->date->currentMSecsSinceEpoch() - this->startTime; currTime = this->date->currentMSecsSinceEpoch() - this->startTime;
} }
else { else {
@ -113,3 +128,19 @@ void SpeedTimer::delay(int mSecs){
loop.exec(); 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 == "STOPPED") {
return STOPPED;
}
}

View file

@ -0,0 +1,96 @@
#include "headers/speedtimerqmladapter.h"
SpeedTimerQmlAdapter::SpeedTimerQmlAdapter(QObject *parent) : QObject(parent)
{
this->state = SpeedTimer::IDLE;
connect(pGlobalSpeedTimer, &SpeedTimer::stateChanged, this, &SpeedTimerQmlAdapter::setState);
connect(pGlobalSpeedTimer, &SpeedTimer::startCanceled, this, &SpeedTimerQmlAdapter::startCanceled);
this->refreshTimer = new QTimer();
refreshTimer->setInterval(1);
refreshTimer->setSingleShot(true);
refreshTimer->connect(refreshTimer, &QTimer::timeout, this, &SpeedTimerQmlAdapter::refreshValues);
refreshTimer->start();
}
QString SpeedTimerQmlAdapter::getState(){
switch(state){
case SpeedTimer::IDLE:
return("IDLE");
case SpeedTimer::STARTING:
return("STARTING");
case SpeedTimer::RUNNING:
return("RUNNING");
case SpeedTimer::STOPPED:
return("STOPPED");
}
}
void SpeedTimerQmlAdapter::setState(SpeedTimer::timerState newState){
this->state = newState;
qDebug() << "tmer state changed: " << newState;
emit this->stateChanged(newState);
}
QString SpeedTimerQmlAdapter::getText(){
return(this->text);
}
void SpeedTimerQmlAdapter::refreshValues(){
//qDebug() << this->getState();
QString newText;
switch (this->state) {
case SpeedTimer::IDLE:
newText = "Click Start to start";
break;
case SpeedTimer::STARTING:
newText = "0.000 sec";
break;
case SpeedTimer::RUNNING:
newText = QString::number( pGlobalSpeedTimer->getCurrTime() / 1000.0, 'f', 3 ) + " sec";
break;
case SpeedTimer::STOPPED:
newText = QString::number( pGlobalSpeedTimer->stoppedTime / 1000.0, 'f', 3 ) + " sec";
}
if(this->text != newText){
this->text = newText;
emit textChanged();
}
//qDebug() << this->text;
refreshTimer->start();
}
bool SpeedTimerQmlAdapter::setStarting(){
if(pGlobalSpeedTimer->remoteControlled){
return false;
}
pGlobalSpeedTimer->setState(SpeedTimer::STARTING);
return true;
}
bool SpeedTimerQmlAdapter::start(){
if(pGlobalSpeedTimer->remoteControlled){
return false;
}
pGlobalSpeedTimer->start();
return true;
}
bool SpeedTimerQmlAdapter::stop(QString type){
if(pGlobalSpeedTimer->remoteControlled){
return false;
}
pGlobalSpeedTimer->stop(type);
return true;
}
bool SpeedTimerQmlAdapter::reset(){
if(pGlobalSpeedTimer->remoteControlled){
return false;
}
pGlobalSpeedTimer->reset();
return true;
}

View file

@ -26,7 +26,8 @@ SOURCES += \
sources/buzzerconn.cpp \ sources/buzzerconn.cpp \
sources/appsettings.cpp \ sources/appsettings.cpp \
sources/baseconn.cpp \ sources/baseconn.cpp \
sources/speedtimer.cpp sources/speedtimer.cpp \
sources/speedtimerqmladapter.cpp
HEADERS += \ HEADERS += \
headers/sqlstoragemodel.h \ headers/sqlstoragemodel.h \
@ -34,7 +35,8 @@ HEADERS += \
headers/buzzerconn.h \ headers/buzzerconn.h \
headers/appsettings.h \ headers/appsettings.h \
headers/baseconn.h \ headers/baseconn.h \
headers/speedtimer.h headers/speedtimer.h \
headers/speedtimerqmladapter.h
RESOURCES += \ RESOURCES += \
shared.qrc \ shared.qrc \